summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Android.bp5
-rw-r--r--apct-tests/perftests/multiuser/Android.bp1
-rw-r--r--apct-tests/perftests/multiuser/AndroidManifest.xml4
-rw-r--r--apex/blobstore/service/java/com/android/server/blob/BlobMetadata.java101
-rw-r--r--apex/blobstore/service/java/com/android/server/blob/BlobStoreConfig.java46
-rw-r--r--apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java41
-rw-r--r--apex/blobstore/service/java/com/android/server/blob/BlobStoreSession.java13
-rw-r--r--apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java8
-rw-r--r--apex/jobscheduler/service/java/com/android/server/usage/AppIdleHistory.java22
-rw-r--r--apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java154
-rw-r--r--apex/media/framework/java/android/media/MediaParser.java62
-rw-r--r--apex/statsd/framework/Android.bp24
-rw-r--r--apex/statsd/framework/test/Android.bp36
-rw-r--r--apex/statsd/framework/test/AndroidTest.xml34
-rw-r--r--api/test-current.txt3
-rw-r--r--cmds/am/src/com/android/commands/am/Instrument.java4
-rw-r--r--cmds/statsd/Android.bp46
-rw-r--r--cmds/statsd/src/atom_field_options.proto2
-rw-r--r--cmds/statsd/src/atoms.proto198
-rw-r--r--cmds/statsd/src/external/StatsPuller.cpp15
-rw-r--r--cmds/statsd/src/guardrail/StatsdStats.cpp29
-rw-r--r--cmds/statsd/src/guardrail/StatsdStats.h11
-rw-r--r--cmds/statsd/src/metrics/MetricsManager.cpp8
-rw-r--r--cmds/statsd/src/metrics/ValueMetricProducer.cpp1
-rw-r--r--cmds/statsd/src/stats_log.proto5
-rw-r--r--cmds/statsd/src/stats_log_util.cpp17
-rw-r--r--cmds/statsd/src/stats_log_util.h3
-rw-r--r--cmds/statsd/tests/FieldValue_test.cpp104
-rw-r--r--cmds/statsd/tests/StatsLogProcessor_test.cpp18
-rw-r--r--cmds/statsd/tests/guardrail/StatsdStats_test.cpp9
-rw-r--r--cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp98
-rw-r--r--config/preloaded-classes-blacklist4
-rw-r--r--core/java/android/app/Activity.java5
-rw-r--r--core/java/android/app/ActivityManager.java4
-rw-r--r--core/java/android/app/ActivityTaskManager.java14
-rw-r--r--core/java/android/app/ActivityView.java33
-rw-r--r--core/java/android/app/AppOpsManager.java47
-rw-r--r--core/java/android/app/AppOpsManagerInternal.java8
-rw-r--r--core/java/android/app/DownloadManager.java56
-rw-r--r--core/java/android/app/ExitTransitionCoordinator.java3
-rw-r--r--core/java/android/app/TaskInfo.java18
-rw-r--r--core/java/android/app/admin/DevicePolicyCache.java8
-rw-r--r--core/java/android/app/usage/NetworkStatsManager.java43
-rw-r--r--core/java/android/app/usage/UsageStatsManager.java1
-rw-r--r--core/java/android/companion/BluetoothDeviceFilterUtils.java7
-rw-r--r--core/java/android/companion/BluetoothLeDeviceFilter.java14
-rw-r--r--core/java/android/content/Intent.java2
-rw-r--r--core/java/android/content/pm/PackageParser.java44
-rw-r--r--core/java/android/content/pm/dex/ArtManagerInternal.java2
-rw-r--r--core/java/android/content/pm/parsing/ApkLiteParseUtils.java26
-rw-r--r--core/java/android/content/pm/parsing/ParsingPackageUtils.java6
-rw-r--r--core/java/android/hardware/biometrics/BiometricManager.java14
-rw-r--r--core/java/android/hardware/biometrics/BiometricPrompt.java30
-rw-r--r--core/java/android/hardware/camera2/CameraCharacteristics.java9
-rw-r--r--core/java/android/hardware/camera2/CameraMetadata.java42
-rw-r--r--core/java/android/hardware/camera2/CaptureRequest.java4
-rw-r--r--core/java/android/hardware/camera2/impl/CameraDeviceImpl.java208
-rw-r--r--core/java/android/hardware/camera2/impl/CameraOfflineSessionImpl.java73
-rw-r--r--core/java/android/hardware/camera2/impl/CaptureResultExtras.java28
-rw-r--r--core/java/android/hardware/camera2/impl/RequestLastFrameNumbersHolder.java37
-rw-r--r--core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java5
-rw-r--r--core/java/android/hardware/display/DisplayManager.java12
-rw-r--r--core/java/android/inputmethodservice/InlineSuggestionSession.java20
-rw-r--r--core/java/android/inputmethodservice/InlineSuggestionSessionController.java1
-rw-r--r--core/java/android/net/DhcpResults.java3
-rw-r--r--core/java/android/net/DnsPacket.java235
-rw-r--r--core/java/android/net/DnsResolver.java15
-rw-r--r--core/java/android/net/NetworkCapabilities.java27
-rw-r--r--core/java/android/net/NetworkUtils.java11
-rw-r--r--core/java/android/net/RouteInfo.java43
-rw-r--r--core/java/android/net/StaticIpConfiguration.java2
-rw-r--r--core/java/android/net/shared/Inet4AddressUtils.java166
-rw-r--r--core/java/android/net/shared/InetAddressUtils.java58
-rw-r--r--core/java/android/os/CarrierAssociatedAppEntry.aidl19
-rw-r--r--core/java/android/os/CarrierAssociatedAppEntry.java68
-rw-r--r--core/java/android/os/ISystemConfig.aidl5
-rw-r--r--core/java/android/os/Process.java7
-rw-r--r--core/java/android/os/StrictMode.java63
-rw-r--r--core/java/android/os/SystemConfigManager.java25
-rw-r--r--core/java/android/os/UserManager.java83
-rw-r--r--core/java/android/os/Users.md80
-rw-r--r--core/java/android/os/incremental/IIncrementalService.aidl5
-rw-r--r--core/java/android/os/incremental/IncrementalFileStorages.java7
-rw-r--r--core/java/android/os/incremental/IncrementalStorage.java11
-rw-r--r--core/java/android/os/storage/StorageManager.java32
-rw-r--r--core/java/android/os/strictmode/Violation.java51
-rw-r--r--core/java/android/permission/Permissions.md6
-rwxr-xr-xcore/java/android/provider/Settings.java31
-rw-r--r--core/java/android/service/autofill/InlineSuggestionRenderService.java31
-rw-r--r--core/java/android/service/autofill/augmented/AugmentedAutofillService.java4
-rw-r--r--core/java/android/service/autofill/augmented/FillCallback.java21
-rw-r--r--core/java/android/service/autofill/augmented/FillWindow.java26
-rw-r--r--core/java/android/service/autofill/augmented/IFillCallback.aidl4
-rw-r--r--core/java/android/service/controls/Control.java7
-rw-r--r--core/java/android/service/controls/ControlsProviderService.java4
-rw-r--r--core/java/android/service/wallpaper/WallpaperService.java3
-rw-r--r--core/java/android/telephony/PhoneStateListener.java14
-rw-r--r--core/java/android/util/FeatureFlagUtils.java1
-rw-r--r--core/java/android/util/apk/ApkSigningBlockUtils.java1
-rw-r--r--core/java/android/util/apk/SourceStampVerifier.java229
-rw-r--r--core/java/android/util/apk/TEST_MAPPING12
-rw-r--r--core/java/android/view/Display.java24
-rw-r--r--core/java/android/view/DisplayInfo.java9
-rw-r--r--core/java/android/view/ImeInsetsSourceConsumer.java10
-rw-r--r--core/java/android/view/InsetsAnimationControlCallbacks.java12
-rw-r--r--core/java/android/view/InsetsAnimationControlImpl.java47
-rw-r--r--core/java/android/view/InsetsAnimationThreadControlRunner.java5
-rw-r--r--core/java/android/view/InsetsController.java69
-rw-r--r--core/java/android/view/InsetsSourceConsumer.java12
-rw-r--r--core/java/android/view/InsetsState.java133
-rw-r--r--core/java/android/view/MotionEvent.java29
-rw-r--r--core/java/android/view/PendingInsetsController.java14
-rw-r--r--core/java/android/view/SurfaceControl.java57
-rw-r--r--core/java/android/view/SurfaceControlViewHost.java13
-rw-r--r--core/java/android/view/SurfaceView.java13
-rw-r--r--core/java/android/view/SyncRtSurfaceTransactionApplier.java12
-rw-r--r--core/java/android/view/View.java8
-rw-r--r--core/java/android/view/ViewGroup.java81
-rw-r--r--core/java/android/view/ViewRootImpl.java9
-rw-r--r--core/java/android/view/ViewRootInsetsControllerHost.java26
-rw-r--r--core/java/android/view/WindowInsetsAnimationController.java7
-rw-r--r--core/java/android/view/WindowInsetsController.java7
-rw-r--r--core/java/android/view/autofill/AutofillId.java2
-rw-r--r--core/java/android/view/contentcapture/MainContentCaptureSession.java72
-rw-r--r--core/java/android/view/inputmethod/InputMethodManager.java21
-rw-r--r--core/java/android/widget/Editor.java17
-rw-r--r--core/java/android/widget/ToastPresenter.java3
-rw-r--r--core/java/android/widget/inline/InlineContentView.java22
-rw-r--r--core/java/com/android/internal/app/ChooserActivity.java58
-rw-r--r--core/java/com/android/internal/app/ChooserListAdapter.java64
-rw-r--r--core/java/com/android/internal/app/IAppOpsService.aidl7
-rw-r--r--core/java/com/android/internal/app/ResolverActivity.java9
-rw-r--r--core/java/com/android/internal/app/ResolverListAdapter.java24
-rw-r--r--core/java/com/android/internal/app/ResolverViewPager.java6
-rw-r--r--core/java/com/android/internal/app/UnlaunchableAppActivity.java7
-rw-r--r--core/java/com/android/internal/app/procstats/ProcessStats.java28
-rw-r--r--core/java/com/android/internal/infra/ServiceConnector.java2
-rw-r--r--core/java/com/android/internal/inputmethod/InputMethodDebug.java6
-rw-r--r--core/java/com/android/internal/inputmethod/SoftInputShowHideReason.java9
-rw-r--r--core/java/com/android/internal/inputmethod/StartInputReason.java30
-rw-r--r--core/java/com/android/internal/os/FuseAppLoop.java18
-rw-r--r--core/java/com/android/internal/os/KernelCpuThreadReaderDiff.java2
-rw-r--r--core/java/com/android/internal/os/Zygote.java13
-rw-r--r--core/java/com/android/internal/policy/BackdropFrameRenderer.java46
-rw-r--r--core/java/com/android/internal/policy/DecorView.java59
-rw-r--r--core/java/com/android/internal/policy/DividerSnapAlgorithm.java11
-rw-r--r--core/java/com/android/internal/statusbar/IStatusBarService.aidl1
-rw-r--r--core/java/com/android/internal/view/IInputMethodManager.aidl3
-rw-r--r--core/java/com/android/internal/widget/ConversationLayout.java14
-rw-r--r--core/java/com/android/internal/widget/MessagingGroup.java10
-rw-r--r--core/java/com/android/internal/widget/MessagingLayout.java1
-rw-r--r--core/java/com/android/internal/widget/MessagingLinearLayout.java39
-rw-r--r--core/java/com/android/server/SystemConfig.java33
-rw-r--r--core/jni/android_media_AudioFormat.h15
-rw-r--r--core/jni/android_net_NetUtils.cpp8
-rw-r--r--core/jni/android_view_SurfaceControl.cpp14
-rw-r--r--core/proto/android/app/enums.proto1
-rw-r--r--core/proto/android/app/settings_enums.proto5
-rw-r--r--core/proto/android/stats/connectivity/Android.bp14
-rw-r--r--core/proto/android/stats/connectivity/tethering.proto97
-rw-r--r--core/proto/android/stats/launcher/launcher.proto10
-rw-r--r--core/proto/android/stats/sysui/notification_enums.proto1
-rw-r--r--core/res/AndroidManifest.xml6
-rw-r--r--core/res/res/drawable-car-night/car_dialog_button_background.xml32
-rw-r--r--core/res/res/drawable-car/car_dialog_button_background.xml20
-rw-r--r--core/res/res/drawable/chooser_action_button_bg.xml4
-rw-r--r--core/res/res/layout/chooser_action_button.xml4
-rw-r--r--core/res/res/layout/notification_template_material_conversation.xml2
-rw-r--r--core/res/res/layout/notification_template_messaging_group.xml1
-rw-r--r--core/res/res/values-af/strings.xml5
-rw-r--r--core/res/res/values-am/strings.xml1
-rw-r--r--core/res/res/values-ar/strings.xml11
-rw-r--r--core/res/res/values-as/strings.xml5
-rw-r--r--core/res/res/values-az/strings.xml1
-rw-r--r--core/res/res/values-b+sr+Latn/strings.xml7
-rw-r--r--core/res/res/values-be/strings.xml3
-rw-r--r--core/res/res/values-bg/strings.xml9
-rw-r--r--core/res/res/values-bn/strings.xml5
-rw-r--r--core/res/res/values-bs/strings.xml11
-rw-r--r--core/res/res/values-ca/strings.xml5
-rw-r--r--core/res/res/values-cs/strings.xml3
-rw-r--r--core/res/res/values-da/strings.xml5
-rw-r--r--core/res/res/values-de/strings.xml3
-rw-r--r--core/res/res/values-el/strings.xml3
-rw-r--r--core/res/res/values-en-rAU/strings.xml9
-rw-r--r--core/res/res/values-en-rCA/strings.xml21
-rw-r--r--core/res/res/values-en-rGB/strings.xml9
-rw-r--r--core/res/res/values-en-rIN/strings.xml13
-rw-r--r--core/res/res/values-en-rXC/strings.xml1
-rw-r--r--core/res/res/values-es-rUS/strings.xml5
-rw-r--r--core/res/res/values-es/strings.xml15
-rw-r--r--core/res/res/values-et/strings.xml13
-rw-r--r--core/res/res/values-eu/strings.xml21
-rw-r--r--core/res/res/values-fa/strings.xml3
-rw-r--r--core/res/res/values-fi/strings.xml3
-rw-r--r--core/res/res/values-fr-rCA/strings.xml1
-rw-r--r--core/res/res/values-fr/strings.xml1
-rw-r--r--core/res/res/values-gl/strings.xml7
-rw-r--r--core/res/res/values-gu/strings.xml1
-rw-r--r--core/res/res/values-hi/strings.xml3
-rw-r--r--core/res/res/values-hr/strings.xml5
-rw-r--r--core/res/res/values-hu/strings.xml3
-rw-r--r--core/res/res/values-hy/strings.xml3
-rw-r--r--core/res/res/values-in/strings.xml7
-rw-r--r--core/res/res/values-is/strings.xml5
-rw-r--r--core/res/res/values-it/strings.xml19
-rw-r--r--core/res/res/values-iw/strings.xml1
-rw-r--r--core/res/res/values-ja/strings.xml3
-rw-r--r--core/res/res/values-ka/strings.xml1
-rw-r--r--core/res/res/values-kk/strings.xml11
-rw-r--r--core/res/res/values-km/strings.xml1
-rw-r--r--core/res/res/values-kn/strings.xml5
-rw-r--r--core/res/res/values-ko/strings.xml5
-rw-r--r--core/res/res/values-ky/strings.xml19
-rw-r--r--core/res/res/values-lo/strings.xml3
-rw-r--r--core/res/res/values-lt/strings.xml1
-rw-r--r--core/res/res/values-lv/strings.xml1
-rw-r--r--core/res/res/values-mk/strings.xml9
-rw-r--r--core/res/res/values-ml/strings.xml81
-rw-r--r--core/res/res/values-mn/strings.xml73
-rw-r--r--core/res/res/values-mr/strings.xml1
-rw-r--r--core/res/res/values-ms/strings.xml1
-rw-r--r--core/res/res/values-my/strings.xml3
-rw-r--r--core/res/res/values-nb/strings.xml1
-rw-r--r--core/res/res/values-ne/strings.xml83
-rw-r--r--core/res/res/values-night/colors.xml1
-rw-r--r--core/res/res/values-nl/strings.xml3
-rw-r--r--core/res/res/values-or/strings.xml63
-rw-r--r--core/res/res/values-pa/strings.xml1
-rw-r--r--core/res/res/values-pl/strings.xml5
-rw-r--r--core/res/res/values-pt-rBR/strings.xml5
-rw-r--r--core/res/res/values-pt-rPT/strings.xml9
-rw-r--r--core/res/res/values-pt/strings.xml5
-rw-r--r--core/res/res/values-ro/strings.xml3
-rw-r--r--core/res/res/values-ru/strings.xml3
-rw-r--r--core/res/res/values-si/strings.xml1
-rw-r--r--core/res/res/values-sk/strings.xml11
-rw-r--r--core/res/res/values-sl/strings.xml3
-rw-r--r--core/res/res/values-sq/strings.xml1
-rw-r--r--core/res/res/values-sr/strings.xml7
-rw-r--r--core/res/res/values-sv/strings.xml5
-rw-r--r--core/res/res/values-sw/strings.xml3
-rw-r--r--core/res/res/values-ta/strings.xml1
-rw-r--r--core/res/res/values-te/strings.xml5
-rw-r--r--core/res/res/values-th/strings.xml5
-rw-r--r--core/res/res/values-tl/strings.xml17
-rw-r--r--core/res/res/values-tr/strings.xml5
-rw-r--r--core/res/res/values-uk/strings.xml9
-rw-r--r--core/res/res/values-ur/strings.xml5
-rw-r--r--core/res/res/values-uz/strings.xml5
-rw-r--r--core/res/res/values-vi/strings.xml1
-rw-r--r--core/res/res/values-zh-rCN/strings.xml9
-rw-r--r--core/res/res/values-zh-rHK/strings.xml5
-rw-r--r--core/res/res/values-zh-rTW/strings.xml5
-rw-r--r--core/res/res/values-zu/strings.xml1
-rw-r--r--core/res/res/values/colors.xml1
-rw-r--r--core/res/res/values/config.xml140
-rw-r--r--core/res/res/values/public.xml4
-rw-r--r--core/res/res/values/strings.xml3
-rw-r--r--core/res/res/values/symbols.xml5
-rw-r--r--core/tests/coretests/assets/SourceStampVerifierTest/stamp-apk-hash-mismatch-v1.apk (renamed from core/tests/coretests/assets/SourceStampVerifierTest/stamp-apk-hash-mismatch.apk)bin16854 -> 16854 bytes
-rw-r--r--core/tests/coretests/assets/SourceStampVerifierTest/stamp-apk-hash-mismatch-v2.apkbin0 -> 16854 bytes
-rw-r--r--core/tests/coretests/assets/SourceStampVerifierTest/stamp-apk-hash-mismatch-v3.apkbin0 -> 16854 bytes
-rw-r--r--core/tests/coretests/assets/SourceStampVerifierTest/stamp-certificate-mismatch.apkbin16854 -> 12758 bytes
-rw-r--r--core/tests/coretests/assets/SourceStampVerifierTest/stamp-malformed-signature.apkbin16854 -> 12758 bytes
-rw-r--r--core/tests/coretests/assets/SourceStampVerifierTest/stamp-without-block.apkbin12758 -> 12758 bytes
-rw-r--r--core/tests/coretests/assets/SourceStampVerifierTest/valid-stamp.apkbin16854 -> 16854 bytes
-rw-r--r--core/tests/coretests/src/android/util/apk/SourceStampVerifierTest.java117
-rw-r--r--core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java18
-rw-r--r--data/etc/car/Android.bp7
-rw-r--r--data/etc/car/com.android.car.companiondevicesupport.xml24
-rw-r--r--data/etc/privapp-permissions-platform.xml1
-rw-r--r--keystore/java/android/security/KeyStore.java70
-rw-r--r--libs/WindowManager/Jetpack/Android.bp14
-rw-r--r--libs/WindowManager/Jetpack/androidx.window.extensions.xml21
-rw-r--r--libs/WindowManager/Jetpack/androidx.window.sidecar.xml21
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/sidecar/SettingsSidecarImpl.java (renamed from libs/WindowManager/Jetpack/src/androidx/window/extensions/SettingsExtensionImpl.java)49
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/sidecar/SidecarHelper.java (renamed from libs/WindowManager/Jetpack/src/androidx/window/extensions/ExtensionHelper.java)11
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/sidecar/SidecarProvider.java (renamed from libs/WindowManager/Jetpack/src/androidx/window/extensions/ExtensionProvider.java)17
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/sidecar/StubSidecar.java85
-rw-r--r--libs/WindowManager/Jetpack/window-extensions-release.aarbin6427 -> 0 bytes
-rw-r--r--libs/WindowManager/Jetpack/window-sidecar-release.aarbin0 -> 4366 bytes
-rw-r--r--libs/androidfw/Idmap.cpp2
-rw-r--r--libs/androidfw/include/androidfw/ResourceTypes.h4
-rw-r--r--libs/hwui/renderthread/CacheManager.cpp2
-rw-r--r--location/java/android/location/AbstractListenerManager.java8
-rw-r--r--location/java/android/location/LocationManager.java6
-rw-r--r--media/java/android/media/AudioDeviceInfo.java3
-rwxr-xr-xmedia/java/android/media/AudioManager.java24
-rw-r--r--media/java/android/media/AudioTrack.java2
-rw-r--r--media/java/android/media/MediaRoute2Info.java17
-rw-r--r--media/java/android/media/MediaRoute2ProviderService.java14
-rw-r--r--media/java/android/media/MediaRouter.java11
-rw-r--r--media/java/android/media/MediaRouter2.java30
-rw-r--r--media/java/android/media/MediaRouter2Manager.java28
-rw-r--r--media/java/android/media/tv/tuner/filter/MediaEvent.java19
-rw-r--r--media/jni/android_media_MediaCodec.cpp21
-rw-r--r--media/jni/android_media_tv_Tuner.cpp13
-rw-r--r--media/jni/android_media_tv_Tuner.h2
-rw-r--r--media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2ManagerTest.java3
-rw-r--r--mime/java-res/android.mime.types1
-rw-r--r--packages/CarSystemUI/res/xml/overlayable.xml23
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBar.java15
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarView.java22
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewController.java71
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationVisibilityLogger.java150
-rw-r--r--packages/CarSystemUI/tests/src/com/android/systemui/car/notification/NotificationVisibilityLoggerTest.java139
-rw-r--r--packages/OsuLogin/res/values-af/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-am/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-ar/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-as/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-az/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-b+sr+Latn/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-be/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-bg/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-bn/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-bs/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-ca/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-cs/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-da/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-de/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-el/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-en-rAU/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-en-rCA/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-en-rGB/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-en-rIN/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-en-rXC/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-es-rUS/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-es/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-et/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-eu/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-fa/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-fi/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-fr-rCA/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-fr/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-gl/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-gu/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-hi/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-hr/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-hu/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-hy/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-in/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-is/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-it/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-iw/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-ja/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-ka/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-kk/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-km/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-kn/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-ko/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-ky/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-lo/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-lt/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-lv/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-mk/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-ml/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-mn/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-mr/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-ms/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-my/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-nb/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-ne/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-nl/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-or/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-pa/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-pl/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-pt-rBR/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-pt-rPT/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-pt/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-ro/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-ru/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-si/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-sk/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-sl/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-sq/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-sr/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-sv/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-sw/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-ta/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-te/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-th/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-tl/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-tr/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-uk/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-ur/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-uz/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-vi/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-zh-rCN/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-zh-rHK/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-zh-rTW/strings.xml7
-rw-r--r--packages/OsuLogin/res/values-zu/strings.xml7
-rw-r--r--packages/PrintSpooler/res/values-ca/strings.xml2
-rw-r--r--packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveOutlineDrawable.java14
-rw-r--r--packages/SettingsLib/HelpUtils/res/values-en-rCA/strings.xml2
-rw-r--r--packages/SettingsLib/SearchWidget/res/values-in/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-ar/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-bs/strings.xml10
-rw-r--r--packages/SettingsLib/res/values-en-rAU/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-en-rCA/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-en-rGB/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-en-rIN/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-fi/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-ja/arrays.xml2
-rw-r--r--packages/SettingsLib/res/values-kk/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-ne/arrays.xml2
-rw-r--r--packages/SettingsLib/res/values-ro/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-ur/strings.xml2
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/TetherUtil.java33
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/TetherUtilTest.java7
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/ApplicationsStateRoboTest.java3
-rw-r--r--packages/SettingsProvider/res/values/defaults.xml3
-rw-r--r--packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java3
-rw-r--r--packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java1
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java4
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java17
-rw-r--r--packages/Shell/AndroidManifest.xml2
-rw-r--r--packages/SoundPicker/AndroidManifest.xml1
-rw-r--r--packages/SoundPicker/res/values-af/strings.xml1
-rw-r--r--packages/SoundPicker/res/values-am/strings.xml2
-rw-r--r--packages/SoundPicker/res/values-ar/strings.xml2
-rw-r--r--packages/SoundPicker/res/values-as/strings.xml2
-rw-r--r--packages/SoundPicker/res/values-az/strings.xml2
-rw-r--r--packages/SoundPicker/res/values-b+sr+Latn/strings.xml1
-rw-r--r--packages/SoundPicker/res/values-be/strings.xml2
-rw-r--r--packages/SoundPicker/res/values-bg/strings.xml1
-rw-r--r--packages/SoundPicker/res/values-bn/strings.xml2
-rw-r--r--packages/SoundPicker/res/values-bs/strings.xml1
-rw-r--r--packages/SoundPicker/res/values-ca/strings.xml1
-rw-r--r--packages/SoundPicker/res/values-cs/strings.xml1
-rw-r--r--packages/SoundPicker/res/values-da/strings.xml1
-rw-r--r--packages/SoundPicker/res/values-de/strings.xml2
-rw-r--r--packages/SoundPicker/res/values-el/strings.xml1
-rw-r--r--packages/SoundPicker/res/values-en-rAU/strings.xml1
-rw-r--r--packages/SoundPicker/res/values-en-rCA/strings.xml1
-rw-r--r--packages/SoundPicker/res/values-en-rGB/strings.xml1
-rw-r--r--packages/SoundPicker/res/values-en-rIN/strings.xml1
-rw-r--r--packages/SoundPicker/res/values-en-rXC/strings.xml1
-rw-r--r--packages/SoundPicker/res/values-es-rUS/strings.xml1
-rw-r--r--packages/SoundPicker/res/values-es/strings.xml1
-rw-r--r--packages/SoundPicker/res/values-et/strings.xml1
-rw-r--r--packages/SoundPicker/res/values-eu/strings.xml2
-rw-r--r--packages/SoundPicker/res/values-fa/strings.xml1
-rw-r--r--packages/SoundPicker/res/values-fi/strings.xml1
-rw-r--r--packages/SoundPicker/res/values-fr-rCA/strings.xml2
-rw-r--r--packages/SoundPicker/res/values-fr/strings.xml2
-rw-r--r--packages/SoundPicker/res/values-gl/strings.xml1
-rw-r--r--packages/SoundPicker/res/values-gu/strings.xml2
-rw-r--r--packages/SoundPicker/res/values-hi/strings.xml2
-rw-r--r--packages/SoundPicker/res/values-hr/strings.xml1
-rw-r--r--packages/SoundPicker/res/values-hu/strings.xml2
-rw-r--r--packages/SoundPicker/res/values-hy/strings.xml2
-rw-r--r--packages/SoundPicker/res/values-in/strings.xml2
-rw-r--r--packages/SoundPicker/res/values-is/strings.xml1
-rw-r--r--packages/SoundPicker/res/values-it/strings.xml2
-rw-r--r--packages/SoundPicker/res/values-iw/strings.xml2
-rw-r--r--packages/SoundPicker/res/values-ja/strings.xml1
-rw-r--r--packages/SoundPicker/res/values-ka/strings.xml1
-rw-r--r--packages/SoundPicker/res/values-kk/strings.xml2
-rw-r--r--packages/SoundPicker/res/values-km/strings.xml2
-rw-r--r--packages/SoundPicker/res/values-kn/strings.xml1
-rw-r--r--packages/SoundPicker/res/values-ko/strings.xml2
-rw-r--r--packages/SoundPicker/res/values-ky/strings.xml2
-rw-r--r--packages/SoundPicker/res/values-lo/strings.xml1
-rw-r--r--packages/SoundPicker/res/values-lt/strings.xml2
-rw-r--r--packages/SoundPicker/res/values-lv/strings.xml2
-rw-r--r--packages/SoundPicker/res/values-mk/strings.xml1
-rw-r--r--packages/SoundPicker/res/values-ml/strings.xml2
-rw-r--r--packages/SoundPicker/res/values-mn/strings.xml2
-rw-r--r--packages/SoundPicker/res/values-mr/strings.xml2
-rw-r--r--packages/SoundPicker/res/values-ms/strings.xml2
-rw-r--r--packages/SoundPicker/res/values-my/strings.xml1
-rw-r--r--packages/SoundPicker/res/values-nb/strings.xml1
-rw-r--r--packages/SoundPicker/res/values-ne/strings.xml2
-rw-r--r--packages/SoundPicker/res/values-nl/strings.xml1
-rw-r--r--packages/SoundPicker/res/values-or/strings.xml2
-rw-r--r--packages/SoundPicker/res/values-pa/strings.xml2
-rw-r--r--packages/SoundPicker/res/values-pl/strings.xml2
-rw-r--r--packages/SoundPicker/res/values-pt-rBR/strings.xml1
-rw-r--r--packages/SoundPicker/res/values-pt-rPT/strings.xml1
-rw-r--r--packages/SoundPicker/res/values-pt/strings.xml1
-rw-r--r--packages/SoundPicker/res/values-ro/strings.xml1
-rw-r--r--packages/SoundPicker/res/values-ru/strings.xml1
-rw-r--r--packages/SoundPicker/res/values-si/strings.xml1
-rw-r--r--packages/SoundPicker/res/values-sk/strings.xml2
-rw-r--r--packages/SoundPicker/res/values-sl/strings.xml1
-rw-r--r--packages/SoundPicker/res/values-sq/strings.xml1
-rw-r--r--packages/SoundPicker/res/values-sr/strings.xml1
-rw-r--r--packages/SoundPicker/res/values-sv/strings.xml2
-rw-r--r--packages/SoundPicker/res/values-sw/strings.xml1
-rw-r--r--packages/SoundPicker/res/values-ta/strings.xml2
-rw-r--r--packages/SoundPicker/res/values-te/strings.xml2
-rw-r--r--packages/SoundPicker/res/values-th/strings.xml2
-rw-r--r--packages/SoundPicker/res/values-tl/strings.xml1
-rw-r--r--packages/SoundPicker/res/values-tr/strings.xml1
-rw-r--r--packages/SoundPicker/res/values-uk/strings.xml2
-rw-r--r--packages/SoundPicker/res/values-ur/strings.xml2
-rw-r--r--packages/SoundPicker/res/values-uz/strings.xml1
-rw-r--r--packages/SoundPicker/res/values-vi/strings.xml2
-rw-r--r--packages/SoundPicker/res/values-zh-rCN/strings.xml2
-rw-r--r--packages/SoundPicker/res/values-zh-rHK/strings.xml2
-rw-r--r--packages/SoundPicker/res/values-zh-rTW/strings.xml2
-rw-r--r--packages/SoundPicker/res/values-zu/strings.xml1
-rw-r--r--packages/SoundPicker/res/values/strings.xml3
-rw-r--r--packages/SystemUI/AndroidManifest.xml3
-rw-r--r--packages/SystemUI/plugin/src/com/android/systemui/plugins/FalsingManager.java6
-rw-r--r--packages/SystemUI/res-keyguard/drawable/qs_media_seamless_background.xml26
-rw-r--r--packages/SystemUI/res-keyguard/layout/qs_media_divider.xml7
-rw-r--r--packages/SystemUI/res-keyguard/values/styles.xml2
-rw-r--r--packages/SystemUI/res-product/values-ml/strings.xml2
-rw-r--r--packages/SystemUI/res-product/values-mn/strings.xml2
-rw-r--r--packages/SystemUI/res/drawable/bubble_stack_user_education_bg_rtl.xml22
-rw-r--r--packages/SystemUI/res/drawable/ic_hardware_speaker.xml24
-rw-r--r--packages/SystemUI/res/layout/auth_biometric_contents.xml34
-rw-r--r--packages/SystemUI/res/layout/bubble_manage_menu.xml8
-rw-r--r--packages/SystemUI/res/layout/bubble_stack_user_education.xml4
-rw-r--r--packages/SystemUI/res/layout/bubbles_manage_button_education.xml10
-rw-r--r--packages/SystemUI/res/layout/controls_management_favorites.xml2
-rw-r--r--packages/SystemUI/res/layout/global_actions_power_dialog.xml24
-rw-r--r--packages/SystemUI/res/layout/global_actions_power_item.xml45
-rw-r--r--packages/SystemUI/res/layout/home_handle.xml1
-rw-r--r--packages/SystemUI/res/layout/keyguard_bottom_area.xml11
-rw-r--r--packages/SystemUI/res/layout/media_carousel.xml6
-rw-r--r--packages/SystemUI/res/layout/media_carousel_settings_button.xml29
-rw-r--r--packages/SystemUI/res/layout/media_view.xml73
-rw-r--r--packages/SystemUI/res/layout/qs_panel.xml2
-rw-r--r--packages/SystemUI/res/layout/screen_record_dialog.xml209
-rw-r--r--packages/SystemUI/res/layout/tv_audio_recording_indicator.xml4
-rw-r--r--packages/SystemUI/res/values-af/strings.xml47
-rw-r--r--packages/SystemUI/res/values-am/strings.xml57
-rw-r--r--packages/SystemUI/res/values-ar/strings.xml57
-rw-r--r--packages/SystemUI/res/values-as/strings.xml57
-rw-r--r--packages/SystemUI/res/values-az/strings.xml65
-rw-r--r--packages/SystemUI/res/values-b+sr+Latn/strings.xml49
-rw-r--r--packages/SystemUI/res/values-be/strings.xml65
-rw-r--r--packages/SystemUI/res/values-bg/strings.xml47
-rw-r--r--packages/SystemUI/res/values-bn/strings.xml63
-rw-r--r--packages/SystemUI/res/values-bs/strings.xml55
-rw-r--r--packages/SystemUI/res/values-ca/strings.xml45
-rw-r--r--packages/SystemUI/res/values-cs/strings.xml43
-rw-r--r--packages/SystemUI/res/values-da/strings.xml53
-rw-r--r--packages/SystemUI/res/values-de/strings.xml60
-rw-r--r--packages/SystemUI/res/values-el/strings.xml43
-rw-r--r--packages/SystemUI/res/values-en-rAU/strings.xml41
-rw-r--r--packages/SystemUI/res/values-en-rCA/strings.xml41
-rw-r--r--packages/SystemUI/res/values-en-rGB/strings.xml41
-rw-r--r--packages/SystemUI/res/values-en-rIN/strings.xml41
-rw-r--r--packages/SystemUI/res/values-en-rXC/strings.xml41
-rw-r--r--packages/SystemUI/res/values-es-rUS/strings.xml53
-rw-r--r--packages/SystemUI/res/values-es/strings.xml53
-rw-r--r--packages/SystemUI/res/values-et/strings.xml43
-rw-r--r--packages/SystemUI/res/values-eu/strings.xml63
-rw-r--r--packages/SystemUI/res/values-fa/strings.xml41
-rw-r--r--packages/SystemUI/res/values-fi/strings.xml45
-rw-r--r--packages/SystemUI/res/values-fi/strings_tv.xml2
-rw-r--r--packages/SystemUI/res/values-fr-rCA/strings.xml69
-rw-r--r--packages/SystemUI/res/values-fr/strings.xml65
-rw-r--r--packages/SystemUI/res/values-gl/strings.xml47
-rw-r--r--packages/SystemUI/res/values-gu/strings.xml57
-rw-r--r--packages/SystemUI/res/values-hi/strings.xml61
-rw-r--r--packages/SystemUI/res/values-hr/strings.xml47
-rw-r--r--packages/SystemUI/res/values-hu/strings.xml57
-rw-r--r--packages/SystemUI/res/values-hy/strings.xml61
-rw-r--r--packages/SystemUI/res/values-in/strings.xml63
-rw-r--r--packages/SystemUI/res/values-is/strings.xml43
-rw-r--r--packages/SystemUI/res/values-it/strings.xml65
-rw-r--r--packages/SystemUI/res/values-iw/strings.xml57
-rw-r--r--packages/SystemUI/res/values-ja/strings.xml49
-rw-r--r--packages/SystemUI/res/values-ka/strings.xml41
-rw-r--r--packages/SystemUI/res/values-kk/strings.xml73
-rw-r--r--packages/SystemUI/res/values-km/strings.xml61
-rw-r--r--packages/SystemUI/res/values-kn/strings.xml44
-rw-r--r--packages/SystemUI/res/values-ko/strings.xml69
-rw-r--r--packages/SystemUI/res/values-ky/strings.xml75
-rw-r--r--packages/SystemUI/res/values-land/dimens.xml3
-rw-r--r--packages/SystemUI/res/values-lo/strings.xml43
-rw-r--r--packages/SystemUI/res/values-lt/strings.xml57
-rw-r--r--packages/SystemUI/res/values-lv/strings.xml59
-rw-r--r--packages/SystemUI/res/values-mk/strings.xml53
-rw-r--r--packages/SystemUI/res/values-ml/strings.xml64
-rw-r--r--packages/SystemUI/res/values-mn/strings.xml61
-rw-r--r--packages/SystemUI/res/values-mr/strings.xml60
-rw-r--r--packages/SystemUI/res/values-ms/strings.xml67
-rw-r--r--packages/SystemUI/res/values-my/strings.xml43
-rw-r--r--packages/SystemUI/res/values-nb/strings.xml47
-rw-r--r--packages/SystemUI/res/values-nb/strings_tv.xml2
-rw-r--r--packages/SystemUI/res/values-ne/strings.xml70
-rw-r--r--packages/SystemUI/res/values-night/colors.xml2
-rw-r--r--packages/SystemUI/res/values-nl/strings.xml43
-rw-r--r--packages/SystemUI/res/values-or/strings.xml66
-rw-r--r--packages/SystemUI/res/values-pa/strings.xml61
-rw-r--r--packages/SystemUI/res/values-pl/strings.xml59
-rw-r--r--packages/SystemUI/res/values-pl/strings_tv.xml2
-rw-r--r--packages/SystemUI/res/values-pt-rBR/strings.xml45
-rw-r--r--packages/SystemUI/res/values-pt-rPT/strings.xml51
-rw-r--r--packages/SystemUI/res/values-pt/strings.xml45
-rw-r--r--packages/SystemUI/res/values-ro/strings.xml45
-rw-r--r--packages/SystemUI/res/values-ru/strings.xml67
-rw-r--r--packages/SystemUI/res/values-si/strings.xml41
-rw-r--r--packages/SystemUI/res/values-sk/strings.xml73
-rw-r--r--packages/SystemUI/res/values-sl/strings.xml47
-rw-r--r--packages/SystemUI/res/values-sq/strings.xml45
-rw-r--r--packages/SystemUI/res/values-sr/strings.xml49
-rw-r--r--packages/SystemUI/res/values-sv/strings.xml63
-rw-r--r--packages/SystemUI/res/values-sv/strings_tv.xml2
-rw-r--r--packages/SystemUI/res/values-sw/strings.xml45
-rw-r--r--packages/SystemUI/res/values-ta/strings.xml57
-rw-r--r--packages/SystemUI/res/values-te/strings.xml57
-rw-r--r--packages/SystemUI/res/values-th/strings.xml57
-rw-r--r--packages/SystemUI/res/values-tl/strings.xml47
-rw-r--r--packages/SystemUI/res/values-tr/strings.xml43
-rw-r--r--packages/SystemUI/res/values-uk/strings.xml63
-rw-r--r--packages/SystemUI/res/values-ur/strings.xml67
-rw-r--r--packages/SystemUI/res/values-uz/strings.xml45
-rw-r--r--packages/SystemUI/res/values-vi/strings.xml61
-rw-r--r--packages/SystemUI/res/values-zh-rCN/strings.xml57
-rw-r--r--packages/SystemUI/res/values-zh-rHK/strings.xml75
-rw-r--r--packages/SystemUI/res/values-zh-rHK/strings_tv.xml2
-rw-r--r--packages/SystemUI/res/values-zh-rTW/strings.xml59
-rw-r--r--packages/SystemUI/res/values-zu/strings.xml41
-rw-r--r--packages/SystemUI/res/values/colors.xml3
-rw-r--r--packages/SystemUI/res/values/dimens.xml13
-rw-r--r--packages/SystemUI/res/values/ids.xml3
-rw-r--r--packages/SystemUI/res/values/strings.xml83
-rw-r--r--packages/SystemUI/res/xml/media_collapsed.xml47
-rw-r--r--packages/SystemUI/res/xml/media_expanded.xml15
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/ThumbnailData.java15
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplierCompat.java1
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/system/TransactionCompat.java4
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java83
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java40
-rw-r--r--packages/SystemUI/src/com/android/systemui/ForegroundServiceController.java52
-rw-r--r--packages/SystemUI/src/com/android/systemui/ForegroundServiceNotificationListener.java26
-rw-r--r--packages/SystemUI/src/com/android/systemui/ForegroundServicesUserState.java18
-rw-r--r--packages/SystemUI/src/com/android/systemui/assist/AssistHandleBehaviorController.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/assist/AssistLogger.kt142
-rw-r--r--packages/SystemUI/src/com/android/systemui/assist/AssistManager.java62
-rw-r--r--packages/SystemUI/src/com/android/systemui/assist/AssistantInvocationEvent.kt64
-rw-r--r--packages/SystemUI/src/com/android/systemui/assist/AssistantSessionEvent.kt48
-rw-r--r--packages/SystemUI/src/com/android/systemui/assist/PhoneStateMonitor.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/assist/ui/DefaultUiController.java18
-rw-r--r--packages/SystemUI/src/com/android/systemui/broadcast/ActionReceiver.kt133
-rw-r--r--packages/SystemUI/src/com/android/systemui/broadcast/BroadcastDispatcher.kt13
-rw-r--r--packages/SystemUI/src/com/android/systemui/broadcast/UserBroadcastDispatcher.kt184
-rw-r--r--packages/SystemUI/src/com/android/systemui/broadcast/logging/BroadcastDispatcherLogger.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BadgedImageView.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java25
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java152
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java70
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BubbleDataRepository.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java40
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BubbleIconFactory.java35
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BubbleManageEducationView.java23
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflowActivity.java60
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java301
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BubbleViewInfoTask.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/animation/AnimatableScaleMatrix.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java37
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/dagger/BubbleModule.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/storage/BubbleVolatileRepository.kt7
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/storage/BubbleXmlHelper.kt14
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerFake.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerImpl.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/brightline/BrightLineFalsingManager.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/ControlStatus.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManager.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt16
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt59
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/management/ControlsModel.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinatorImpl.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt46
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt48
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/ui/StatusBehavior.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/ui/ToggleRangeBehavior.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/ui/TouchBehavior.kt23
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java21
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java283
-rw-r--r--packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsPopupMenu.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsPowerDialog.java61
-rw-r--r--packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/KeyguardMediaController.kt14
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt (renamed from packages/SystemUI/src/com/android/systemui/media/MediaViewManager.kt)316
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaCarouselScrollHandler.kt516
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java111
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaData.kt53
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt215
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt32
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt71
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaHost.kt101
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaResumeListener.kt41
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaScrollView.kt100
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaTimeoutListener.kt19
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaViewController.kt147
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/PlayerViewHolder.kt14
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/ResumeMediaBrowser.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/SeekBarObserver.kt13
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/UnboundHorizontalScrollView.kt31
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java53
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/phone/PipAccessibilityInteractionConnection.java132
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java242
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/phone/PipResizeGestureHandler.java58
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java67
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchState.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/NonInterceptingScrollView.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java26
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java63
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSDetail.java30
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSPanel.java48
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java27
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordDialog.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java58
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotNotificationsController.java54
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java21
-rw-r--r--packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java18
-rw-r--r--packages/SystemUI/src/com/android/systemui/stackdivider/DividerImeController.java91
-rw-r--r--packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java87
-rw-r--r--packages/SystemUI/src/com/android/systemui/stackdivider/SplitDisplayLayout.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java55
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java96
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/MessagingLayoutTransformState.java29
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/AppOpsCoordinator.java (renamed from packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ForegroundCoordinator.java)61
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HideNotifsForOtherUsersCoordinator.java23
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/SharedCoordinatorLogger.kt38
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconManager.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java128
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationPanelLogger.java31
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/Notifications.proto11
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/AppOpsInfo.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationAppOpsEvent.java41
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationControlsEvent.java40
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java26
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java25
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MediaHeaderView.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt364
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java76
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java29
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java109
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenGestureLogger.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java76
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java23
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickswitchOrientedNavHandle.java (renamed from packages/SystemUI/src/com/android/systemui/statusbar/phone/VerticalNavigationHandle.java)40
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/RegionSamplingHelper.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationButtonController.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java20
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonRipple.java68
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityController.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/tv/micdisclosure/AudioRecordingDisclosureBar.java35
-rw-r--r--packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/ConvenienceExtensions.kt25
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/SparseArrayUtils.kt16
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/Utils.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/animation/FloatProperties.kt34
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/animation/TransitionLayout.kt20
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/animation/TransitionLayoutController.kt25
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/animation/UniqueObjectHostView.kt9
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java40
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/magnetictarget/MagnetizedObject.kt31
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/Events.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/wm/DisplayImeController.java41
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java5
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java20
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java129
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/broadcast/ActionReceiverTest.kt256
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastDispatcherTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/broadcast/FakeBroadcastDispatcher.kt3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/broadcast/UserBroadcastDispatcherTest.kt212
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleDataTest.java26
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/bubbles/NewNotifPipelineBubbleControllerTest.java6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/bubbles/TestableBubbleController.java6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/bubbles/storage/BubbleVolatileRepositoryTest.kt13
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/bubbles/storage/BubbleXmlHelperTest.kt17
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java9
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java190
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsImeTest.java34
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/KeyguardMediaControllerTest.kt3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt45
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt249
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt8
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/MediaHierarchyManagerTest.kt20
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/MediaTimeoutListenerTest.kt17
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/SeekBarObserverTest.kt17
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/pip/phone/PipTouchHandlerTest.java7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java28
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java43
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java160
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/AppOpsCoordinatorTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ForegroundCoordinatorTest.java)123
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HideNotifsForOtherUsersCoordinatorTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerTest.java53
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/AppOpsInfoTest.java32
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java52
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java11
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java79
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java82
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java16
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeSecurityController.java5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeStatusBarIconController.java5
-rw-r--r--packages/Tethering/Android.bp1
-rw-r--r--packages/Tethering/OWNERS2
-rw-r--r--packages/Tethering/common/TetheringLib/src/android/net/TetheringConstants.java38
-rw-r--r--packages/Tethering/jarjar-rules.txt18
-rw-r--r--packages/Tethering/src/android/net/dhcp/DhcpServingParamsParcelExt.java2
-rw-r--r--packages/Tethering/src/android/net/ip/IpServer.java9
-rw-r--r--packages/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java171
-rw-r--r--packages/Tethering/src/com/android/networkstack/tethering/EntitlementManager.java33
-rw-r--r--packages/Tethering/src/com/android/networkstack/tethering/Tethering.java68
-rw-r--r--packages/Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java24
-rw-r--r--packages/Tethering/src/com/android/networkstack/tethering/TetheringDependencies.java14
-rw-r--r--packages/Tethering/tests/unit/src/android/net/ip/IpServerTest.java47
-rw-r--r--packages/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java395
-rw-r--r--packages/Tethering/tests/unit/src/com/android/networkstack/tethering/EntitlementManagerTest.java53
-rw-r--r--packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringConfigurationTest.java18
-rw-r--r--packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java36
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java96
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java8
-rw-r--r--services/accessibility/java/com/android/server/accessibility/gestures/EventDispatcher.java256
-rw-r--r--services/accessibility/java/com/android/server/accessibility/gestures/GestureManifold.java9
-rw-r--r--services/accessibility/java/com/android/server/accessibility/gestures/MultiFingerMultiTap.java4
-rw-r--r--services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java23
-rw-r--r--services/accessibility/java/com/android/server/accessibility/gestures/TouchState.java117
-rw-r--r--services/autofill/java/com/android/server/autofill/AutofillInlineSessionController.java27
-rw-r--r--services/autofill/java/com/android/server/autofill/AutofillInlineSuggestionsRequestSession.java43
-rw-r--r--services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java21
-rw-r--r--services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java32
-rw-r--r--services/autofill/java/com/android/server/autofill/Session.java182
-rw-r--r--services/autofill/java/com/android/server/autofill/ui/InlineFillUi.java17
-rw-r--r--services/autofill/java/com/android/server/autofill/ui/InlineSuggestionFactory.java2
-rw-r--r--services/autofill/java/com/android/server/autofill/ui/SaveUi.java5
-rw-r--r--services/backup/java/com/android/server/backup/UserBackupManagerService.java6
-rw-r--r--services/backup/java/com/android/server/backup/restore/FullRestoreEngineThread.java4
-rw-r--r--services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java71
-rw-r--r--services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java94
-rw-r--r--services/contentcapture/java/com/android/server/contentcapture/RemoteContentCaptureService.java3
-rw-r--r--services/core/java/android/os/UserManagerInternal.java8
-rw-r--r--services/core/java/com/android/server/AlarmManagerService.java53
-rw-r--r--services/core/java/com/android/server/ConnectivityService.java38
-rw-r--r--services/core/java/com/android/server/StorageManagerService.java91
-rw-r--r--services/core/java/com/android/server/TelephonyRegistry.java37
-rw-r--r--services/core/java/com/android/server/UiModeManagerService.java13
-rw-r--r--services/core/java/com/android/server/am/ActiveServices.java4
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java50
-rw-r--r--services/core/java/com/android/server/am/ProcessStatsService.java6
-rw-r--r--services/core/java/com/android/server/am/UserController.java18
-rw-r--r--services/core/java/com/android/server/appop/AppOpsService.java47
-rwxr-xr-xservices/core/java/com/android/server/audio/AudioService.java265
-rw-r--r--services/core/java/com/android/server/connectivity/DnsManager.java19
-rw-r--r--services/core/java/com/android/server/connectivity/NetworkDiagnostics.java208
-rw-r--r--services/core/java/com/android/server/connectivity/Vpn.java3
-rw-r--r--services/core/java/com/android/server/display/DisplayDeviceInfo.java8
-rw-r--r--services/core/java/com/android/server/display/DisplayManagerService.java21
-rw-r--r--services/core/java/com/android/server/display/LocalDisplayAdapter.java2
-rw-r--r--services/core/java/com/android/server/display/LogicalDisplay.java3
-rw-r--r--services/core/java/com/android/server/display/OverlayDisplayAdapter.java4
-rw-r--r--services/core/java/com/android/server/display/VirtualDisplayAdapter.java6
-rw-r--r--services/core/java/com/android/server/display/WifiDisplayAdapter.java2
-rw-r--r--services/core/java/com/android/server/dreams/DreamManagerService.java35
-rw-r--r--services/core/java/com/android/server/gpu/GpuService.java77
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java1
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiControlService.java2
-rw-r--r--services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java15
-rw-r--r--services/core/java/com/android/server/inputmethod/InputMethodManagerService.java84
-rw-r--r--services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java16
-rw-r--r--services/core/java/com/android/server/location/gnss/GnssNetworkConnectivityHandler.java104
-rw-r--r--services/core/java/com/android/server/media/BluetoothRouteProvider.java145
-rw-r--r--services/core/java/com/android/server/media/MediaButtonReceiverHolder.java3
-rw-r--r--services/core/java/com/android/server/media/MediaKeyDispatcher.java9
-rw-r--r--services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java26
-rw-r--r--services/core/java/com/android/server/media/MediaSessionService.java667
-rw-r--r--services/core/java/com/android/server/media/SystemMediaRoute2Provider.java21
-rw-r--r--services/core/java/com/android/server/net/NetworkPolicyManagerService.java54
-rw-r--r--services/core/java/com/android/server/notification/BadgeExtractor.java13
-rw-r--r--services/core/java/com/android/server/notification/CalendarTracker.java16
-rw-r--r--services/core/java/com/android/server/notification/NotificationChannelLogger.java62
-rw-r--r--services/core/java/com/android/server/notification/NotificationChannelLoggerImpl.java9
-rw-r--r--services/core/java/com/android/server/notification/NotificationHistoryDatabase.java43
-rwxr-xr-xservices/core/java/com/android/server/notification/NotificationManagerService.java8
-rw-r--r--services/core/java/com/android/server/notification/NotificationRecordLogger.java17
-rw-r--r--services/core/java/com/android/server/notification/NotificationRecordLoggerImpl.java3
-rw-r--r--services/core/java/com/android/server/notification/PreferencesHelper.java27
-rw-r--r--services/core/java/com/android/server/notification/RankingConfig.java2
-rw-r--r--services/core/java/com/android/server/pm/AppsFilter.java498
-rw-r--r--services/core/java/com/android/server/pm/PackageAbiHelperImpl.java6
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerSession.java8
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java38
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerServiceUtils.java4
-rw-r--r--services/core/java/com/android/server/pm/StagingManager.java14
-rw-r--r--services/core/java/com/android/server/pm/UserManagerService.java27
-rw-r--r--services/core/java/com/android/server/pm/dex/ArtManagerService.java73
-rw-r--r--services/core/java/com/android/server/pm/permission/PermissionManagerService.java3
-rw-r--r--services/core/java/com/android/server/policy/PermissionPolicyService.java10
-rw-r--r--services/core/java/com/android/server/power/batterysaver/BatterySaverController.java3
-rw-r--r--services/core/java/com/android/server/stats/pull/StatsPullAtomService.java77
-rw-r--r--services/core/java/com/android/server/statusbar/StatusBarManagerService.java13
-rw-r--r--services/core/java/com/android/server/storage/AppFuseBridge.java12
-rw-r--r--services/core/java/com/android/server/storage/StorageSessionController.java5
-rw-r--r--services/core/java/com/android/server/storage/StorageUserConnection.java3
-rw-r--r--services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java52
-rw-r--r--services/core/java/com/android/server/wm/ActivityMetricsLogger.java3
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java71
-rw-r--r--services/core/java/com/android/server/wm/ActivityStack.java2
-rw-r--r--services/core/java/com/android/server/wm/ActivityStackSupervisor.java3
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskManagerService.java6
-rw-r--r--services/core/java/com/android/server/wm/AppTaskImpl.java3
-rw-r--r--services/core/java/com/android/server/wm/BLASTSyncEngine.java33
-rw-r--r--services/core/java/com/android/server/wm/BarController.java11
-rw-r--r--services/core/java/com/android/server/wm/DisplayArea.java2
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java97
-rw-r--r--services/core/java/com/android/server/wm/DisplayPolicy.java112
-rw-r--r--services/core/java/com/android/server/wm/DisplayRotation.java9
-rw-r--r--services/core/java/com/android/server/wm/InputMonitor.java50
-rw-r--r--services/core/java/com/android/server/wm/InsetsPolicy.java72
-rw-r--r--services/core/java/com/android/server/wm/InsetsStateController.java7
-rw-r--r--services/core/java/com/android/server/wm/LockTaskController.java21
-rw-r--r--services/core/java/com/android/server/wm/RecentTasks.java6
-rw-r--r--services/core/java/com/android/server/wm/RootWindowContainer.java22
-rw-r--r--services/core/java/com/android/server/wm/StatusBarController.java2
-rw-r--r--services/core/java/com/android/server/wm/SurfaceAnimationRunner.java3
-rw-r--r--services/core/java/com/android/server/wm/Task.java66
-rw-r--r--services/core/java/com/android/server/wm/TaskDisplayArea.java135
-rw-r--r--services/core/java/com/android/server/wm/TaskOrganizerController.java2
-rw-r--r--services/core/java/com/android/server/wm/TaskSnapshotController.java18
-rw-r--r--services/core/java/com/android/server/wm/TaskSnapshotSurface.java46
-rw-r--r--services/core/java/com/android/server/wm/WindowAnimator.java38
-rw-r--r--services/core/java/com/android/server/wm/WindowContainer.java54
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java78
-rw-r--r--services/core/java/com/android/server/wm/WindowOrganizerController.java20
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java138
-rw-r--r--services/core/java/com/android/server/wm/WindowStateAnimator.java13
-rw-r--r--services/core/java/com/android/server/wm/WindowSurfaceController.java4
-rw-r--r--services/core/java/com/android/server/wm/WindowToken.java42
-rw-r--r--services/core/jni/Android.bp2
-rw-r--r--services/core/jni/com_android_server_gpu_GpuService.cpp66
-rw-r--r--services/core/jni/com_android_server_location_GnssLocationProvider.cpp4
-rw-r--r--services/core/jni/com_android_server_storage_AppFuseBridge.cpp18
-rw-r--r--services/core/jni/onload.cpp2
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyCacheImpl.java8
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java26
-rw-r--r--services/incremental/BinderIncrementalService.cpp5
-rw-r--r--services/incremental/BinderIncrementalService.h2
-rw-r--r--services/incremental/IncrementalService.cpp49
-rw-r--r--services/incremental/IncrementalService.h9
-rw-r--r--services/incremental/test/IncrementalServiceTest.cpp28
-rw-r--r--services/java/com/android/server/SystemConfigService.java16
-rw-r--r--services/net/java/android/net/ip/IpClientCallbacks.java13
-rw-r--r--services/tests/PackageManagerServiceTests/host/Android.bp8
-rw-r--r--services/tests/PackageManagerServiceTests/host/resources/PackageManagerDummyAppVersion3Invalid.apkbin0 -> 2457 bytes
-rw-r--r--services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/HostUtils.kt10
-rw-r--r--services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/InvalidNewSystemAppTest.kt83
-rw-r--r--services/tests/PackageManagerServiceTests/host/test-apps/Android.bp5
-rw-r--r--services/tests/PackageManagerServiceTests/host/test-apps/AndroidManifestVersion1.xml9
-rw-r--r--services/tests/PackageManagerServiceTests/host/test-apps/AndroidManifestVersion2.xml9
-rw-r--r--services/tests/PackageManagerServiceTests/host/test-apps/AndroidManifestVersion3.xml9
-rw-r--r--services/tests/PackageManagerServiceTests/host/test-apps/AndroidManifestVersion4.xml28
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/appop/AppOpsServiceTest.java52
-rw-r--r--services/tests/servicestests/AndroidManifest.xml1
-rw-r--r--services/tests/servicestests/assets/AppIntegrityManagerServiceImplTest/SourceStampTestApk.apkbin2075621 -> 2075621 bytes
-rw-r--r--services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java2
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java133
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java13
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java403
-rw-r--r--services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java4
-rw-r--r--services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java41
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/BadgeExtractorTest.java87
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/NotificationChannelLoggerFake.java5
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryDatabaseTest.java4
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java24
-rw-r--r--services/tests/uiservicestests/src/com/android/server/slice/SliceClientPermissionsTest.java17
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java36
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java26
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java71
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java7
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java28
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java16
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java94
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java4
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java18
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java1
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java47
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java18
-rw-r--r--services/usage/java/com/android/server/usage/UsageStatsService.java154
-rw-r--r--telephony/common/com/android/internal/telephony/CarrierAppUtils.java158
-rw-r--r--telephony/common/com/android/internal/telephony/TelephonyPermissions.java43
-rwxr-xr-xtelephony/java/android/telephony/CarrierConfigManager.java9
-rw-r--r--telephony/java/android/telephony/SmsManager.java25
-rw-r--r--telephony/java/android/telephony/SubscriptionInfo.java46
-rw-r--r--telephony/java/com/android/internal/telephony/ISms.aidl10
-rw-r--r--telephony/java/com/android/internal/telephony/ISmsImplBase.java5
-rw-r--r--tests/BlobStoreTestUtils/src/com/android/utils/blob/DummyBlobData.java9
-rw-r--r--tests/BlobStoreTestUtils/src/com/android/utils/blob/Utils.java6
-rw-r--r--tests/StagedInstallTest/Android.bp31
-rw-r--r--tests/StagedInstallTest/StagedInstallInternalTest.xml33
-rw-r--r--tests/StagedInstallTest/TEST_MAPPING7
-rw-r--r--tests/StagedInstallTest/app/AndroidManifest.xml33
-rw-r--r--tests/StagedInstallTest/app/src/com/android/tests/stagedinstallinternal/StagedInstallInternalTest.java135
-rw-r--r--tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java111
-rw-r--r--tests/net/common/java/android/net/DhcpInfoTest.java3
-rw-r--r--tests/net/common/java/android/net/LinkPropertiesTest.java18
-rw-r--r--tests/net/common/java/android/net/RouteInfoTest.java42
-rw-r--r--tests/net/java/android/net/DnsPacketTest.java159
-rw-r--r--tests/net/java/android/net/NetworkUtilsTest.java60
-rw-r--r--tests/net/java/com/android/server/ConnectivityServiceTest.java27
-rw-r--r--tests/net/java/com/android/server/connectivity/DnsManagerTest.java50
-rw-r--r--tools/stats_log_api_gen/Android.bp1
-rw-r--r--tools/stats_log_api_gen/Collation.cpp11
-rw-r--r--tools/stats_log_api_gen/Collation.h4
-rw-r--r--tools/stats_log_api_gen/atoms_info_writer.cpp91
-rw-r--r--tools/stats_log_api_gen/atoms_info_writer.h35
-rw-r--r--tools/stats_log_api_gen/main.cpp61
-rw-r--r--tools/stats_log_api_gen/test.proto18
-rw-r--r--tools/stats_log_api_gen/test_collation.cpp19
-rw-r--r--tools/stats_log_api_gen/utils.h1
-rw-r--r--wifi/jarjar-rules.txt3
-rw-r--r--wifi/java/android/net/wifi/WifiEnterpriseConfig.java45
-rw-r--r--wifi/java/android/net/wifi/WifiInfo.java3
-rw-r--r--wifi/java/android/net/wifi/WifiManager.java30
-rw-r--r--wifi/tests/src/android/net/wifi/WifiEnterpriseConfigTest.java7
1056 files changed, 21810 insertions, 9866 deletions
diff --git a/Android.bp b/Android.bp
index 632f49da5df9..ec7740437c2d 100644
--- a/Android.bp
+++ b/Android.bp
@@ -264,6 +264,7 @@ filegroup {
":libcamera_client_aidl",
":libcamera_client_framework_aidl",
":libupdate_engine_aidl",
+ ":resourcemanager_aidl",
":storaged_aidl",
":vold_aidl",
@@ -700,7 +701,6 @@ filegroup {
"core/java/com/android/internal/util/TrafficStatsConstants.java",
"core/java/com/android/internal/util/WakeupMessage.java",
"core/java/com/android/internal/util/TokenBucket.java",
- "core/java/android/net/shared/*.java",
],
}
@@ -708,7 +708,6 @@ filegroup {
name: "framework-services-net-module-wifi-shared-srcs",
srcs: [
"core/java/android/net/DhcpResults.java",
- "core/java/android/net/shared/InetAddressUtils.java",
"core/java/android/net/util/IpUtils.java",
"core/java/android/util/LocalLog.java",
],
@@ -725,7 +724,6 @@ filegroup {
"core/java/com/android/internal/util/State.java",
"core/java/com/android/internal/util/StateMachine.java",
"core/java/com/android/internal/util/TrafficStatsConstants.java",
- "core/java/android/net/shared/Inet4AddressUtils.java",
],
}
@@ -1162,7 +1160,6 @@ java_library {
srcs: [
"core/java/android/content/pm/BaseParceledListSlice.java",
"core/java/android/content/pm/ParceledListSlice.java",
- "core/java/android/net/shared/Inet4AddressUtils.java",
"core/java/android/os/HandlerExecutor.java",
"core/java/com/android/internal/util/AsyncChannel.java",
"core/java/com/android/internal/util/AsyncService.java",
diff --git a/apct-tests/perftests/multiuser/Android.bp b/apct-tests/perftests/multiuser/Android.bp
index 508bf6007a9f..04432f25e337 100644
--- a/apct-tests/perftests/multiuser/Android.bp
+++ b/apct-tests/perftests/multiuser/Android.bp
@@ -17,6 +17,7 @@ android_test {
srcs: ["src/**/*.java"],
static_libs: [
"androidx.test.rules",
+ "collector-device-lib-platform",
"apct-perftests-utils",
],
platform_apis: true,
diff --git a/apct-tests/perftests/multiuser/AndroidManifest.xml b/apct-tests/perftests/multiuser/AndroidManifest.xml
index 893c8ca9328b..e4196dd6cf12 100644
--- a/apct-tests/perftests/multiuser/AndroidManifest.xml
+++ b/apct-tests/perftests/multiuser/AndroidManifest.xml
@@ -17,12 +17,16 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.perftests.multiuser">
+ <uses-sdk android:targetSdkVersion="28" />
+
<uses-permission android:name="android.permission.CONTROL_KEYGUARD" />
<uses-permission android:name="android.permission.MANAGE_USERS" />
<uses-permission android:name="android.permission.INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+ <uses-permission android:name="android.permission.REAL_GET_TASKS" />
<application>
<uses-library android:name="android.test.runner" />
diff --git a/apex/blobstore/service/java/com/android/server/blob/BlobMetadata.java b/apex/blobstore/service/java/com/android/server/blob/BlobMetadata.java
index 7e8c90632fd9..4d29045fa631 100644
--- a/apex/blobstore/service/java/com/android/server/blob/BlobMetadata.java
+++ b/apex/blobstore/service/java/com/android/server/blob/BlobMetadata.java
@@ -29,6 +29,8 @@ import static android.app.blob.XmlTags.TAG_COMMITTER;
import static android.app.blob.XmlTags.TAG_LEASEE;
import static android.os.Process.INVALID_UID;
import static android.system.OsConstants.O_RDONLY;
+import static android.text.format.Formatter.FLAG_IEC_UNITS;
+import static android.text.format.Formatter.formatFileSize;
import static com.android.server.blob.BlobStoreConfig.TAG;
import static com.android.server.blob.BlobStoreConfig.XML_VERSION_ADD_COMMIT_TIME;
@@ -335,7 +337,9 @@ class BlobMetadata {
}
void forEachLeasee(Consumer<Leasee> consumer) {
- mLeasees.forEach(consumer);
+ synchronized (mMetadataLock) {
+ mLeasees.forEach(consumer);
+ }
}
File getBlobFile() {
@@ -354,7 +358,11 @@ class BlobMetadata {
throw e.rethrowAsIOException();
}
try {
- return createRevocableFd(fd, callingPackage);
+ if (BlobStoreConfig.shouldUseRevocableFdForReads()) {
+ return createRevocableFd(fd, callingPackage);
+ } else {
+ return new ParcelFileDescriptor(fd);
+ }
} catch (IOException e) {
IoUtils.closeQuietly(fd);
throw e;
@@ -460,54 +468,57 @@ class BlobMetadata {
}
void dump(IndentingPrintWriter fout, DumpArgs dumpArgs) {
- fout.println("blobHandle:");
- fout.increaseIndent();
- mBlobHandle.dump(fout, dumpArgs.shouldDumpFull());
- fout.decreaseIndent();
-
- fout.println("Committers:");
- fout.increaseIndent();
- if (mCommitters.isEmpty()) {
- fout.println("<empty>");
- } else {
- for (int i = 0, count = mCommitters.size(); i < count; ++i) {
- final Committer committer = mCommitters.valueAt(i);
- fout.println("committer " + committer.toString());
- fout.increaseIndent();
- committer.dump(fout);
- fout.decreaseIndent();
+ synchronized (mMetadataLock) {
+ fout.println("blobHandle:");
+ fout.increaseIndent();
+ mBlobHandle.dump(fout, dumpArgs.shouldDumpFull());
+ fout.decreaseIndent();
+ fout.println("size: " + formatFileSize(mContext, getSize(), FLAG_IEC_UNITS));
+
+ fout.println("Committers:");
+ fout.increaseIndent();
+ if (mCommitters.isEmpty()) {
+ fout.println("<empty>");
+ } else {
+ for (int i = 0, count = mCommitters.size(); i < count; ++i) {
+ final Committer committer = mCommitters.valueAt(i);
+ fout.println("committer " + committer.toString());
+ fout.increaseIndent();
+ committer.dump(fout);
+ fout.decreaseIndent();
+ }
}
- }
- fout.decreaseIndent();
+ fout.decreaseIndent();
- fout.println("Leasees:");
- fout.increaseIndent();
- if (mLeasees.isEmpty()) {
- fout.println("<empty>");
- } else {
- for (int i = 0, count = mLeasees.size(); i < count; ++i) {
- final Leasee leasee = mLeasees.valueAt(i);
- fout.println("leasee " + leasee.toString());
- fout.increaseIndent();
- leasee.dump(mContext, fout);
- fout.decreaseIndent();
+ fout.println("Leasees:");
+ fout.increaseIndent();
+ if (mLeasees.isEmpty()) {
+ fout.println("<empty>");
+ } else {
+ for (int i = 0, count = mLeasees.size(); i < count; ++i) {
+ final Leasee leasee = mLeasees.valueAt(i);
+ fout.println("leasee " + leasee.toString());
+ fout.increaseIndent();
+ leasee.dump(mContext, fout);
+ fout.decreaseIndent();
+ }
}
- }
- fout.decreaseIndent();
-
- fout.println("Open fds:");
- fout.increaseIndent();
- if (mRevocableFds.isEmpty()) {
- fout.println("<empty>");
- } else {
- for (int i = 0, count = mRevocableFds.size(); i < count; ++i) {
- final String packageName = mRevocableFds.keyAt(i);
- final ArraySet<RevocableFileDescriptor> packageFds =
- mRevocableFds.valueAt(i);
- fout.println(packageName + "#" + packageFds.size());
+ fout.decreaseIndent();
+
+ fout.println("Open fds:");
+ fout.increaseIndent();
+ if (mRevocableFds.isEmpty()) {
+ fout.println("<empty>");
+ } else {
+ for (int i = 0, count = mRevocableFds.size(); i < count; ++i) {
+ final String packageName = mRevocableFds.keyAt(i);
+ final ArraySet<RevocableFileDescriptor> packageFds =
+ mRevocableFds.valueAt(i);
+ fout.println(packageName + "#" + packageFds.size());
+ }
}
+ fout.decreaseIndent();
}
- fout.decreaseIndent();
}
void writeToXml(XmlSerializer out) throws IOException {
diff --git a/apex/blobstore/service/java/com/android/server/blob/BlobStoreConfig.java b/apex/blobstore/service/java/com/android/server/blob/BlobStoreConfig.java
index 08ee24460722..265479f7c533 100644
--- a/apex/blobstore/service/java/com/android/server/blob/BlobStoreConfig.java
+++ b/apex/blobstore/service/java/com/android/server/blob/BlobStoreConfig.java
@@ -122,6 +122,25 @@ class BlobStoreConfig {
public static long COMMIT_COOL_OFF_DURATION_MS =
DEFAULT_COMMIT_COOL_OFF_DURATION_MS;
+ /**
+ * Denotes whether to use RevocableFileDescriptor when apps try to read session/blob data.
+ */
+ public static final String KEY_USE_REVOCABLE_FD_FOR_READS =
+ "use_revocable_fd_for_reads";
+ public static final boolean DEFAULT_USE_REVOCABLE_FD_FOR_READS = true;
+ public static boolean USE_REVOCABLE_FD_FOR_READS =
+ DEFAULT_USE_REVOCABLE_FD_FOR_READS;
+
+ /**
+ * Denotes how long before a blob is deleted, once the last lease on it is released.
+ */
+ public static final String KEY_DELETE_ON_LAST_LEASE_DELAY_MS =
+ "delete_on_last_lease_delay_ms";
+ public static final long DEFAULT_DELETE_ON_LAST_LEASE_DELAY_MS =
+ TimeUnit.HOURS.toMillis(6);
+ public static long DELETE_ON_LAST_LEASE_DELAY_MS =
+ DEFAULT_DELETE_ON_LAST_LEASE_DELAY_MS;
+
static void refresh(Properties properties) {
if (!NAMESPACE_BLOBSTORE.equals(properties.getNamespace())) {
return;
@@ -151,6 +170,14 @@ class BlobStoreConfig {
COMMIT_COOL_OFF_DURATION_MS = properties.getLong(key,
DEFAULT_COMMIT_COOL_OFF_DURATION_MS);
break;
+ case KEY_USE_REVOCABLE_FD_FOR_READS:
+ USE_REVOCABLE_FD_FOR_READS = properties.getBoolean(key,
+ DEFAULT_USE_REVOCABLE_FD_FOR_READS);
+ break;
+ case KEY_DELETE_ON_LAST_LEASE_DELAY_MS:
+ DELETE_ON_LAST_LEASE_DELAY_MS = properties.getLong(key,
+ DEFAULT_DELETE_ON_LAST_LEASE_DELAY_MS);
+ break;
default:
Slog.wtf(TAG, "Unknown key in device config properties: " + key);
}
@@ -178,6 +205,11 @@ class BlobStoreConfig {
fout.println(String.format(dumpFormat, KEY_COMMIT_COOL_OFF_DURATION_MS,
TimeUtils.formatDuration(COMMIT_COOL_OFF_DURATION_MS),
TimeUtils.formatDuration(DEFAULT_COMMIT_COOL_OFF_DURATION_MS)));
+ fout.println(String.format(dumpFormat, KEY_USE_REVOCABLE_FD_FOR_READS,
+ USE_REVOCABLE_FD_FOR_READS, DEFAULT_USE_REVOCABLE_FD_FOR_READS));
+ fout.println(String.format(dumpFormat, KEY_DELETE_ON_LAST_LEASE_DELAY_MS,
+ TimeUtils.formatDuration(DELETE_ON_LAST_LEASE_DELAY_MS),
+ TimeUtils.formatDuration(DEFAULT_DELETE_ON_LAST_LEASE_DELAY_MS)));
}
}
@@ -242,6 +274,20 @@ class BlobStoreConfig {
< System.currentTimeMillis();
}
+ /**
+ * Return whether to use RevocableFileDescriptor when apps try to read session/blob data.
+ */
+ public static boolean shouldUseRevocableFdForReads() {
+ return DeviceConfigProperties.USE_REVOCABLE_FD_FOR_READS;
+ }
+
+ /**
+ * Returns the duration to wait before a blob is deleted, once the last lease on it is released.
+ */
+ public static long getDeletionOnLastLeaseDelayMs() {
+ return DeviceConfigProperties.DELETE_ON_LAST_LEASE_DELAY_MS;
+ }
+
@Nullable
public static File prepareBlobFile(long sessionId) {
final File blobsDir = prepareBlobsDir();
diff --git a/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java b/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java
index 850a1d25339c..a90536fee904 100644
--- a/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java
+++ b/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java
@@ -34,6 +34,7 @@ import static com.android.server.blob.BlobStoreConfig.LOGV;
import static com.android.server.blob.BlobStoreConfig.TAG;
import static com.android.server.blob.BlobStoreConfig.XML_VERSION_CURRENT;
import static com.android.server.blob.BlobStoreConfig.getAdjustedCommitTimeMs;
+import static com.android.server.blob.BlobStoreConfig.getDeletionOnLastLeaseDelayMs;
import static com.android.server.blob.BlobStoreSession.STATE_ABANDONED;
import static com.android.server.blob.BlobStoreSession.STATE_COMMITTED;
import static com.android.server.blob.BlobStoreSession.STATE_VERIFIED_INVALID;
@@ -227,7 +228,8 @@ public class BlobStoreManagerService extends SystemService {
int n = 0;
long sessionId;
do {
- sessionId = Math.abs(mRandom.nextLong());
+ final long randomLong = mRandom.nextLong();
+ sessionId = (randomLong == Long.MIN_VALUE) ? INVALID_BLOB_ID : Math.abs(randomLong);
if (mKnownBlobIds.indexOf(sessionId) < 0 && sessionId != INVALID_BLOB_ID) {
return sessionId;
}
@@ -487,9 +489,21 @@ public class BlobStoreManagerService extends SystemService {
Slog.v(TAG, "Released lease on " + blobHandle
+ "; callingUid=" + callingUid + ", callingPackage=" + callingPackage);
}
- if (blobMetadata.shouldBeDeleted(true /* respectLeaseWaitTime */)) {
- deleteBlobLocked(blobMetadata);
- userBlobs.remove(blobHandle);
+ if (!blobMetadata.hasLeases()) {
+ mHandler.postDelayed(() -> {
+ synchronized (mBlobsLock) {
+ // Check if blobMetadata object is still valid. If it is not, then
+ // it means that it was already deleted and nothing else to do here.
+ if (!Objects.equals(userBlobs.get(blobHandle), blobMetadata)) {
+ return;
+ }
+ if (blobMetadata.shouldBeDeleted(true /* respectLeaseWaitTime */)) {
+ deleteBlobLocked(blobMetadata);
+ userBlobs.remove(blobHandle);
+ }
+ writeBlobsInfoAsync();
+ }
+ }, getDeletionOnLastLeaseDelayMs());
}
writeBlobsInfoAsync();
}
@@ -647,6 +661,17 @@ public class BlobStoreManagerService extends SystemService {
session.getOwnerUid(), blob.getBlobId(), blob.getSize(),
FrameworkStatsLog.BLOB_COMMITTED__RESULT__ERROR_DURING_COMMIT);
session.sendCommitCallbackResult(COMMIT_RESULT_ERROR);
+ // If the commit fails and this blob data didn't exist before, delete it.
+ // But if it is a recommit, just leave it as is.
+ if (session.getSessionId() == blob.getBlobId()) {
+ deleteBlobLocked(blob);
+ userBlobs.remove(blob.getBlobHandle());
+ }
+ }
+ // Delete redundant data from recommits.
+ if (session.getSessionId() != blob.getBlobId()) {
+ session.getSessionFile().delete();
+ mActiveBlobIds.remove(session.getSessionId());
}
getUserSessionsLocked(UserHandle.getUserId(session.getOwnerUid()))
.remove(session.getSessionId());
@@ -1058,10 +1083,8 @@ public class BlobStoreManagerService extends SystemService {
return shouldRemove;
});
}
- if (LOGV) {
- Slog.v(TAG, "Completed idle maintenance; deleted "
- + Arrays.toString(deletedBlobIds.toArray()));
- }
+ Slog.d(TAG, "Completed idle maintenance; deleted "
+ + Arrays.toString(deletedBlobIds.toArray()));
writeBlobSessionsAsync();
}
@@ -1543,7 +1566,7 @@ public class BlobStoreManagerService extends SystemService {
public int handleShellCommand(@NonNull ParcelFileDescriptor in,
@NonNull ParcelFileDescriptor out, @NonNull ParcelFileDescriptor err,
@NonNull String[] args) {
- return (new BlobStoreManagerShellCommand(BlobStoreManagerService.this)).exec(this,
+ return new BlobStoreManagerShellCommand(BlobStoreManagerService.this).exec(this,
in.getFileDescriptor(), out.getFileDescriptor(), err.getFileDescriptor(), args);
}
}
diff --git a/apex/blobstore/service/java/com/android/server/blob/BlobStoreSession.java b/apex/blobstore/service/java/com/android/server/blob/BlobStoreSession.java
index 51cf805aa000..baafff53d072 100644
--- a/apex/blobstore/service/java/com/android/server/blob/BlobStoreSession.java
+++ b/apex/blobstore/service/java/com/android/server/blob/BlobStoreSession.java
@@ -27,6 +27,8 @@ import static android.system.OsConstants.O_CREAT;
import static android.system.OsConstants.O_RDONLY;
import static android.system.OsConstants.O_RDWR;
import static android.system.OsConstants.SEEK_SET;
+import static android.text.format.Formatter.FLAG_IEC_UNITS;
+import static android.text.format.Formatter.formatFileSize;
import static com.android.server.blob.BlobStoreConfig.TAG;
import static com.android.server.blob.BlobStoreConfig.XML_VERSION_ADD_SESSION_CREATION_TIME;
@@ -100,7 +102,7 @@ class BlobStoreSession extends IBlobStoreSession.Stub {
private File mSessionFile;
@GuardedBy("mRevocableFds")
- private ArrayList<RevocableFileDescriptor> mRevocableFds = new ArrayList<>();
+ private final ArrayList<RevocableFileDescriptor> mRevocableFds = new ArrayList<>();
// This will be accessed from only one thread at any point of time, so no need to grab
// a lock for this.
@@ -266,6 +268,13 @@ class BlobStoreSession extends IBlobStoreSession.Stub {
throw new IllegalStateException("Not allowed to read in state: "
+ stateToString(mState));
}
+ if (!BlobStoreConfig.shouldUseRevocableFdForReads()) {
+ try {
+ return new ParcelFileDescriptor(openReadInternal());
+ } catch (IOException e) {
+ throw ExceptionUtils.wrap(e);
+ }
+ }
}
FileDescriptor fd = null;
@@ -281,7 +290,6 @@ class BlobStoreSession extends IBlobStoreSession.Stub {
trackRevocableFdLocked(revocableFd);
return revocableFd.getRevocableFileDescriptor();
}
-
} catch (IOException e) {
IoUtils.closeQuietly(fd);
throw ExceptionUtils.wrap(e);
@@ -533,6 +541,7 @@ class BlobStoreSession extends IBlobStoreSession.Stub {
fout.println("ownerUid: " + mOwnerUid);
fout.println("ownerPkg: " + mOwnerPackageName);
fout.println("creation time: " + BlobStoreUtils.formatTime(mCreationTimeMs));
+ fout.println("size: " + formatFileSize(mContext, getSize(), FLAG_IEC_UNITS));
fout.println("blobHandle:");
fout.increaseIndent();
diff --git a/apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java b/apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java
index 887d82c6413f..e15f0f37fc62 100644
--- a/apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java
+++ b/apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java
@@ -71,7 +71,7 @@ public interface AppStandbyInternal {
*/
void postOneTimeCheckIdleStates();
- void reportEvent(UsageEvents.Event event, long elapsedRealtime, int userId);
+ void reportEvent(UsageEvents.Event event, int userId);
void setLastJobRunTime(String packageName, int userId, long elapsedRealtime);
@@ -150,9 +150,7 @@ public interface AppStandbyInternal {
void clearCarrierPrivilegedApps();
- void flushToDisk(int userId);
-
- void flushDurationsToDisk();
+ void flushToDisk();
void initializeDefaultsForSystemApps(int userId);
@@ -162,7 +160,7 @@ public interface AppStandbyInternal {
void postReportExemptedSyncStart(String packageName, int userId);
- void dumpUser(IndentingPrintWriter idpw, int userId, List<String> pkgs);
+ void dumpUsers(IndentingPrintWriter idpw, int[] userIds, List<String> pkgs);
void dumpState(String[] args, PrintWriter pw);
diff --git a/apex/jobscheduler/service/java/com/android/server/usage/AppIdleHistory.java b/apex/jobscheduler/service/java/com/android/server/usage/AppIdleHistory.java
index 372ec981df02..70155ee84720 100644
--- a/apex/jobscheduler/service/java/com/android/server/usage/AppIdleHistory.java
+++ b/apex/jobscheduler/service/java/com/android/server/usage/AppIdleHistory.java
@@ -675,6 +675,14 @@ public class AppIdleHistory {
return Long.parseLong(value);
}
+
+ public void writeAppIdleTimes() {
+ final int size = mIdleHistory.size();
+ for (int i = 0; i < size; i++) {
+ writeAppIdleTimes(mIdleHistory.keyAt(i));
+ }
+ }
+
public void writeAppIdleTimes(int userId) {
FileOutputStream fos = null;
AtomicFile appIdleFile = new AtomicFile(getUserFile(userId));
@@ -743,8 +751,18 @@ public class AppIdleHistory {
}
}
- public void dump(IndentingPrintWriter idpw, int userId, List<String> pkgs) {
- idpw.println("App Standby States:");
+ public void dumpUsers(IndentingPrintWriter idpw, int[] userIds, List<String> pkgs) {
+ final int numUsers = userIds.length;
+ for (int i = 0; i < numUsers; i++) {
+ idpw.println();
+ dumpUser(idpw, userIds[i], pkgs);
+ }
+ }
+
+ private void dumpUser(IndentingPrintWriter idpw, int userId, List<String> pkgs) {
+ idpw.print("User ");
+ idpw.print(userId);
+ idpw.println(" App Standby States:");
idpw.increaseIndent();
ArrayMap<String, AppUsageHistory> userHistory = mIdleHistory.get(userId);
final long elapsedRealtime = SystemClock.elapsedRealtime();
diff --git a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
index 062108757349..687b1d4e0bde 100644
--- a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
+++ b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
@@ -82,18 +82,18 @@ import android.os.BatteryStats;
import android.os.Build;
import android.os.Environment;
import android.os.Handler;
+import android.os.IDeviceIdleController;
import android.os.Looper;
import android.os.Message;
import android.os.PowerManager;
-import android.os.PowerWhitelistManager;
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
+import android.os.Trace;
import android.os.UserHandle;
import android.provider.Settings.Global;
import android.telephony.TelephonyManager;
-import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.KeyValueListParser;
import android.util.Slog;
@@ -205,6 +205,10 @@ public class AppStandbyController implements AppStandbyInternal {
*/
private static final long WAIT_FOR_ADMIN_DATA_TIMEOUT_MS = 10_000;
+ private static final int HEADLESS_APP_CHECK_FLAGS =
+ PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
+ | PackageManager.GET_ACTIVITIES | PackageManager.MATCH_DISABLED_COMPONENTS;
+
// To name the lock for stack traces
static class Lock {}
@@ -234,10 +238,18 @@ public class AppStandbyController implements AppStandbyInternal {
* disabled). Presence in this map indicates that the app is a headless system app.
*/
@GuardedBy("mHeadlessSystemApps")
- private final ArrayMap<String, Boolean> mHeadlessSystemApps = new ArrayMap<>();
+ private final ArraySet<String> mHeadlessSystemApps = new ArraySet<>();
private final CountDownLatch mAdminDataAvailableLatch = new CountDownLatch(1);
+ // Cache the active network scorer queried from the network scorer service
+ private volatile String mCachedNetworkScorer = null;
+ // The last time the network scorer service was queried
+ private volatile long mCachedNetworkScorerAtMillis = 0L;
+ // How long before querying the network scorer again. During this time, subsequent queries will
+ // get the cached value
+ private static final long NETWORK_SCORER_CACHE_DURATION_MILLIS = 5000L;
+
// Messages for the handler
static final int MSG_INFORM_LISTENERS = 3;
static final int MSG_FORCE_IDLE_STATE = 4;
@@ -387,6 +399,7 @@ public class AppStandbyController implements AppStandbyInternal {
DeviceStateReceiver deviceStateReceiver = new DeviceStateReceiver();
IntentFilter deviceStates = new IntentFilter(BatteryManager.ACTION_CHARGING);
deviceStates.addAction(BatteryManager.ACTION_DISCHARGING);
+ deviceStates.addAction(PowerManager.ACTION_POWER_SAVE_WHITELIST_CHANGED);
mContext.registerReceiver(deviceStateReceiver, deviceStates);
synchronized (mAppIdleLock) {
@@ -442,6 +455,9 @@ public class AppStandbyController implements AppStandbyInternal {
mSystemServicesReady = true;
+ // Offload to handler thread to avoid boot time impact.
+ mHandler.post(mInjector::updatePowerWhitelistCache);
+
boolean userFileExists;
synchronized (mAppIdleLock) {
userFileExists = mAppIdleHistory.userFileExists(UserHandle.USER_SYSTEM);
@@ -850,7 +866,7 @@ public class AppStandbyController implements AppStandbyInternal {
}
@Override
- public void reportEvent(UsageEvents.Event event, long elapsedRealtime, int userId) {
+ public void reportEvent(UsageEvents.Event event, int userId) {
if (!mAppIdleEnabled) return;
final int eventType = event.getEventType();
if ((eventType == UsageEvents.Event.ACTIVITY_RESUMED
@@ -864,6 +880,7 @@ public class AppStandbyController implements AppStandbyInternal {
final String pkg = event.getPackageName();
final List<UserHandle> linkedProfiles = getCrossProfileTargets(pkg, userId);
synchronized (mAppIdleLock) {
+ final long elapsedRealtime = mInjector.elapsedRealtime();
reportEventLocked(pkg, eventType, elapsedRealtime, userId);
final int size = linkedProfiles.size();
@@ -1080,15 +1097,11 @@ public class AppStandbyController implements AppStandbyInternal {
return STANDBY_BUCKET_EXEMPTED;
}
if (mSystemServicesReady) {
- try {
- // We allow all whitelisted apps, including those that don't want to be whitelisted
- // for idle mode, because app idle (aka app standby) is really not as big an issue
- // for controlling who participates vs. doze mode.
- if (mInjector.isNonIdleWhitelisted(packageName)) {
- return STANDBY_BUCKET_EXEMPTED;
- }
- } catch (RemoteException re) {
- throw re.rethrowFromSystemServer();
+ // We allow all whitelisted apps, including those that don't want to be whitelisted
+ // for idle mode, because app idle (aka app standby) is really not as big an issue
+ // for controlling who participates vs. doze mode.
+ if (mInjector.isNonIdleWhitelisted(packageName)) {
+ return STANDBY_BUCKET_EXEMPTED;
}
if (isActiveDeviceAdmin(packageName, userId)) {
@@ -1123,7 +1136,7 @@ public class AppStandbyController implements AppStandbyInternal {
private boolean isHeadlessSystemApp(String packageName) {
synchronized (mHeadlessSystemApps) {
- return mHeadlessSystemApps.containsKey(packageName);
+ return mHeadlessSystemApps.contains(packageName);
}
}
@@ -1157,6 +1170,8 @@ public class AppStandbyController implements AppStandbyInternal {
return new int[0];
}
+ Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "getIdleUidsForUser");
+
final long elapsedRealtime = mInjector.elapsedRealtime();
List<ApplicationInfo> apps;
@@ -1192,6 +1207,7 @@ public class AppStandbyController implements AppStandbyInternal {
uidStates.setValueAt(index, value + 1 + (idle ? 1<<16 : 0));
}
}
+
if (DEBUG) {
Slog.d(TAG, "getIdleUids took " + (mInjector.elapsedRealtime() - elapsedRealtime));
}
@@ -1213,6 +1229,8 @@ public class AppStandbyController implements AppStandbyInternal {
}
}
+ Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
+
return res;
}
@@ -1579,8 +1597,16 @@ public class AppStandbyController implements AppStandbyInternal {
}
private boolean isActiveNetworkScorer(String packageName) {
- String activeScorer = mInjector.getActiveNetworkScorer();
- return packageName != null && packageName.equals(activeScorer);
+ // Validity of network scorer cache is limited to a few seconds. Fetch it again
+ // if longer since query.
+ // This is a temporary optimization until there's a callback mechanism for changes to network scorer.
+ final long now = SystemClock.elapsedRealtime();
+ if (mCachedNetworkScorer == null
+ || mCachedNetworkScorerAtMillis < now - NETWORK_SCORER_CACHE_DURATION_MILLIS) {
+ mCachedNetworkScorer = mInjector.getActiveNetworkScorer();
+ mCachedNetworkScorerAtMillis = now;
+ }
+ return packageName != null && packageName.equals(mCachedNetworkScorer);
}
private void informListeners(String packageName, int userId, int bucket, int reason,
@@ -1605,18 +1631,11 @@ public class AppStandbyController implements AppStandbyInternal {
}
}
- @Override
- public void flushToDisk(int userId) {
- synchronized (mAppIdleLock) {
- mAppIdleHistory.writeAppIdleTimes(userId);
- }
- }
@Override
- public void flushDurationsToDisk() {
- // Persist elapsed and screen on time. If this fails for whatever reason, the apps will be
- // considered not-idle, which is the safest outcome in such an event.
+ public void flushToDisk() {
synchronized (mAppIdleLock) {
+ mAppIdleHistory.writeAppIdleTimes();
mAppIdleHistory.writeAppIdleDurations();
}
}
@@ -1695,9 +1714,8 @@ public class AppStandbyController implements AppStandbyInternal {
return;
}
try {
- PackageInfo pi = mPackageManager.getPackageInfoAsUser(packageName,
- PackageManager.GET_ACTIVITIES | PackageManager.MATCH_DISABLED_COMPONENTS,
- userId);
+ PackageInfo pi = mPackageManager.getPackageInfoAsUser(
+ packageName, HEADLESS_APP_CHECK_FLAGS, userId);
evaluateSystemAppException(pi);
} catch (PackageManager.NameNotFoundException e) {
synchronized (mHeadlessSystemApps) {
@@ -1709,15 +1727,16 @@ public class AppStandbyController implements AppStandbyInternal {
/** Returns true if the exception status changed. */
private boolean evaluateSystemAppException(@Nullable PackageInfo pkgInfo) {
if (pkgInfo == null || pkgInfo.applicationInfo == null
- || !pkgInfo.applicationInfo.isSystemApp()) {
+ || (!pkgInfo.applicationInfo.isSystemApp()
+ && !pkgInfo.applicationInfo.isUpdatedSystemApp())) {
return false;
}
synchronized (mHeadlessSystemApps) {
if (pkgInfo.activities == null || pkgInfo.activities.length == 0) {
// Headless system app.
- return mHeadlessSystemApps.put(pkgInfo.packageName, true) == null;
+ return mHeadlessSystemApps.add(pkgInfo.packageName);
} else {
- return mHeadlessSystemApps.remove(pkgInfo.packageName) != null;
+ return mHeadlessSystemApps.remove(pkgInfo.packageName);
}
}
}
@@ -1754,12 +1773,11 @@ public class AppStandbyController implements AppStandbyInternal {
}
}
- /** Call on a system update to temporarily reset system app buckets. */
+ /** Call on system boot to get the initial set of headless system apps. */
private void loadHeadlessSystemAppCache() {
Slog.d(TAG, "Loading headless system app cache. appIdleEnabled=" + mAppIdleEnabled);
final List<PackageInfo> packages = mPackageManager.getInstalledPackagesAsUser(
- PackageManager.GET_ACTIVITIES | PackageManager.MATCH_DISABLED_COMPONENTS,
- UserHandle.USER_SYSTEM);
+ HEADLESS_APP_CHECK_FLAGS, UserHandle.USER_SYSTEM);
final int packageCount = packages.size();
for (int i = 0; i < packageCount; i++) {
PackageInfo pkgInfo = packages.get(i);
@@ -1794,9 +1812,9 @@ public class AppStandbyController implements AppStandbyInternal {
}
@Override
- public void dumpUser(IndentingPrintWriter idpw, int userId, List<String> pkgs) {
+ public void dumpUsers(IndentingPrintWriter idpw, int[] userIds, List<String> pkgs) {
synchronized (mAppIdleLock) {
- mAppIdleHistory.dump(idpw, userId, pkgs);
+ mAppIdleHistory.dumpUsers(idpw, userIds, pkgs);
}
}
@@ -1807,8 +1825,6 @@ public class AppStandbyController implements AppStandbyInternal {
+ "): " + mCarrierPrivilegedApps);
}
- final long now = System.currentTimeMillis();
-
pw.println();
pw.println("Settings:");
@@ -1868,12 +1884,14 @@ public class AppStandbyController implements AppStandbyInternal {
synchronized (mHeadlessSystemApps) {
for (int i = mHeadlessSystemApps.size() - 1; i >= 0; --i) {
pw.print(" ");
- pw.print(mHeadlessSystemApps.keyAt(i));
+ pw.print(mHeadlessSystemApps.valueAt(i));
pw.println(",");
}
}
pw.println("]");
pw.println();
+
+ mInjector.dump(pw);
}
/**
@@ -1890,7 +1908,7 @@ public class AppStandbyController implements AppStandbyInternal {
private PackageManagerInternal mPackageManagerInternal;
private DisplayManager mDisplayManager;
private PowerManager mPowerManager;
- private PowerWhitelistManager mPowerWhitelistManager;
+ private IDeviceIdleController mDeviceIdleController;
private CrossProfileAppsInternal mCrossProfileAppsInternal;
int mBootPhase;
/**
@@ -1898,6 +1916,11 @@ public class AppStandbyController implements AppStandbyInternal {
* automatically placed in the RESTRICTED bucket.
*/
long mAutoRestrictedBucketDelayMs = ONE_DAY;
+ /**
+ * Cached set of apps that are power whitelisted, including those not whitelisted from idle.
+ */
+ @GuardedBy("mPowerWhitelistedApps")
+ private final ArraySet<String> mPowerWhitelistedApps = new ArraySet<>();
Injector(Context context, Looper looper) {
mContext = context;
@@ -1914,7 +1937,8 @@ public class AppStandbyController implements AppStandbyInternal {
void onBootPhase(int phase) {
if (phase == PHASE_SYSTEM_SERVICES_READY) {
- mPowerWhitelistManager = mContext.getSystemService(PowerWhitelistManager.class);
+ mDeviceIdleController = IDeviceIdleController.Stub.asInterface(
+ ServiceManager.getService(Context.DEVICE_IDLE_CONTROLLER));
mBatteryStats = IBatteryStats.Stub.asInterface(
ServiceManager.getService(BatteryStats.SERVICE_NAME));
mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
@@ -1965,8 +1989,34 @@ public class AppStandbyController implements AppStandbyInternal {
return mBatteryManager.isCharging();
}
- boolean isNonIdleWhitelisted(String packageName) throws RemoteException {
- return mPowerWhitelistManager.isWhitelisted(packageName, false);
+ boolean isNonIdleWhitelisted(String packageName) {
+ if (mBootPhase < PHASE_SYSTEM_SERVICES_READY) {
+ return false;
+ }
+ synchronized (mPowerWhitelistedApps) {
+ return mPowerWhitelistedApps.contains(packageName);
+ }
+ }
+
+ private void updatePowerWhitelistCache() {
+ if (mBootPhase < PHASE_SYSTEM_SERVICES_READY) {
+ return;
+ }
+ try {
+ // Don't call out to DeviceIdleController with the lock held.
+ final String[] whitelistedPkgs =
+ mDeviceIdleController.getFullPowerWhitelistExceptIdle();
+ synchronized (mPowerWhitelistedApps) {
+ mPowerWhitelistedApps.clear();
+ final int len = whitelistedPkgs.length;
+ for (int i = 0; i < len; ++i) {
+ mPowerWhitelistedApps.add(whitelistedPkgs[i]);
+ }
+ }
+ } catch (RemoteException e) {
+ // Should not happen.
+ Slog.wtf(TAG, "Failed to get power whitelist", e);
+ }
}
boolean isRestrictedBucketEnabled() {
@@ -2053,6 +2103,19 @@ public class AppStandbyController implements AppStandbyInternal {
}
return mCrossProfileAppsInternal.getTargetUserProfiles(pkg, userId);
}
+
+ void dump(PrintWriter pw) {
+ pw.println("mPowerWhitelistedApps=[");
+ synchronized (mPowerWhitelistedApps) {
+ for (int i = mPowerWhitelistedApps.size() - 1; i >= 0; --i) {
+ pw.print(" ");
+ pw.print(mPowerWhitelistedApps.valueAt(i));
+ pw.println(",");
+ }
+ }
+ pw.println("]");
+ pw.println();
+ }
}
class AppStandbyHandler extends Handler {
@@ -2138,6 +2201,11 @@ public class AppStandbyController implements AppStandbyInternal {
case BatteryManager.ACTION_DISCHARGING:
setChargingState(false);
break;
+ case PowerManager.ACTION_POWER_SAVE_WHITELIST_CHANGED:
+ if (mSystemServicesReady) {
+ mHandler.post(mInjector::updatePowerWhitelistCache);
+ }
+ break;
}
}
}
diff --git a/apex/media/framework/java/android/media/MediaParser.java b/apex/media/framework/java/android/media/MediaParser.java
index 19f578ecfc66..8a3fbde5609b 100644
--- a/apex/media/framework/java/android/media/MediaParser.java
+++ b/apex/media/framework/java/android/media/MediaParser.java
@@ -31,6 +31,7 @@ import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.ParserException;
import com.google.android.exoplayer2.drm.DrmInitData.SchemeData;
+import com.google.android.exoplayer2.extractor.ChunkIndex;
import com.google.android.exoplayer2.extractor.DefaultExtractorInput;
import com.google.android.exoplayer2.extractor.Extractor;
import com.google.android.exoplayer2.extractor.ExtractorInput;
@@ -817,6 +818,30 @@ public final class MediaParser {
public static final String PARAMETER_EXPOSE_DUMMY_SEEKMAP =
"android.media.mediaparser.exposeDummySeekMap";
+ /**
+ * Sets whether chunk indices available in the extracted media should be exposed as {@link
+ * MediaFormat MediaFormats}. {@code boolean} expected. Default value is {@link false}.
+ *
+ * <p>When set to true, any information about media segmentation will be exposed as a {@link
+ * MediaFormat} (with track index 0) containing four {@link ByteBuffer} elements under the
+ * following keys:
+ *
+ * <ul>
+ * <li>"chunk-index-int-sizes": Contains {@code ints} representing the sizes in bytes of each
+ * of the media segments.
+ * <li>"chunk-index-long-offsets": Contains {@code longs} representing the byte offsets of
+ * each segment in the stream.
+ * <li>"chunk-index-long-us-durations": Contains {@code longs} representing the media duration
+ * of each segment, in microseconds.
+ * <li>"chunk-index-long-us-times": Contains {@code longs} representing the start time of each
+ * segment, in microseconds.
+ * </ul>
+ *
+ * @hide
+ */
+ public static final String PARAMETER_EXPOSE_CHUNK_INDEX_AS_MEDIA_FORMAT =
+ "android.media.mediaParser.exposeChunkIndexAsMediaFormat";
+
// Private constants.
private static final String TAG = "MediaParser";
@@ -980,6 +1005,7 @@ public final class MediaParser {
private boolean mIgnoreTimestampOffset;
private boolean mEagerlyExposeTrackType;
private boolean mExposeDummySeekMap;
+ private boolean mExposeChunkIndexAsMediaFormat;
private String mParserName;
private Extractor mExtractor;
private ExtractorInput mExtractorInput;
@@ -1042,6 +1068,9 @@ public final class MediaParser {
if (PARAMETER_EXPOSE_DUMMY_SEEKMAP.equals(parameterName)) {
mExposeDummySeekMap = (boolean) value;
}
+ if (PARAMETER_EXPOSE_CHUNK_INDEX_AS_MEDIA_FORMAT.equals(parameterName)) {
+ mExposeChunkIndexAsMediaFormat = (boolean) value;
+ }
mParserParameters.put(parameterName, value);
return this;
}
@@ -1436,6 +1465,19 @@ public final class MediaParser {
@Override
public void seekMap(com.google.android.exoplayer2.extractor.SeekMap exoplayerSeekMap) {
+ if (mExposeChunkIndexAsMediaFormat && exoplayerSeekMap instanceof ChunkIndex) {
+ ChunkIndex chunkIndex = (ChunkIndex) exoplayerSeekMap;
+ MediaFormat mediaFormat = new MediaFormat();
+ mediaFormat.setByteBuffer("chunk-index-int-sizes", toByteBuffer(chunkIndex.sizes));
+ mediaFormat.setByteBuffer(
+ "chunk-index-long-offsets", toByteBuffer(chunkIndex.offsets));
+ mediaFormat.setByteBuffer(
+ "chunk-index-long-us-durations", toByteBuffer(chunkIndex.durationsUs));
+ mediaFormat.setByteBuffer(
+ "chunk-index-long-us-times", toByteBuffer(chunkIndex.timesUs));
+ mOutputConsumer.onTrackDataFound(
+ /* trackIndex= */ 0, new TrackData(mediaFormat, /* drmInitData= */ null));
+ }
mOutputConsumer.onSeekMapFound(new SeekMap(exoplayerSeekMap));
}
}
@@ -1823,6 +1865,24 @@ public final class MediaParser {
return result;
}
+ private static ByteBuffer toByteBuffer(long[] longArray) {
+ ByteBuffer byteBuffer = ByteBuffer.allocateDirect(longArray.length * Long.BYTES);
+ for (long element : longArray) {
+ byteBuffer.putLong(element);
+ }
+ byteBuffer.flip();
+ return byteBuffer;
+ }
+
+ private static ByteBuffer toByteBuffer(int[] intArray) {
+ ByteBuffer byteBuffer = ByteBuffer.allocateDirect(intArray.length * Integer.BYTES);
+ for (int element : intArray) {
+ byteBuffer.putInt(element);
+ }
+ byteBuffer.flip();
+ return byteBuffer;
+ }
+
private static String toTypeString(int type) {
switch (type) {
case C.TRACK_TYPE_VIDEO:
@@ -1979,6 +2039,8 @@ public final class MediaParser {
expectedTypeByParameterName.put(PARAMETER_IGNORE_TIMESTAMP_OFFSET, Boolean.class);
expectedTypeByParameterName.put(PARAMETER_EAGERLY_EXPOSE_TRACKTYPE, Boolean.class);
expectedTypeByParameterName.put(PARAMETER_EXPOSE_DUMMY_SEEKMAP, Boolean.class);
+ expectedTypeByParameterName.put(
+ PARAMETER_EXPOSE_CHUNK_INDEX_AS_MEDIA_FORMAT, Boolean.class);
EXPECTED_TYPE_BY_PARAMETER_NAME = Collections.unmodifiableMap(expectedTypeByParameterName);
}
}
diff --git a/apex/statsd/framework/Android.bp b/apex/statsd/framework/Android.bp
index 15a2f22e0fea..d19faa97e223 100644
--- a/apex/statsd/framework/Android.bp
+++ b/apex/statsd/framework/Android.bp
@@ -74,6 +74,7 @@ java_sdk_library {
visibility: [
"//frameworks/base", // Framework
"//frameworks/base/apex/statsd:__subpackages__", // statsd apex
+ "//frameworks/base/packages/Tethering", // Tethering
"//frameworks/opt/net/wifi/service", // wifi service
"//packages/providers/MediaProvider", // MediaProvider apk
],
@@ -89,26 +90,3 @@ java_sdk_library {
"test_com.android.os.statsd",
],
}
-
-android_test {
- name: "FrameworkStatsdTest",
- platform_apis: true,
- srcs: [
- // TODO(b/147705194): Use framework-statsd as a lib dependency instead.
- ":framework-statsd-sources",
- "test/**/*.java",
- ],
- manifest: "test/AndroidManifest.xml",
- static_libs: [
- "androidx.test.rules",
- "truth-prebuilt",
- ],
- libs: [
- "android.test.runner.stubs",
- "android.test.base.stubs",
- ],
- test_suites: [
- "device-tests",
- ],
-}
-
diff --git a/apex/statsd/framework/test/Android.bp b/apex/statsd/framework/test/Android.bp
new file mode 100644
index 000000000000..b113d595b57c
--- /dev/null
+++ b/apex/statsd/framework/test/Android.bp
@@ -0,0 +1,36 @@
+// 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.
+
+android_test {
+ name: "FrameworkStatsdTest",
+ platform_apis: true,
+ srcs: [
+ // TODO(b/147705194): Use framework-statsd as a lib dependency instead.
+ ":framework-statsd-sources",
+ "**/*.java",
+ ],
+ manifest: "AndroidManifest.xml",
+ static_libs: [
+ "androidx.test.rules",
+ "truth-prebuilt",
+ ],
+ libs: [
+ "android.test.runner.stubs",
+ "android.test.base.stubs",
+ ],
+ test_suites: [
+ "device-tests",
+ "mts",
+ ],
+} \ No newline at end of file
diff --git a/apex/statsd/framework/test/AndroidTest.xml b/apex/statsd/framework/test/AndroidTest.xml
new file mode 100644
index 000000000000..fb519150ecd5
--- /dev/null
+++ b/apex/statsd/framework/test/AndroidTest.xml
@@ -0,0 +1,34 @@
+<?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.
+-->
+<configuration description="Runs Tests for Statsd.">
+ <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
+ <option name="test-file-name" value="FrameworkStatsdTest.apk" />
+ <option name="install-arg" value="-g" />
+ </target_preparer>
+
+ <option name="test-suite-tag" value="apct" />
+ <option name="test-suite-tag" value="mts" />
+ <option name="test-tag" value="FrameworkStatsdTest" />
+ <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+ <option name="package" value="com.android.os.statsd.framework.test" />
+ <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
+ <option name="hidden-api-checks" value="false"/>
+ </test>
+
+ <object type="module_controller" class="com.android.tradefed.testtype.suite.module.MainlineTestModuleController">
+ <option name="mainline-module-package-name" value="com.google.android.os.statsd" />
+ </object>
+</configuration> \ No newline at end of file
diff --git a/api/test-current.txt b/api/test-current.txt
index 795d873ec69c..95f6289b0e79 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -32,6 +32,7 @@ package android {
}
public static final class R.bool {
+ field public static final int config_assistantOnTopOfDream = 17891333; // 0x1110005
field public static final int config_perDisplayFocusEnabled = 17891332; // 0x1110004
}
@@ -5103,6 +5104,7 @@ package android.view {
method @NonNull public android.graphics.ColorSpace[] getSupportedWideColorGamut();
method public int getType();
method public boolean hasAccess(int);
+ field public static final int FLAG_TRUSTED = 128; // 0x80
field public static final int TYPE_EXTERNAL = 2; // 0x2
field public static final int TYPE_INTERNAL = 1; // 0x1
field public static final int TYPE_OVERLAY = 4; // 0x4
@@ -5262,6 +5264,7 @@ package android.view.autofill {
ctor public AutofillId(int, int);
ctor public AutofillId(@NonNull android.view.autofill.AutofillId, long, int);
method public boolean equalsIgnoreSession(@Nullable android.view.autofill.AutofillId);
+ method @NonNull public static android.view.autofill.AutofillId withoutSession(@NonNull android.view.autofill.AutofillId);
}
public final class AutofillManager {
diff --git a/cmds/am/src/com/android/commands/am/Instrument.java b/cmds/am/src/com/android/commands/am/Instrument.java
index 2adbc1f6e1ae..7c30c8b1e1dd 100644
--- a/cmds/am/src/com/android/commands/am/Instrument.java
+++ b/cmds/am/src/com/android/commands/am/Instrument.java
@@ -17,8 +17,8 @@
package com.android.commands.am;
import static android.app.ActivityManager.INSTR_FLAG_DISABLE_HIDDEN_API_CHECKS;
+import static android.app.ActivityManager.INSTR_FLAG_DISABLE_ISOLATED_STORAGE;
import static android.app.ActivityManager.INSTR_FLAG_DISABLE_TEST_API_CHECKS;
-import static android.app.ActivityManager.INSTR_FLAG_MOUNT_EXTERNAL_STORAGE_FULL;
import android.app.IActivityManager;
import android.app.IInstrumentationWatcher;
@@ -512,7 +512,7 @@ public class Instrument {
flags |= INSTR_FLAG_DISABLE_TEST_API_CHECKS;
}
if (disableIsolatedStorage) {
- flags |= INSTR_FLAG_MOUNT_EXTERNAL_STORAGE_FULL;
+ flags |= INSTR_FLAG_DISABLE_ISOLATED_STORAGE;
}
if (!mAm.startInstrumentation(cn, profileFile, flags, args, watcher, connection, userId,
abi)) {
diff --git a/cmds/statsd/Android.bp b/cmds/statsd/Android.bp
index 3dbe41395024..0617eb6c0e66 100644
--- a/cmds/statsd/Android.bp
+++ b/cmds/statsd/Android.bp
@@ -116,7 +116,6 @@ cc_defaults {
"libcutils",
"libgtest_prod",
"libprotoutil",
- "libstatsmetadata",
"libstatslog_statsd",
"libsysutils",
"libutils",
@@ -129,51 +128,6 @@ cc_defaults {
],
}
-// ================
-// libstatsmetadata
-// ================
-
-genrule {
- name: "atoms_info.h",
- tools: ["stats-log-api-gen"],
- cmd: "$(location stats-log-api-gen) --atomsInfoHeader $(genDir)/atoms_info.h",
- out: [
- "atoms_info.h",
- ],
-}
-
-genrule {
- name: "atoms_info.cpp",
- tools: ["stats-log-api-gen"],
- cmd: "$(location stats-log-api-gen) --atomsInfoCpp $(genDir)/atoms_info.cpp",
- out: [
- "atoms_info.cpp",
- ],
-}
-
-cc_library_static {
- name: "libstatsmetadata",
- host_supported: true,
- generated_sources: [
- "atoms_info.cpp",
- ],
- generated_headers: [
- "atoms_info.h",
- ],
- cflags: [
- "-Wall",
- "-Werror",
- ],
- export_generated_headers: [
- "atoms_info.h",
- ],
- apex_available: [
- //TODO(b/149782403): Remove this once statsd no longer links against libstatsmetadata
- "com.android.os.statsd",
- "test_com.android.os.statsd",
- ],
-}
-
genrule {
name: "statslog_statsd.h",
tools: ["stats-log-api-gen"],
diff --git a/cmds/statsd/src/atom_field_options.proto b/cmds/statsd/src/atom_field_options.proto
index 8527185d3891..ff5717e4fa78 100644
--- a/cmds/statsd/src/atom_field_options.proto
+++ b/cmds/statsd/src/atom_field_options.proto
@@ -110,8 +110,6 @@ extend google.protobuf.FieldOptions {
optional LogMode log_mode = 50002 [default = MODE_AUTOMATIC];
- optional bool allow_from_any_uid = 50003 [default = false];
-
repeated string module = 50004;
optional bool truncate_timestamp = 50005 [default = false];
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index 278278fc18c4..a5f0ac97cebc 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -43,6 +43,7 @@ import "frameworks/base/core/proto/android/server/location/enums.proto";
import "frameworks/base/core/proto/android/service/procstats_enum.proto";
import "frameworks/base/core/proto/android/service/usb.proto";
import "frameworks/base/core/proto/android/stats/connectivity/network_stack.proto";
+import "frameworks/base/core/proto/android/stats/connectivity/tethering.proto";
import "frameworks/base/core/proto/android/stats/dnsresolver/dns_resolver.proto";
import "frameworks/base/core/proto/android/stats/devicepolicy/device_policy.proto";
import "frameworks/base/core/proto/android/stats/devicepolicy/device_policy_enums.proto";
@@ -144,8 +145,7 @@ message Atom {
PacketWakeupOccurred packet_wakeup_occurred = 44 [(module) = "framework"];
WallClockTimeShifted wall_clock_time_shifted = 45 [(module) = "framework"];
AnomalyDetected anomaly_detected = 46 [(module) = "statsd"];
- AppBreadcrumbReported app_breadcrumb_reported =
- 47 [(allow_from_any_uid) = true, (module) = "statsd"];
+ AppBreadcrumbReported app_breadcrumb_reported = 47 [(module) = "statsd"];
AppStartOccurred app_start_occurred = 48 [(module) = "framework", (module) = "statsdtest"];
AppStartCanceled app_start_canceled = 49 [(module) = "framework"];
AppStartFullyDrawn app_start_fully_drawn = 50 [(module) = "framework"];
@@ -156,7 +156,7 @@ message Atom {
AppStartMemoryStateCaptured app_start_memory_state_captured = 55 [(module) = "framework"];
ShutdownSequenceReported shutdown_sequence_reported = 56 [(module) = "framework"];
BootSequenceReported boot_sequence_reported = 57;
- DaveyOccurred davey_occurred = 58 [(allow_from_any_uid) = true, (module) = "statsd"];
+ DaveyOccurred davey_occurred = 58 [(module) = "statsd"];
OverlayStateChanged overlay_state_changed =
59 [(module) = "framework", (module) = "statsdtest"];
ForegroundServiceStateChanged foreground_service_state_changed
@@ -185,8 +185,7 @@ message Atom {
WTFOccurred wtf_occurred = 80 [(module) = "framework"];
LowMemReported low_mem_reported = 81 [(module) = "framework"];
GenericAtom generic_atom = 82;
- KeyValuePairsAtom key_value_pairs_atom =
- 83 [(allow_from_any_uid) = true, (module) = "framework", (module) = "statsd"];
+ KeyValuePairsAtom key_value_pairs_atom = 83 [(module) = "framework", (module) = "statsd"];
VibratorStateChanged vibrator_state_changed = 84 [(module) = "framework"];
DeferredJobStatsReported deferred_job_stats_reported = 85 [(module) = "framework"];
ThermalThrottlingStateChanged thermal_throttling = 86 [deprecated=true];
@@ -316,7 +315,7 @@ message Atom {
AssistGestureFeedbackReported assist_gesture_feedback_reported = 175 [(module) = "sysui"];
AssistGestureProgressReported assist_gesture_progress_reported = 176 [(module) = "sysui"];
TouchGestureClassified touch_gesture_classified = 177 [(module) = "framework"];
- HiddenApiUsed hidden_api_used = 178 [(allow_from_any_uid) = true, (module) = "framework"];
+ HiddenApiUsed hidden_api_used = 178 [(module) = "framework"];
StyleUIChanged style_ui_changed = 179 [(module) = "sysui"];
PrivacyIndicatorsInteracted privacy_indicators_interacted =
180 [(module) = "permissioncontroller"];
@@ -382,7 +381,7 @@ message Atom {
UpdateEngineSuccessfulUpdateReported update_engine_successful_update_reported = 226;
CameraActionEvent camera_action_event = 227 [(module) = "framework"];
AppCompatibilityChangeReported app_compatibility_change_reported =
- 228 [(allow_from_any_uid) = true, (module) = "framework"];
+ 228 [(module) = "framework"];
PerfettoUploaded perfetto_uploaded = 229 [(module) = "perfetto"];
VmsClientConnectionStateChanged vms_client_connection_state_changed =
230 [(module) = "car"];
@@ -481,6 +480,11 @@ message Atom {
BlobCommitted blob_committed = 298 [(module) = "framework"];
BlobLeased blob_leased = 299 [(module) = "framework"];
BlobOpened blob_opened = 300 [(module) = "framework"];
+ ContactsProviderStatusReported contacts_provider_status_reported = 301;
+ KeystoreKeyEventReported keystore_key_event_reported = 302;
+ NetworkTetheringReported network_tethering_reported =
+ 303 [(module) = "network_tethering"];
+ ImeTouchReported ime_touch_reported = 304 [(module) = "sysui"];
// StatsdStats tracks platform atoms with ids upto 500.
// Update StatsdStats::kMaxPushedAtomId when atom ids here approach that value.
@@ -3056,6 +3060,18 @@ message ExclusionRectStateChanged {
}
/**
+ * Logs when IME is on.
+ *
+ * Logged from: /packages/SystemUI/src/com/android/systemui/
+ statusbar/phone/NavigationBarView.java
+ *
+ */
+message ImeTouchReported {
+ optional int32 x_coordinate = 1; // X coordinate for ACTION_DOWN event.
+ optional int32 y_coordinate = 2; // Y coordinate for ACTION_DOWN event.
+}
+
+/**
* Logs when Launcher (HomeScreen) UI has changed or was interacted.
*
* Logged from:
@@ -6889,6 +6905,24 @@ message AppCompacted {
}
/**
+ * Logs when a Tethering event occurs.
+ *
+ */
+message NetworkTetheringReported {
+ // tethering error code
+ optional android.stats.connectivity.ErrorCode error_code = 1;
+
+ // tethering downstream type
+ optional android.stats.connectivity.DownstreamType downstream_type = 2;
+
+ // transport type of upstream network
+ optional android.stats.connectivity.UpstreamType upstream_type = 3;
+
+ // The user type of Tethering
+ optional android.stats.connectivity.UserType user_type= 4;
+}
+
+/**
* Logs a DNS lookup operation initiated by the system resolver on behalf of an application
* invoking native APIs such as getaddrinfo() or Java APIs such as Network#getAllByName().
*
@@ -9907,6 +9941,48 @@ message TvCasSessionOpenStatus {
}
/**
+ * Logs for ContactsProvider general usage.
+ * This is atom ID 301.
+ *
+ * Logged from:
+ * packages/providers/ContactsProvider/src/com/android/providers/contacts/ContactsProvider2.java
+ */
+message ContactsProviderStatusReported {
+ enum ApiType {
+ UNKNOWN_API = 0;
+ QUERY = 1;
+ // INSERT includes insert and bulkInsert, and inserts triggered by applyBatch.
+ INSERT = 2;
+ // UPDATE and DELETE includes update/delete and the ones triggered by applyBatch.
+ UPDATE = 3;
+ DELETE = 4;
+ }
+
+ enum ResultType {
+ UNKNOWN_RESULT = 0;
+ SUCCESS = 1;
+ FAIL = 2;
+ ILLEGAL_ARGUMENT = 3;
+ UNSUPPORTED_OPERATION = 4;
+ }
+
+ enum CallerType {
+ UNSPECIFIED_CALLER_TYPE = 0;
+ CALLER_IS_SYNC_ADAPTER = 1;
+ CALLER_IS_NOT_SYNC_ADAPTER = 2;
+ }
+
+ optional ApiType api_type = 1;
+ // Defined in
+ // packages/providers/ContactsProvider/src/com/android/providers/contacts/ContactsProvider2.java
+ optional int32 uri_type = 2;
+ optional CallerType caller_type = 3;
+ optional ResultType result_type = 4;
+ optional int32 result_count = 5;
+ optional int64 latency_micros = 6;
+}
+
+/**
* Logs when an app is frozen or unfrozen.
*
* Logged from:
@@ -10883,6 +10959,114 @@ message MediametricsAudioDeviceConnectionReported {
optional int32 connection_count = 6;
}
+/**
+ * Logs: i) creation of different types of cryptographic keys in the keystore,
+ * ii) operations performed using the keys,
+ * iii) attestation of the keys
+ * Logged from: system/security/keystore/key_event_log_handler.cpp
+ */
+message KeystoreKeyEventReported {
+
+ enum Algorithm {
+ /** Asymmetric algorithms. */
+ RSA = 1;
+ // 2 removed, do not reuse.
+ EC = 3;
+ /** Block cipher algorithms */
+ AES = 32;
+ TRIPLE_DES = 33;
+ /** MAC algorithms */
+ HMAC = 128;
+ };
+ /** Algorithm associated with the key */
+ optional Algorithm algorithm = 1;
+
+ /** Size of the key */
+ optional int32 key_size = 2;
+
+ enum KeyOrigin {
+ /** Generated in keymaster. Should not exist outside the TEE. */
+ GENERATED = 0;
+ /** Derived inside keymaster. Likely exists off-device. */
+ DERIVED = 1;
+ /** Imported into keymaster. Existed as cleartext in Android. */
+ IMPORTED = 2;
+ /** Keymaster did not record origin. */
+ UNKNOWN = 3;
+ /** Securely imported into Keymaster. */
+ SECURELY_IMPORTED = 4;
+ };
+ /* Logs whether the key was generated, imported, securely imported, or derived.*/
+ optional KeyOrigin key_origin = 3;
+
+ enum HardwareAuthenticatorType {
+ NONE = 0;
+ PASSWORD = 1;
+ FINGERPRINT = 2;
+ // Additional entries must be powers of 2.
+ };
+ /**
+ * What auth types does this key require? If none,
+ * then no auth required.
+ */
+ optional HardwareAuthenticatorType user_auth_type = 4;
+
+ /**
+ * If user authentication is required, is the requirement time based? If it
+ * is not time based then this field will not be used and the key is per
+ * operation. Per operation keys must be user authenticated on each usage.
+ */
+ optional int32 user_auth_key_timeout_secs = 5;
+
+ /**
+ * padding mode, digest, block_mode and purpose should ideally be repeated
+ * fields. However, since statsd does not support repeated fields in
+ * pushed atoms, they are represented using bitmaps.
+ */
+
+ /** Track which padding mode is being used.*/
+ optional int32 padding_mode_bitmap = 6;
+
+ /** Track which digest is being used. */
+ optional int32 digest_bitmap = 7;
+
+ /** Track what block mode is being used (for encryption). */
+ optional int32 block_mode_bitmap = 8;
+
+ /** Track what purpose is this key serving. */
+ optional int32 purpose_bitmap = 9;
+
+ enum EcCurve {
+ P_224 = 0;
+ P_256 = 1;
+ P_384 = 2;
+ P_521 = 3;
+ };
+ /** Which ec curve was selected if elliptic curve cryptography is in use **/
+ optional EcCurve ec_curve = 10;
+
+ enum KeyBlobUsageRequirements {
+ STANDALONE = 0;
+ REQUIRES_FILE_SYSTEM = 1;
+ };
+ /** Standalone or is a file system required */
+ optional KeyBlobUsageRequirements key_blob_usage_reqs = 11;
+
+ enum Type {
+ key_operation = 0;
+ key_creation = 1;
+ key_attestation = 2;
+ }
+ /** Key creation event, operation event or attestation event? */
+ optional Type type = 12;
+
+ /** Was the key creation, operation, or attestation successful? */
+ optional bool was_successful = 13;
+
+ /** Response code or error code */
+ optional int32 error_code = 14;
+}
+
// Blob Committer stats
// Keep in sync between:
// frameworks/base/core/proto/android/server/blobstoremanagerservice.proto
diff --git a/cmds/statsd/src/external/StatsPuller.cpp b/cmds/statsd/src/external/StatsPuller.cpp
index 9df4d1f8ce24..bb5d0a6bab58 100644
--- a/cmds/statsd/src/external/StatsPuller.cpp
+++ b/cmds/statsd/src/external/StatsPuller.cpp
@@ -44,7 +44,8 @@ StatsPuller::StatsPuller(const int tagId, const int64_t coolDownNs, const int64_
bool StatsPuller::Pull(const int64_t eventTimeNs, std::vector<std::shared_ptr<LogEvent>>* data) {
lock_guard<std::mutex> lock(mLock);
- int64_t elapsedTimeNs = getElapsedRealtimeNs();
+ const int64_t elapsedTimeNs = getElapsedRealtimeNs();
+ const int64_t systemUptimeMillis = getSystemUptimeMillis();
StatsdStats::getInstance().notePull(mTagId);
const bool shouldUseCache =
(mLastEventTimeNs == eventTimeNs) || (elapsedTimeNs - mLastPullTimeNs < mCoolDownNs);
@@ -67,16 +68,18 @@ bool StatsPuller::Pull(const int64_t eventTimeNs, std::vector<std::shared_ptr<Lo
if (!mHasGoodData) {
return mHasGoodData;
}
- const int64_t pullDurationNs = getElapsedRealtimeNs() - elapsedTimeNs;
- StatsdStats::getInstance().notePullTime(mTagId, pullDurationNs);
- const bool pullTimeOut = pullDurationNs > mPullTimeoutNs;
+ const int64_t pullElapsedDurationNs = getElapsedRealtimeNs() - elapsedTimeNs;
+ const int64_t pullSystemUptimeDurationMillis = getSystemUptimeMillis() - systemUptimeMillis;
+ StatsdStats::getInstance().notePullTime(mTagId, pullElapsedDurationNs);
+ const bool pullTimeOut = pullElapsedDurationNs > mPullTimeoutNs;
if (pullTimeOut) {
// Something went wrong. Discard the data.
mCachedData.clear();
mHasGoodData = false;
- StatsdStats::getInstance().notePullTimeout(mTagId);
+ StatsdStats::getInstance().notePullTimeout(
+ mTagId, pullSystemUptimeDurationMillis, NanoToMillis(pullElapsedDurationNs));
ALOGW("Pull for atom %d exceeds timeout %lld nano seconds.", mTagId,
- (long long)pullDurationNs);
+ (long long)pullElapsedDurationNs);
return mHasGoodData;
}
diff --git a/cmds/statsd/src/guardrail/StatsdStats.cpp b/cmds/statsd/src/guardrail/StatsdStats.cpp
index c027fffd20a0..6e89038f4152 100644
--- a/cmds/statsd/src/guardrail/StatsdStats.cpp
+++ b/cmds/statsd/src/guardrail/StatsdStats.cpp
@@ -38,6 +38,7 @@ using android::util::ProtoOutputStream;
using std::lock_guard;
using std::shared_ptr;
using std::string;
+using std::to_string;
using std::vector;
const int FIELD_ID_BEGIN_TIME = 1;
@@ -436,9 +437,18 @@ void StatsdStats::notePullDataError(int pullAtomId) {
mPulledAtomStats[pullAtomId].dataError++;
}
-void StatsdStats::notePullTimeout(int pullAtomId) {
+void StatsdStats::notePullTimeout(int pullAtomId,
+ int64_t pullUptimeMillis,
+ int64_t pullElapsedMillis) {
lock_guard<std::mutex> lock(mLock);
- mPulledAtomStats[pullAtomId].pullTimeout++;
+ PulledAtomStats& pulledAtomStats = mPulledAtomStats[pullAtomId];
+ pulledAtomStats.pullTimeout++;
+
+ if (pulledAtomStats.pullTimeoutMetadata.size() == kMaxTimestampCount) {
+ pulledAtomStats.pullTimeoutMetadata.pop_front();
+ }
+
+ pulledAtomStats.pullTimeoutMetadata.emplace_back(pullUptimeMillis, pullElapsedMillis);
}
void StatsdStats::notePullExceedMaxDelay(int pullAtomId) {
@@ -630,6 +640,7 @@ void StatsdStats::resetInternalLocked() {
pullStats.second.unregisteredCount = 0;
pullStats.second.atomErrorCount = 0;
pullStats.second.binderCallFailCount = 0;
+ pullStats.second.pullTimeoutMetadata.clear();
}
mAtomMetricStats.clear();
mActivationBroadcastGuardrailStats.clear();
@@ -786,6 +797,20 @@ void StatsdStats::dumpStats(int out) const {
pair.second.pullUidProviderNotFound, pair.second.pullerNotFound,
pair.second.registeredCount, pair.second.unregisteredCount,
pair.second.atomErrorCount);
+ if (pair.second.pullTimeoutMetadata.size() > 0) {
+ string uptimeMillis = "(pull timeout system uptime millis) ";
+ string pullTimeoutMillis = "(pull timeout elapsed time millis) ";
+ for (const auto& stats : pair.second.pullTimeoutMetadata) {
+ uptimeMillis.append(to_string(stats.pullTimeoutUptimeMillis)).append(",");;
+ pullTimeoutMillis.append(to_string(stats.pullTimeoutElapsedMillis)).append(",");
+ }
+ uptimeMillis.pop_back();
+ uptimeMillis.push_back('\n');
+ pullTimeoutMillis.pop_back();
+ pullTimeoutMillis.push_back('\n');
+ dprintf(out, "%s", uptimeMillis.c_str());
+ dprintf(out, "%s", pullTimeoutMillis.c_str());
+ }
}
if (mAnomalyAlarmRegisteredStats > 0) {
diff --git a/cmds/statsd/src/guardrail/StatsdStats.h b/cmds/statsd/src/guardrail/StatsdStats.h
index 9d46dcea1896..005048446fc3 100644
--- a/cmds/statsd/src/guardrail/StatsdStats.h
+++ b/cmds/statsd/src/guardrail/StatsdStats.h
@@ -352,7 +352,7 @@ public:
/*
* Records pull exceeds timeout for the puller.
*/
- void notePullTimeout(int pullAtomId);
+ void notePullTimeout(int pullAtomId, int64_t pullUptimeMillis, int64_t pullElapsedMillis);
/*
* Records pull exceeds max delay for a metric.
@@ -498,6 +498,14 @@ public:
*/
void dumpStats(int outFd) const;
+ typedef struct PullTimeoutMetadata {
+ int64_t pullTimeoutUptimeMillis;
+ int64_t pullTimeoutElapsedMillis;
+ PullTimeoutMetadata(int64_t uptimeMillis, int64_t elapsedMillis) :
+ pullTimeoutUptimeMillis(uptimeMillis),
+ pullTimeoutElapsedMillis(elapsedMillis) {/* do nothing */}
+ } PullTimeoutMetadata;
+
typedef struct {
long totalPull = 0;
long totalPullFromCache = 0;
@@ -519,6 +527,7 @@ public:
long unregisteredCount = 0;
int32_t atomErrorCount = 0;
long binderCallFailCount = 0;
+ std::list<PullTimeoutMetadata> pullTimeoutMetadata;
} PulledAtomStats;
typedef struct {
diff --git a/cmds/statsd/src/metrics/MetricsManager.cpp b/cmds/statsd/src/metrics/MetricsManager.cpp
index 7e825efddb75..60de1a24cce5 100644
--- a/cmds/statsd/src/metrics/MetricsManager.cpp
+++ b/cmds/statsd/src/metrics/MetricsManager.cpp
@@ -21,7 +21,6 @@
#include <private/android_filesystem_config.h>
#include "CountMetricProducer.h"
-#include "atoms_info.h"
#include "condition/CombinationConditionTracker.h"
#include "condition/SimpleConditionTracker.h"
#include "guardrail/StatsdStats.h"
@@ -372,13 +371,6 @@ void MetricsManager::onDumpReport(const int64_t dumpTimeStampNs,
bool MetricsManager::checkLogCredentials(const LogEvent& event) {
- // TODO(b/154856835): Remove this check once we get whitelist from the config.
- if (android::util::AtomsInfo::kWhitelistedAtoms.find(event.GetTagId()) !=
- android::util::AtomsInfo::kWhitelistedAtoms.end())
- {
- return true;
- }
-
if (mWhitelistedAtomIds.find(event.GetTagId()) != mWhitelistedAtomIds.end()) {
return true;
}
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.cpp b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
index 9dcba7cad9a8..5987a723a421 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
@@ -951,6 +951,7 @@ void ValueMetricProducer::flushCurrentBucketLocked(const int64_t& eventTimeNs,
const int64_t& nextBucketStartTimeNs) {
if (mCondition == ConditionState::kUnknown) {
StatsdStats::getInstance().noteBucketUnknownCondition(mMetricId);
+ invalidateCurrentBucketWithoutResetBase(eventTimeNs, BucketDropReason::CONDITION_UNKNOWN);
}
VLOG("finalizing bucket for %ld, dumping %d slices", (long)mCurrentBucketStartTimeNs,
diff --git a/cmds/statsd/src/stats_log.proto b/cmds/statsd/src/stats_log.proto
index 6bfa26761b2f..ddd2725c9cb9 100644
--- a/cmds/statsd/src/stats_log.proto
+++ b/cmds/statsd/src/stats_log.proto
@@ -467,6 +467,11 @@ message StatsdStatsReport {
optional int64 binder_call_failed = 19;
optional int64 failed_uid_provider_not_found = 20;
optional int64 puller_not_found = 21;
+ message PullTimeoutMetadata {
+ optional int64 pull_timeout_uptime_millis = 1;
+ optional int64 pull_timeout_elapsed_millis = 2;
+ }
+ repeated PullTimeoutMetadata pull_atom_metadata = 22;
}
repeated PulledAtomStats pulled_atom_stats = 10;
diff --git a/cmds/statsd/src/stats_log_util.cpp b/cmds/statsd/src/stats_log_util.cpp
index bafdfcba59b2..423bae8bc0a4 100644
--- a/cmds/statsd/src/stats_log_util.cpp
+++ b/cmds/statsd/src/stats_log_util.cpp
@@ -81,6 +81,9 @@ const int FIELD_ID_ATOM_ERROR_COUNT = 18;
const int FIELD_ID_BINDER_CALL_FAIL_COUNT = 19;
const int FIELD_ID_PULL_UID_PROVIDER_NOT_FOUND = 20;
const int FIELD_ID_PULLER_NOT_FOUND = 21;
+const int FIELD_ID_PULL_TIMEOUT_METADATA = 22;
+const int FIELD_ID_PULL_TIMEOUT_METADATA_UPTIME_MILLIS = 1;
+const int FIELD_ID_PULL_TIMEOUT_METADATA_ELAPSED_MILLIS = 2;
// for AtomMetricStats proto
const int FIELD_ID_ATOM_METRIC_STATS = 17;
@@ -497,6 +500,16 @@ void writePullerStatsToStream(const std::pair<int, StatsdStats::PulledAtomStats>
(long long)pair.second.pullUidProviderNotFound);
protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_PULLER_NOT_FOUND,
(long long)pair.second.pullerNotFound);
+ for (const auto& pullTimeoutMetadata : pair.second.pullTimeoutMetadata) {
+ uint64_t timeoutMetadataToken = protoOutput->start(FIELD_TYPE_MESSAGE |
+ FIELD_ID_PULL_TIMEOUT_METADATA |
+ FIELD_COUNT_REPEATED);
+ protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_PULL_TIMEOUT_METADATA_UPTIME_MILLIS,
+ pullTimeoutMetadata.pullTimeoutUptimeMillis);
+ protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_PULL_TIMEOUT_METADATA_ELAPSED_MILLIS,
+ pullTimeoutMetadata.pullTimeoutElapsedMillis);
+ protoOutput->end(timeoutMetadataToken);
+ }
protoOutput->end(token);
}
@@ -542,6 +555,10 @@ int64_t getElapsedRealtimeMillis() {
return ::android::elapsedRealtime();
}
+int64_t getSystemUptimeMillis() {
+ return ::android::uptimeMillis();
+}
+
int64_t getWallClockNs() {
return time(nullptr) * NS_PER_SEC;
}
diff --git a/cmds/statsd/src/stats_log_util.h b/cmds/statsd/src/stats_log_util.h
index 20d93b5a5365..eb65dc6979c5 100644
--- a/cmds/statsd/src/stats_log_util.h
+++ b/cmds/statsd/src/stats_log_util.h
@@ -61,6 +61,9 @@ int64_t getElapsedRealtimeMillis();
// Gets the elapsed timestamp in seconds.
int64_t getElapsedRealtimeSec();
+// Gets the system uptime in millis.
+int64_t getSystemUptimeMillis();
+
// Gets the wall clock timestamp in ns.
int64_t getWallClockNs();
diff --git a/cmds/statsd/tests/FieldValue_test.cpp b/cmds/statsd/tests/FieldValue_test.cpp
index 23f8ca4e74e6..a21eb9b9147f 100644
--- a/cmds/statsd/tests/FieldValue_test.cpp
+++ b/cmds/statsd/tests/FieldValue_test.cpp
@@ -33,6 +33,12 @@ namespace android {
namespace os {
namespace statsd {
+// These constants must be kept in sync with those in StatsDimensionsValue.java.
+const static int STATS_DIMENSIONS_VALUE_STRING_TYPE = 2;
+const static int STATS_DIMENSIONS_VALUE_INT_TYPE = 3;
+const static int STATS_DIMENSIONS_VALUE_FLOAT_TYPE = 6;
+const static int STATS_DIMENSIONS_VALUE_TUPLE_TYPE = 7;
+
namespace {
void makeLogEvent(LogEvent* logEvent, const int32_t atomId, const int64_t timestamp,
const vector<int>& attributionUids, const vector<string>& attributionTags,
@@ -291,34 +297,76 @@ TEST(AtomMatcherTest, TestWriteDimensionPath) {
}
}
-//TODO(b/149050405) Update this test for StatsDimensionValueParcel
-//TEST(AtomMatcherTest, TestSubscriberDimensionWrite) {
-// HashableDimensionKey dim;
-//
-// int pos1[] = {1, 1, 1};
-// int pos2[] = {1, 1, 2};
-// int pos3[] = {1, 1, 3};
-// int pos4[] = {2, 0, 0};
-//
-// Field field1(10, pos1, 2);
-// Field field2(10, pos2, 2);
-// Field field3(10, pos3, 2);
-// Field field4(10, pos4, 0);
-//
-// Value value1((int32_t)10025);
-// Value value2("tag");
-// Value value3((int32_t)987654);
-// Value value4((int32_t)99999);
-//
-// dim.addValue(FieldValue(field1, value1));
-// dim.addValue(FieldValue(field2, value2));
-// dim.addValue(FieldValue(field3, value3));
-// dim.addValue(FieldValue(field4, value4));
-//
-// SubscriberReporter::getStatsDimensionsValue(dim);
-// // TODO(b/110562792): can't test anything here because StatsDimensionsValue class doesn't
-// // have any read api.
-//}
+void checkAttributionNodeInDimensionsValueParcel(StatsDimensionsValueParcel& attributionNodeParcel,
+ int32_t nodeDepthInAttributionChain,
+ int32_t uid, string tag) {
+ EXPECT_EQ(attributionNodeParcel.field, nodeDepthInAttributionChain /*position at depth 1*/);
+ ASSERT_EQ(attributionNodeParcel.valueType, STATS_DIMENSIONS_VALUE_TUPLE_TYPE);
+ ASSERT_EQ(attributionNodeParcel.tupleValue.size(), 2);
+
+ StatsDimensionsValueParcel uidParcel = attributionNodeParcel.tupleValue[0];
+ EXPECT_EQ(uidParcel.field, 1 /*position at depth 2*/);
+ EXPECT_EQ(uidParcel.valueType, STATS_DIMENSIONS_VALUE_INT_TYPE);
+ EXPECT_EQ(uidParcel.intValue, uid);
+
+ StatsDimensionsValueParcel tagParcel = attributionNodeParcel.tupleValue[1];
+ EXPECT_EQ(tagParcel.field, 2 /*position at depth 2*/);
+ EXPECT_EQ(tagParcel.valueType, STATS_DIMENSIONS_VALUE_STRING_TYPE);
+ EXPECT_EQ(tagParcel.stringValue, tag);
+}
+
+// Test conversion of a HashableDimensionKey into a StatsDimensionValueParcel
+TEST(AtomMatcherTest, TestSubscriberDimensionWrite) {
+ int atomId = 10;
+ // First four fields form an attribution chain
+ int pos1[] = {1, 1, 1};
+ int pos2[] = {1, 1, 2};
+ int pos3[] = {1, 2, 1};
+ int pos4[] = {1, 2, 2};
+ int pos5[] = {2, 1, 1};
+
+ Field field1(atomId, pos1, /*depth=*/2);
+ Field field2(atomId, pos2, /*depth=*/2);
+ Field field3(atomId, pos3, /*depth=*/2);
+ Field field4(atomId, pos4, /*depth=*/2);
+ Field field5(atomId, pos5, /*depth=*/0);
+
+ Value value1((int32_t)1);
+ Value value2("string2");
+ Value value3((int32_t)3);
+ Value value4("string4");
+ Value value5((float)5.0);
+
+ HashableDimensionKey dimensionKey;
+ dimensionKey.addValue(FieldValue(field1, value1));
+ dimensionKey.addValue(FieldValue(field2, value2));
+ dimensionKey.addValue(FieldValue(field3, value3));
+ dimensionKey.addValue(FieldValue(field4, value4));
+ dimensionKey.addValue(FieldValue(field5, value5));
+
+ StatsDimensionsValueParcel rootParcel = dimensionKey.toStatsDimensionsValueParcel();
+ EXPECT_EQ(rootParcel.field, atomId);
+ ASSERT_EQ(rootParcel.valueType, STATS_DIMENSIONS_VALUE_TUPLE_TYPE);
+ ASSERT_EQ(rootParcel.tupleValue.size(), 2);
+
+ // Check that attribution chain is populated correctly
+ StatsDimensionsValueParcel attributionChainParcel = rootParcel.tupleValue[0];
+ EXPECT_EQ(attributionChainParcel.field, 1 /*position at depth 0*/);
+ ASSERT_EQ(attributionChainParcel.valueType, STATS_DIMENSIONS_VALUE_TUPLE_TYPE);
+ ASSERT_EQ(attributionChainParcel.tupleValue.size(), 2);
+ checkAttributionNodeInDimensionsValueParcel(attributionChainParcel.tupleValue[0],
+ /*nodeDepthInAttributionChain=*/1,
+ value1.int_value, value2.str_value);
+ checkAttributionNodeInDimensionsValueParcel(attributionChainParcel.tupleValue[1],
+ /*nodeDepthInAttributionChain=*/2,
+ value3.int_value, value4.str_value);
+
+ // Check that the float is populated correctly
+ StatsDimensionsValueParcel floatParcel = rootParcel.tupleValue[1];
+ EXPECT_EQ(floatParcel.field, 2 /*position at depth 0*/);
+ EXPECT_EQ(floatParcel.valueType, STATS_DIMENSIONS_VALUE_FLOAT_TYPE);
+ EXPECT_EQ(floatParcel.floatValue, value5.float_value);
+}
TEST(AtomMatcherTest, TestWriteDimensionToProto) {
HashableDimensionKey dim;
diff --git a/cmds/statsd/tests/StatsLogProcessor_test.cpp b/cmds/statsd/tests/StatsLogProcessor_test.cpp
index 13d977fa2563..1e6680c47567 100644
--- a/cmds/statsd/tests/StatsLogProcessor_test.cpp
+++ b/cmds/statsd/tests/StatsLogProcessor_test.cpp
@@ -13,6 +13,11 @@
// limitations under the License.
#include "StatsLogProcessor.h"
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <stdio.h>
+
#include "StatsService.h"
#include "config/ConfigKey.h"
#include "frameworks/base/cmds/statsd/src/stats_log.pb.h"
@@ -20,16 +25,10 @@
#include "guardrail/StatsdStats.h"
#include "logd/LogEvent.h"
#include "packages/UidMap.h"
-#include "storage/StorageManager.h"
#include "statslog_statsdtest.h"
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-
+#include "storage/StorageManager.h"
#include "tests/statsd_test_util.h"
-#include <stdio.h>
-
using namespace android;
using namespace testing;
using ::ndk::SharedRefBase;
@@ -1836,6 +1835,11 @@ TEST(StatsLogProcessorTest, TestDumpReportWithoutErasingDataDoesNotUpdateTimesta
int isolatedUid = 30;
sp<MockUidMap> mockUidMap = makeMockUidMapForOneHost(hostUid, {isolatedUid});
ConfigKey key(3, 4);
+
+ // TODO: All tests should not persist state on disk. This removes any reports that were present.
+ ProtoOutputStream proto;
+ StorageManager::appendConfigMetricsReport(key, &proto, /*erase data=*/true, /*isAdb=*/false);
+
StatsdConfig config = MakeConfig(false);
sp<StatsLogProcessor> processor =
CreateStatsLogProcessor(1, 1, config, key, nullptr, 0, mockUidMap);
diff --git a/cmds/statsd/tests/guardrail/StatsdStats_test.cpp b/cmds/statsd/tests/guardrail/StatsdStats_test.cpp
index 5cc10cd9840c..428c46f8a0d2 100644
--- a/cmds/statsd/tests/guardrail/StatsdStats_test.cpp
+++ b/cmds/statsd/tests/guardrail/StatsdStats_test.cpp
@@ -306,6 +306,8 @@ TEST(StatsdStatsTest, TestPullAtomStats) {
stats.notePullUidProviderNotFound(util::DISK_SPACE);
stats.notePullerNotFound(util::DISK_SPACE);
stats.notePullerNotFound(util::DISK_SPACE);
+ stats.notePullTimeout(util::DISK_SPACE, 3000L, 6000L);
+ stats.notePullTimeout(util::DISK_SPACE, 4000L, 7000L);
vector<uint8_t> output;
stats.dumpStats(&output, false);
@@ -328,6 +330,13 @@ TEST(StatsdStatsTest, TestPullAtomStats) {
EXPECT_EQ(1L, report.pulled_atom_stats(0).binder_call_failed());
EXPECT_EQ(1L, report.pulled_atom_stats(0).failed_uid_provider_not_found());
EXPECT_EQ(2L, report.pulled_atom_stats(0).puller_not_found());
+ ASSERT_EQ(2, report.pulled_atom_stats(0).pull_atom_metadata_size());
+ EXPECT_EQ(3000L, report.pulled_atom_stats(0).pull_atom_metadata(0).pull_timeout_uptime_millis());
+ EXPECT_EQ(4000L, report.pulled_atom_stats(0).pull_atom_metadata(1).pull_timeout_uptime_millis());
+ EXPECT_EQ(6000L, report.pulled_atom_stats(0).pull_atom_metadata(0)
+ .pull_timeout_elapsed_millis());
+ EXPECT_EQ(7000L, report.pulled_atom_stats(0).pull_atom_metadata(1)
+ .pull_timeout_elapsed_millis());
}
TEST(StatsdStatsTest, TestAtomMetricsStats) {
diff --git a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
index f0419964e892..5666501d7d51 100644
--- a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
@@ -3295,11 +3295,15 @@ TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenConditionEventWron
report.value_metrics().skipped(0).start_bucket_elapsed_millis());
EXPECT_EQ(NanoToMillis(bucket2StartTimeNs + 100),
report.value_metrics().skipped(0).end_bucket_elapsed_millis());
- ASSERT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
+ ASSERT_EQ(2, report.value_metrics().skipped(0).drop_event_size());
auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
EXPECT_EQ(BucketDropReason::EVENT_IN_WRONG_BUCKET, dropEvent.drop_reason());
EXPECT_EQ(NanoToMillis(bucket2StartTimeNs - 100), dropEvent.drop_time_millis());
+
+ dropEvent = report.value_metrics().skipped(0).drop_event(1);
+ EXPECT_EQ(BucketDropReason::CONDITION_UNKNOWN, dropEvent.drop_reason());
+ EXPECT_EQ(NanoToMillis(bucket2StartTimeNs + 100), dropEvent.drop_time_millis());
}
/*
@@ -3615,7 +3619,7 @@ TEST(ValueMetricProducerTest_BucketDrop, TestBucketDropWhenDataUnavailable) {
sp<ValueMetricProducer> valueProducer =
ValueMetricProducerTestHelper::createValueProducerWithCondition(
- pullerManager, metric, ConditionState::kUnknown);
+ pullerManager, metric, ConditionState::kFalse);
// Check dump report.
ProtoOutputStream output;
@@ -3641,6 +3645,94 @@ TEST(ValueMetricProducerTest_BucketDrop, TestBucketDropWhenDataUnavailable) {
}
/*
+ * Test that all buckets are dropped due to condition unknown until the first onConditionChanged.
+ */
+TEST(ValueMetricProducerTest_BucketDrop, TestConditionUnknownMultipleBuckets) {
+ ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
+
+ sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+ EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
+ // Condition change to true.
+ .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
+ vector<std::shared_ptr<LogEvent>>* data, bool) {
+ EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 10 * NS_PER_SEC);
+ data->clear();
+ data->push_back(CreateRepeatedValueLogEvent(
+ tagId, bucket2StartTimeNs + 10 * NS_PER_SEC, 10));
+ return true;
+ }))
+ // Dump report requested.
+ .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
+ vector<std::shared_ptr<LogEvent>>* data, bool) {
+ EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 15 * NS_PER_SEC);
+ data->clear();
+ data->push_back(CreateRepeatedValueLogEvent(
+ tagId, bucket2StartTimeNs + 15 * NS_PER_SEC, 15));
+ return true;
+ }));
+
+ sp<ValueMetricProducer> valueProducer =
+ ValueMetricProducerTestHelper::createValueProducerWithCondition(
+ pullerManager, metric, ConditionState::kUnknown);
+
+ // Bucket should be dropped because of condition unknown.
+ int64_t appUpgradeTimeNs = bucketStartTimeNs + 5 * NS_PER_SEC;
+ valueProducer->notifyAppUpgrade(appUpgradeTimeNs);
+
+ // Bucket also dropped due to condition unknown
+ vector<shared_ptr<LogEvent>> allData;
+ allData.clear();
+ allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 3));
+ valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
+
+ // This bucket is also dropped due to condition unknown.
+ int64_t conditionChangeTimeNs = bucket2StartTimeNs + 10 * NS_PER_SEC;
+ valueProducer->onConditionChanged(true, conditionChangeTimeNs);
+
+ // Check dump report.
+ ProtoOutputStream output;
+ std::set<string> strSet;
+ int64_t dumpReportTimeNs = bucket2StartTimeNs + 15 * NS_PER_SEC; // 15 seconds
+ valueProducer->onDumpReport(dumpReportTimeNs, true /* include current bucket */, true,
+ NO_TIME_CONSTRAINTS /* dumpLatency */, &strSet, &output);
+
+ StatsLogReport report = outputStreamToProto(&output);
+ EXPECT_TRUE(report.has_value_metrics());
+ ASSERT_EQ(0, report.value_metrics().data_size());
+ ASSERT_EQ(3, report.value_metrics().skipped_size());
+
+ EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
+ report.value_metrics().skipped(0).start_bucket_elapsed_millis());
+ EXPECT_EQ(NanoToMillis(appUpgradeTimeNs),
+ report.value_metrics().skipped(0).end_bucket_elapsed_millis());
+ ASSERT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
+
+ auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
+ EXPECT_EQ(BucketDropReason::CONDITION_UNKNOWN, dropEvent.drop_reason());
+ EXPECT_EQ(NanoToMillis(appUpgradeTimeNs), dropEvent.drop_time_millis());
+
+ EXPECT_EQ(NanoToMillis(appUpgradeTimeNs),
+ report.value_metrics().skipped(1).start_bucket_elapsed_millis());
+ EXPECT_EQ(NanoToMillis(bucket2StartTimeNs),
+ report.value_metrics().skipped(1).end_bucket_elapsed_millis());
+ ASSERT_EQ(1, report.value_metrics().skipped(1).drop_event_size());
+
+ dropEvent = report.value_metrics().skipped(1).drop_event(0);
+ EXPECT_EQ(BucketDropReason::CONDITION_UNKNOWN, dropEvent.drop_reason());
+ EXPECT_EQ(NanoToMillis(bucket2StartTimeNs), dropEvent.drop_time_millis());
+
+ EXPECT_EQ(NanoToMillis(bucket2StartTimeNs),
+ report.value_metrics().skipped(2).start_bucket_elapsed_millis());
+ EXPECT_EQ(NanoToMillis(dumpReportTimeNs),
+ report.value_metrics().skipped(2).end_bucket_elapsed_millis());
+ ASSERT_EQ(1, report.value_metrics().skipped(2).drop_event_size());
+
+ dropEvent = report.value_metrics().skipped(2).drop_event(0);
+ EXPECT_EQ(BucketDropReason::CONDITION_UNKNOWN, dropEvent.drop_reason());
+ EXPECT_EQ(NanoToMillis(conditionChangeTimeNs), dropEvent.drop_time_millis());
+}
+
+/*
* Test that a skipped bucket is logged when a forced bucket split occurs when the previous bucket
* was not flushed in time.
*/
@@ -4957,7 +5049,7 @@ TEST(ValueMetricProducerTest, TestForcedBucketSplitWhenConditionUnknownSkipsBuck
ASSERT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
- EXPECT_EQ(BucketDropReason::NO_DATA, dropEvent.drop_reason());
+ EXPECT_EQ(BucketDropReason::CONDITION_UNKNOWN, dropEvent.drop_reason());
EXPECT_EQ(NanoToMillis(appUpdateTimeNs), dropEvent.drop_time_millis());
}
diff --git a/config/preloaded-classes-blacklist b/config/preloaded-classes-blacklist
index 353f786da153..48d579cc118e 100644
--- a/config/preloaded-classes-blacklist
+++ b/config/preloaded-classes-blacklist
@@ -1,6 +1,8 @@
android.content.AsyncTaskLoader$LoadTask
android.net.ConnectivityThread$Singleton
+android.os.AsyncTask
android.os.FileObserver
+android.os.NullVibrator
android.speech.tts.TextToSpeech$Connection$SetupConnectionAsyncTask
android.widget.Magnifier
-sun.nio.fs.UnixChannelFactory
+com.android.server.BootReceiver$2
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 22a63d9b486b..3772755beca1 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -2816,6 +2816,11 @@ public class Activity extends ContextThemeWrapper
* The system may disallow entering picture-in-picture in various cases, including when the
* activity is not visible, if the screen is locked or if the user has an activity pinned.
*
+ * <p>By default, system calculates the dimension of picture-in-picture window based on the
+ * given {@param params}.
+ * See <a href="{@docRoot}guide/topics/ui/picture-in-picture">Picture-in-picture Support</a>
+ * on how to override this behavior.</p>
+ *
* @see android.R.attr#supportsPictureInPicture
* @see PictureInPictureParams
*
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index b608a343fc7d..acf6315ddc5d 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -159,10 +159,10 @@ public class ActivityManager {
*/
public static final int INSTR_FLAG_DISABLE_HIDDEN_API_CHECKS = 1 << 0;
/**
- * Mount full external storage for the newly started instrumentation.
+ * Grant full access to the external storage for the newly started instrumentation.
* @hide
*/
- public static final int INSTR_FLAG_MOUNT_EXTERNAL_STORAGE_FULL = 1 << 1;
+ public static final int INSTR_FLAG_DISABLE_ISOLATED_STORAGE = 1 << 1;
/**
* Disable test API access for the newly started instrumentation.
diff --git a/core/java/android/app/ActivityTaskManager.java b/core/java/android/app/ActivityTaskManager.java
index 1cc63da3db0a..0f31529451fb 100644
--- a/core/java/android/app/ActivityTaskManager.java
+++ b/core/java/android/app/ActivityTaskManager.java
@@ -433,13 +433,21 @@ public class ActivityTaskManager {
}
}
- /** Returns whether the current UI mode supports error dialogs (ANR, crash, etc). */
- public static boolean currentUiModeSupportsErrorDialogs(@NonNull Context context) {
- final Configuration config = context.getResources().getConfiguration();
+ /**
+ * @return whether the UI mode of the given config supports error dialogs (ANR, crash, etc).
+ * @hide
+ */
+ public static boolean currentUiModeSupportsErrorDialogs(@NonNull Configuration config) {
int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
return (modeType != Configuration.UI_MODE_TYPE_CAR
&& !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
&& modeType != Configuration.UI_MODE_TYPE_TELEVISION
&& modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
}
+
+ /** @return whether the current UI mode supports error dialogs (ANR, crash, etc). */
+ public static boolean currentUiModeSupportsErrorDialogs(@NonNull Context context) {
+ final Configuration config = context.getResources().getConfiguration();
+ return currentUiModeSupportsErrorDialogs(config);
+ }
}
diff --git a/core/java/android/app/ActivityView.java b/core/java/android/app/ActivityView.java
index d650bbcdfa33..98a23f2b0075 100644
--- a/core/java/android/app/ActivityView.java
+++ b/core/java/android/app/ActivityView.java
@@ -33,7 +33,10 @@ import android.hardware.display.VirtualDisplay;
import android.os.Bundle;
import android.os.UserHandle;
import android.util.AttributeSet;
+import android.util.DisplayMetrics;
import android.util.Log;
+import android.view.Display;
+import android.view.DisplayInfo;
import android.view.IWindow;
import android.view.IWindowManager;
import android.view.KeyEvent;
@@ -360,18 +363,9 @@ public class ActivityView extends ViewGroup implements android.window.TaskEmbedd
}
/**
- * Release this container. Activity launching will no longer be permitted.
- * <p>Note: Calling this method is allowed after
- * {@link StateCallback#onActivityViewReady(ActivityView)} callback was triggered and before
- * {@link StateCallback#onActivityViewDestroyed(ActivityView)}.
- *
- * @see StateCallback
+ * Release this container if it is initialized. Activity launching will no longer be permitted.
*/
public void release() {
- if (!mTaskEmbedder.isInitialized()) {
- throw new IllegalStateException(
- "Trying to release container that is not initialized.");
- }
performRelease();
}
@@ -416,6 +410,9 @@ public class ActivityView extends ViewGroup implements android.window.TaskEmbedd
}
private class SurfaceCallback implements SurfaceHolder.Callback {
+ private final DisplayInfo mTempDisplayInfo = new DisplayInfo();
+ private final DisplayMetrics mTempMetrics = new DisplayMetrics();
+
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
if (!mTaskEmbedder.isInitialized()) {
@@ -424,13 +421,21 @@ public class ActivityView extends ViewGroup implements android.window.TaskEmbedd
mTmpTransaction.reparent(mTaskEmbedder.getSurfaceControl(),
mSurfaceView.getSurfaceControl()).apply();
}
+ mTaskEmbedder.resizeTask(getWidth(), getHeight());
mTaskEmbedder.start();
}
@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int width, int height) {
- mTaskEmbedder.resizeTask(width, height);
- mTaskEmbedder.notifyBoundsChanged();
+ final Display display = getVirtualDisplay().getDisplay();
+ if (!display.getDisplayInfo(mTempDisplayInfo)) {
+ return;
+ }
+ mTempDisplayInfo.getAppMetrics(mTempMetrics);
+ if (width != mTempMetrics.widthPixels || height != mTempMetrics.heightPixels) {
+ mTaskEmbedder.resizeTask(width, height);
+ mTaskEmbedder.notifyBoundsChanged();
+ }
}
@Override
@@ -487,7 +492,9 @@ public class ActivityView extends ViewGroup implements android.window.TaskEmbedd
return;
}
mSurfaceView.getHolder().removeCallback(mSurfaceCallback);
- mTaskEmbedder.release();
+ if (mTaskEmbedder.isInitialized()) {
+ mTaskEmbedder.release();
+ }
mTaskEmbedder.setListener(null);
mGuard.close();
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index ddc57474a027..0a6827cde3d3 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -227,7 +227,7 @@ public class AppOpsManager {
* {@link #sMessageCollector}, which forces {@link COLLECT_SYNC} mode.
*/
@GuardedBy("sLock")
- private static ArrayList<SyncNotedAppOp> sUnforwardedOps = new ArrayList<>();
+ private static ArrayList<AsyncNotedAppOp> sUnforwardedOps = new ArrayList<>();
/**
* Additional collector that collect accesses and forwards a few of them them via
@@ -261,8 +261,9 @@ public class AppOpsManager {
< SystemClock.elapsedRealtime()) {
String stackTrace = getFormattedStackTrace();
try {
+ String packageName = ActivityThread.currentOpPackageName();
sConfig = getService().reportRuntimeAppOpAccessMessageAndGetConfig(
- ActivityThread.currentOpPackageName(), op, stackTrace);
+ packageName == null ? "" : packageName, op, stackTrace);
} catch (RemoteException e) {
e.rethrowFromSystemServer();
}
@@ -1121,8 +1122,11 @@ public class AppOpsManager {
AppProtoEnums.APP_OP_AUTO_REVOKE_MANAGED_BY_INSTALLER;
/** @hide */
+ public static final int OP_NO_ISOLATED_STORAGE = AppProtoEnums.APP_OP_NO_ISOLATED_STORAGE;
+
+ /** @hide */
@UnsupportedAppUsage
- public static final int _NUM_OP = 99;
+ public static final int _NUM_OP = 100;
/** Access to coarse location information. */
public static final String OPSTR_COARSE_LOCATION = "android:coarse_location";
@@ -1433,6 +1437,12 @@ public class AppOpsManager {
@SystemApi
public static final String OPSTR_LOADER_USAGE_STATS = "android:loader_usage_stats";
+ /**
+ * AppOp granted to apps that we are started via {@code am instrument -e --no-isolated-storage}
+ *
+ * @hide
+ */
+ public static final String OPSTR_NO_ISOLATED_STORAGE = "android:no_isolated_storage";
/** {@link #sAppOpsToNote} not initialized yet for this op */
private static final byte SHOULD_COLLECT_NOTE_OP_NOT_INITIALIZED = 0;
@@ -1622,6 +1632,7 @@ public class AppOpsManager {
OP_DEPRECATED_1, // deprecated
OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED, //AUTO_REVOKE_PERMISSIONS_IF_UNUSED
OP_AUTO_REVOKE_MANAGED_BY_INSTALLER, //OP_AUTO_REVOKE_MANAGED_BY_INSTALLER
+ OP_NO_ISOLATED_STORAGE, // NO_ISOLATED_STORAGE
};
/**
@@ -1727,6 +1738,7 @@ public class AppOpsManager {
"", // deprecated
OPSTR_AUTO_REVOKE_PERMISSIONS_IF_UNUSED,
OPSTR_AUTO_REVOKE_MANAGED_BY_INSTALLER,
+ OPSTR_NO_ISOLATED_STORAGE,
};
/**
@@ -1833,6 +1845,7 @@ public class AppOpsManager {
"deprecated",
"AUTO_REVOKE_PERMISSIONS_IF_UNUSED",
"AUTO_REVOKE_MANAGED_BY_INSTALLER",
+ "NO_ISOLATED_STORAGE",
};
/**
@@ -1940,6 +1953,7 @@ public class AppOpsManager {
null, // deprecated operation
null, // no permission for OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED
null, // no permission for OP_AUTO_REVOKE_MANAGED_BY_INSTALLER
+ null, // no permission for OP_NO_ISOLATED_STORAGE
};
/**
@@ -2047,6 +2061,7 @@ public class AppOpsManager {
null, // deprecated operation
null, // AUTO_REVOKE_PERMISSIONS_IF_UNUSED
null, // AUTO_REVOKE_MANAGED_BY_INSTALLER
+ null, // NO_ISOLATED_STORAGE
};
/**
@@ -2153,6 +2168,7 @@ public class AppOpsManager {
null, // deprecated operation
null, // AUTO_REVOKE_PERMISSIONS_IF_UNUSED
null, // AUTO_REVOKE_MANAGED_BY_INSTALLER
+ null, // NO_ISOLATED_STORAGE
};
/**
@@ -2258,6 +2274,7 @@ public class AppOpsManager {
AppOpsManager.MODE_IGNORED, // deprecated operation
AppOpsManager.MODE_DEFAULT, // OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED
AppOpsManager.MODE_ALLOWED, // OP_AUTO_REVOKE_MANAGED_BY_INSTALLER
+ AppOpsManager.MODE_ERRORED, // OP_NO_ISOLATED_STORAGE
};
/**
@@ -2367,6 +2384,7 @@ public class AppOpsManager {
false, // deprecated operation
false, // AUTO_REVOKE_PERMISSIONS_IF_UNUSED
false, // AUTO_REVOKE_MANAGED_BY_INSTALLER
+ true, // NO_ISOLATED_STORAGE
};
/**
@@ -7352,15 +7370,17 @@ public class AppOpsManager {
try {
collectNoteOpCallsForValidation(op);
int collectionMode = getNotedOpCollectionMode(uid, packageName, op);
+ boolean shouldCollectMessage = Process.myUid() == Process.SYSTEM_UID ? true : false;
if (collectionMode == COLLECT_ASYNC) {
if (message == null) {
// Set stack trace as default message
message = getFormattedStackTrace();
+ shouldCollectMessage = true;
}
}
int mode = mService.noteOperation(op, uid, packageName, attributionTag,
- collectionMode == COLLECT_ASYNC, message);
+ collectionMode == COLLECT_ASYNC, message, shouldCollectMessage);
if (mode == MODE_ALLOWED) {
if (collectionMode == COLLECT_SELF) {
@@ -7513,16 +7533,19 @@ public class AppOpsManager {
try {
collectNoteOpCallsForValidation(op);
int collectionMode = getNotedOpCollectionMode(proxiedUid, proxiedPackageName, op);
+ boolean shouldCollectMessage = myUid == Process.SYSTEM_UID ? true : false;
if (collectionMode == COLLECT_ASYNC) {
if (message == null) {
// Set stack trace as default message
message = getFormattedStackTrace();
+ shouldCollectMessage = true;
}
}
int mode = mService.noteProxyOperation(op, proxiedUid, proxiedPackageName,
proxiedAttributionTag, myUid, mContext.getOpPackageName(),
- mContext.getAttributionTag(), collectionMode == COLLECT_ASYNC, message);
+ mContext.getAttributionTag(), collectionMode == COLLECT_ASYNC, message,
+ shouldCollectMessage);
if (mode == MODE_ALLOWED) {
if (collectionMode == COLLECT_SELF) {
@@ -7837,15 +7860,18 @@ public class AppOpsManager {
try {
collectNoteOpCallsForValidation(op);
int collectionMode = getNotedOpCollectionMode(uid, packageName, op);
+ boolean shouldCollectMessage = Process.myUid() == Process.SYSTEM_UID ? true : false;
if (collectionMode == COLLECT_ASYNC) {
if (message == null) {
// Set stack trace as default message
message = getFormattedStackTrace();
+ shouldCollectMessage = true;
}
}
int mode = mService.startOperation(getClientId(), op, uid, packageName,
- attributionTag, startIfModeDefault, collectionMode == COLLECT_ASYNC, message);
+ attributionTag, startIfModeDefault, collectionMode == COLLECT_ASYNC, message,
+ shouldCollectMessage);
if (mode == MODE_ALLOWED) {
if (collectionMode == COLLECT_SELF) {
@@ -8177,7 +8203,10 @@ public class AppOpsManager {
if (sOnOpNotedCallback != null) {
sOnOpNotedCallback.onNoted(new SyncNotedAppOp(code, attributionTag));
} else {
- sUnforwardedOps.add(new SyncNotedAppOp(code, attributionTag));
+ String message = getFormattedStackTrace();
+ sUnforwardedOps.add(
+ new AsyncNotedAppOp(code, Process.myUid(), attributionTag,
+ message, System.currentTimeMillis()));
if (sUnforwardedOps.size() > MAX_UNFORWARDED_OPS) {
sUnforwardedOps.remove(0);
}
@@ -8250,10 +8279,10 @@ public class AppOpsManager {
synchronized (this) {
int numMissedSyncOps = sUnforwardedOps.size();
for (int i = 0; i < numMissedSyncOps; i++) {
- final SyncNotedAppOp syncNotedAppOp = sUnforwardedOps.get(i);
+ final AsyncNotedAppOp syncNotedAppOp = sUnforwardedOps.get(i);
if (sOnOpNotedCallback != null) {
sOnOpNotedCallback.getAsyncNotedExecutor().execute(
- () -> sOnOpNotedCallback.onNoted(syncNotedAppOp));
+ () -> sOnOpNotedCallback.onAsyncNoted(syncNotedAppOp));
}
}
sUnforwardedOps.clear();
diff --git a/core/java/android/app/AppOpsManagerInternal.java b/core/java/android/app/AppOpsManagerInternal.java
index 309e91f1e4ff..5e032f00a3a0 100644
--- a/core/java/android/app/AppOpsManagerInternal.java
+++ b/core/java/android/app/AppOpsManagerInternal.java
@@ -22,7 +22,7 @@ import android.util.SparseArray;
import android.util.SparseIntArray;
import com.android.internal.app.IAppOpsCallback;
-import com.android.internal.util.function.HexFunction;
+import com.android.internal.util.function.HeptFunction;
import com.android.internal.util.function.QuadFunction;
/**
@@ -73,9 +73,9 @@ public abstract class AppOpsManagerInternal {
*/
int noteOperation(int code, int uid, @Nullable String packageName,
@Nullable String featureId, boolean shouldCollectAsyncNotedOp,
- @Nullable String message,
- @NonNull HexFunction<Integer, Integer, String, String, Boolean, String, Integer>
- superImpl);
+ @Nullable String message, boolean shouldCollectMessage,
+ @NonNull HeptFunction<Integer, Integer, String, String, Boolean, String, Boolean,
+ Integer> superImpl);
}
/**
diff --git a/core/java/android/app/DownloadManager.java b/core/java/android/app/DownloadManager.java
index 1278ff6817fd..0719422632d1 100644
--- a/core/java/android/app/DownloadManager.java
+++ b/core/java/android/app/DownloadManager.java
@@ -25,6 +25,7 @@ import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage;
+import android.content.ClipDescription;
import android.content.ContentProviderClient;
import android.content.ContentResolver;
import android.content.ContentUris;
@@ -50,11 +51,13 @@ import android.provider.Settings.SettingNotFoundException;
import android.text.TextUtils;
import android.util.LongSparseArray;
import android.util.Pair;
+import android.webkit.MimeTypeMap;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
+import java.util.Locale;
/**
* The download manager is a system service that handles long-running HTTP downloads. Clients may
@@ -1554,6 +1557,7 @@ public class DownloadManager {
values.put(Downloads.Impl.COLUMN_DESTINATION,
Downloads.Impl.DESTINATION_NON_DOWNLOADMANAGER_DOWNLOAD);
values.put(Downloads.Impl._DATA, path);
+ values.put(Downloads.Impl.COLUMN_MIME_TYPE, resolveMimeType(new File(path)));
values.put(Downloads.Impl.COLUMN_STATUS, Downloads.Impl.STATUS_SUCCESS);
values.put(Downloads.Impl.COLUMN_TOTAL_BYTES, length);
values.put(Downloads.Impl.COLUMN_MEDIA_SCANNED,
@@ -1569,6 +1573,58 @@ public class DownloadManager {
return Long.parseLong(downloadUri.getLastPathSegment());
}
+ /**
+ * Shamelessly borrowed from
+ * {@code packages/providers/MediaProvider/src/com/android/providers/media/util/MimeUtils.java}
+ *
+ * @hide
+ */
+ private static @NonNull String resolveMimeType(@NonNull File file) {
+ final String extension = extractFileExtension(file.getPath());
+ if (extension == null) return ClipDescription.MIMETYPE_UNKNOWN;
+
+ final String mimeType = MimeTypeMap.getSingleton()
+ .getMimeTypeFromExtension(extension.toLowerCase(Locale.ROOT));
+ if (mimeType == null) return ClipDescription.MIMETYPE_UNKNOWN;
+
+ return mimeType;
+ }
+
+ /**
+ * Shamelessly borrowed from
+ * {@code packages/providers/MediaProvider/src/com/android/providers/media/util/FileUtils.java}
+ *
+ * @hide
+ */
+ private static @Nullable String extractDisplayName(@Nullable String data) {
+ if (data == null) return null;
+ if (data.indexOf('/') == -1) {
+ return data;
+ }
+ if (data.endsWith("/")) {
+ data = data.substring(0, data.length() - 1);
+ }
+ return data.substring(data.lastIndexOf('/') + 1);
+ }
+
+ /**
+ * Shamelessly borrowed from
+ * {@code packages/providers/MediaProvider/src/com/android/providers/media/util/FileUtils.java}
+ *
+ * @hide
+ */
+ private static @Nullable String extractFileExtension(@Nullable String data) {
+ if (data == null) return null;
+ data = extractDisplayName(data);
+
+ final int lastDot = data.lastIndexOf('.');
+ if (lastDot == -1) {
+ return null;
+ } else {
+ return data.substring(lastDot + 1);
+ }
+ }
+
private static final String NON_DOWNLOADMANAGER_DOWNLOAD =
"non-dwnldmngr-download-dont-retry2download";
diff --git a/core/java/android/app/ExitTransitionCoordinator.java b/core/java/android/app/ExitTransitionCoordinator.java
index fd3eb0618429..68824cd26eaa 100644
--- a/core/java/android/app/ExitTransitionCoordinator.java
+++ b/core/java/android/app/ExitTransitionCoordinator.java
@@ -434,8 +434,7 @@ class ExitTransitionCoordinator extends ActivityTransitionCoordinator {
mSharedElementNotified = true;
delayCancel();
- if (!mActivity.isTopOfTask() || (mIsReturning && !mActivity.isTaskRoot()
- && !mSharedElements.isEmpty())) {
+ if (!mActivity.isTopOfTask()) {
mResultReceiver.send(MSG_ALLOW_RETURN_TRANSITION, null);
}
diff --git a/core/java/android/app/TaskInfo.java b/core/java/android/app/TaskInfo.java
index c7a2a1e11c9e..f3f00e50715b 100644
--- a/core/java/android/app/TaskInfo.java
+++ b/core/java/android/app/TaskInfo.java
@@ -16,8 +16,6 @@
package android.app;
-import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
-
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.TestApi;
@@ -170,6 +168,14 @@ public class TaskInfo {
@Nullable
public ActivityInfo topActivityInfo;
+ /**
+ * Whether this task is resizable. Unlike {@link #resizeMode} (which is what the top activity
+ * supports), this is what the system actually uses for resizability based on other policy and
+ * developer options.
+ * @hide
+ */
+ public boolean isResizeable;
+
TaskInfo() {
// Do nothing
}
@@ -193,11 +199,6 @@ public class TaskInfo {
}
/** @hide */
- public boolean isResizable() {
- return resizeMode != RESIZE_MODE_UNRESIZEABLE;
- }
-
- /** @hide */
@NonNull
@TestApi
public WindowContainerToken getToken() {
@@ -245,6 +246,7 @@ public class TaskInfo {
topActivityInfo = source.readInt() != 0
? ActivityInfo.CREATOR.createFromParcel(source)
: null;
+ isResizeable = source.readBoolean();
}
/**
@@ -294,6 +296,7 @@ public class TaskInfo {
dest.writeInt(1);
topActivityInfo.writeToParcel(dest, flags);
}
+ dest.writeBoolean(isResizeable);
}
@Override
@@ -308,6 +311,7 @@ public class TaskInfo {
+ " lastActiveTime=" + lastActiveTime
+ " supportsSplitScreenMultiWindow=" + supportsSplitScreenMultiWindow
+ " resizeMode=" + resizeMode
+ + " isResizeable=" + isResizeable
+ " token=" + token
+ " topActivityType=" + topActivityType
+ " pictureInPictureParams=" + pictureInPictureParams
diff --git a/core/java/android/app/admin/DevicePolicyCache.java b/core/java/android/app/admin/DevicePolicyCache.java
index 4d9970c2c144..15ff531b445d 100644
--- a/core/java/android/app/admin/DevicePolicyCache.java
+++ b/core/java/android/app/admin/DevicePolicyCache.java
@@ -41,7 +41,8 @@ public abstract class DevicePolicyCache {
/**
* See {@link DevicePolicyManager#getScreenCaptureDisabled}
*/
- public abstract boolean getScreenCaptureDisabled(@UserIdInt int userHandle);
+ public abstract boolean isScreenCaptureAllowed(@UserIdInt int userHandle,
+ boolean ownerCanAddInternalSystemWindow);
/**
* Caches {@link DevicePolicyManager#getPasswordQuality(android.content.ComponentName)} of the
@@ -56,8 +57,9 @@ public abstract class DevicePolicyCache {
private static final EmptyDevicePolicyCache INSTANCE = new EmptyDevicePolicyCache();
@Override
- public boolean getScreenCaptureDisabled(int userHandle) {
- return false;
+ public boolean isScreenCaptureAllowed(int userHandle,
+ boolean ownerCanAddInternalSystemWindow) {
+ return true;
}
@Override
diff --git a/core/java/android/app/usage/NetworkStatsManager.java b/core/java/android/app/usage/NetworkStatsManager.java
index d6e77624a967..fc8248e1012a 100644
--- a/core/java/android/app/usage/NetworkStatsManager.java
+++ b/core/java/android/app/usage/NetworkStatsManager.java
@@ -41,6 +41,7 @@ import android.os.Messenger;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.ServiceManager.ServiceNotFoundException;
+import android.telephony.TelephonyManager;
import android.util.DataUnit;
import android.util.Log;
@@ -198,6 +199,12 @@ public class NetworkStatsManager {
* {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI}
* etc.
* @param subscriberId If applicable, the subscriber id of the network interface.
+ * <p>Starting with API level 29, the {@code subscriberId} is guarded by
+ * additional restrictions. Calling apps that do not meet the new
+ * requirements to access the {@code subscriberId} can provide a {@code
+ * null} value when querying for the mobile network type to receive usage
+ * for all mobile networks. For additional details see {@link
+ * TelephonyManager#getSubscriberId()}.
* @param startTime Start of period. Defined in terms of "Unix time", see
* {@link java.lang.System#currentTimeMillis}.
* @param endTime End of period. Defined in terms of "Unix time", see
@@ -231,6 +238,12 @@ public class NetworkStatsManager {
* {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI}
* etc.
* @param subscriberId If applicable, the subscriber id of the network interface.
+ * <p>Starting with API level 29, the {@code subscriberId} is guarded by
+ * additional restrictions. Calling apps that do not meet the new
+ * requirements to access the {@code subscriberId} can provide a {@code
+ * null} value when querying for the mobile network type to receive usage
+ * for all mobile networks. For additional details see {@link
+ * TelephonyManager#getSubscriberId()}.
* @param startTime Start of period. Defined in terms of "Unix time", see
* {@link java.lang.System#currentTimeMillis}.
* @param endTime End of period. Defined in terms of "Unix time", see
@@ -268,6 +281,12 @@ public class NetworkStatsManager {
* {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI}
* etc.
* @param subscriberId If applicable, the subscriber id of the network interface.
+ * <p>Starting with API level 29, the {@code subscriberId} is guarded by
+ * additional restrictions. Calling apps that do not meet the new
+ * requirements to access the {@code subscriberId} can provide a {@code
+ * null} value when querying for the mobile network type to receive usage
+ * for all mobile networks. For additional details see {@link
+ * TelephonyManager#getSubscriberId()}.
* @param startTime Start of period. Defined in terms of "Unix time", see
* {@link java.lang.System#currentTimeMillis}.
* @param endTime End of period. Defined in terms of "Unix time", see
@@ -301,7 +320,7 @@ public class NetworkStatsManager {
/**
* Query network usage statistics details for a given uid.
*
- * #see queryDetailsForUidTagState(int, String, long, long, int, int, int)
+ * @see #queryDetailsForUidTagState(int, String, long, long, int, int, int)
*/
public NetworkStats queryDetailsForUid(int networkType, String subscriberId,
long startTime, long endTime, int uid) throws SecurityException {
@@ -319,7 +338,7 @@ public class NetworkStatsManager {
/**
* Query network usage statistics details for a given uid and tag.
*
- * #see queryDetailsForUidTagState(int, String, long, long, int, int, int)
+ * @see #queryDetailsForUidTagState(int, String, long, long, int, int, int)
*/
public NetworkStats queryDetailsForUidTag(int networkType, String subscriberId,
long startTime, long endTime, int uid, int tag) throws SecurityException {
@@ -344,6 +363,12 @@ public class NetworkStatsManager {
* {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI}
* etc.
* @param subscriberId If applicable, the subscriber id of the network interface.
+ * <p>Starting with API level 29, the {@code subscriberId} is guarded by
+ * additional restrictions. Calling apps that do not meet the new
+ * requirements to access the {@code subscriberId} can provide a {@code
+ * null} value when querying for the mobile network type to receive usage
+ * for all mobile networks. For additional details see {@link
+ * TelephonyManager#getSubscriberId()}.
* @param startTime Start of period. Defined in terms of "Unix time", see
* {@link java.lang.System#currentTimeMillis}.
* @param endTime End of period. Defined in terms of "Unix time", see
@@ -398,6 +423,12 @@ public class NetworkStatsManager {
* {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI}
* etc.
* @param subscriberId If applicable, the subscriber id of the network interface.
+ * <p>Starting with API level 29, the {@code subscriberId} is guarded by
+ * additional restrictions. Calling apps that do not meet the new
+ * requirements to access the {@code subscriberId} can provide a {@code
+ * null} value when querying for the mobile network type to receive usage
+ * for all mobile networks. For additional details see {@link
+ * TelephonyManager#getSubscriberId()}.
* @param startTime Start of period. Defined in terms of "Unix time", see
* {@link java.lang.System#currentTimeMillis}.
* @param endTime End of period. Defined in terms of "Unix time", see
@@ -455,7 +486,7 @@ public class NetworkStatsManager {
/**
* Registers to receive notifications about data usage on specified networks.
*
- * #see registerUsageCallback(int, String[], long, UsageCallback, Handler)
+ * @see #registerUsageCallback(int, String, long, UsageCallback, Handler)
*/
public void registerUsageCallback(int networkType, String subscriberId, long thresholdBytes,
UsageCallback callback) {
@@ -472,6 +503,12 @@ public class NetworkStatsManager {
* @param networkType Type of network to monitor. Either
{@link ConnectivityManager#TYPE_MOBILE} or {@link ConnectivityManager#TYPE_WIFI}.
* @param subscriberId If applicable, the subscriber id of the network interface.
+ * <p>Starting with API level 29, the {@code subscriberId} is guarded by
+ * additional restrictions. Calling apps that do not meet the new
+ * requirements to access the {@code subscriberId} can provide a {@code
+ * null} value when registering for the mobile network type to receive
+ * notifications for all mobile networks. For additional details see {@link
+ * TelephonyManager#getSubscriberId()}.
* @param thresholdBytes Threshold in bytes to be notified on.
* @param callback The {@link UsageCallback} that the system will call when data usage
* has exceeded the specified threshold.
diff --git a/core/java/android/app/usage/UsageStatsManager.java b/core/java/android/app/usage/UsageStatsManager.java
index 2ce6a86753a6..8a6cc95319fb 100644
--- a/core/java/android/app/usage/UsageStatsManager.java
+++ b/core/java/android/app/usage/UsageStatsManager.java
@@ -154,6 +154,7 @@ public final class UsageStatsManager {
* been misbehaving in some manner.
* Apps in this bucket will have the most restrictions, including network restrictions and
* additional restrictions on jobs.
+ * <p> Note: this bucket is not enabled in {@link Build.VERSION_CODES#R}.
* @see #getAppStandbyBucket()
*/
public static final int STANDBY_BUCKET_RESTRICTED = 45;
diff --git a/core/java/android/companion/BluetoothDeviceFilterUtils.java b/core/java/android/companion/BluetoothDeviceFilterUtils.java
index 24be45cb20fe..8e687413b7e1 100644
--- a/core/java/android/companion/BluetoothDeviceFilterUtils.java
+++ b/core/java/android/companion/BluetoothDeviceFilterUtils.java
@@ -51,13 +51,6 @@ public class BluetoothDeviceFilterUtils {
return s == null ? null : Pattern.compile(s);
}
- static boolean matches(ScanFilter filter, BluetoothDevice device) {
- boolean result = matchesAddress(filter.getDeviceAddress(), device)
- && matchesServiceUuid(filter.getServiceUuid(), filter.getServiceUuidMask(), device);
- if (DEBUG) debugLogMatchResult(result, device, filter);
- return result;
- }
-
static boolean matchesAddress(String deviceAddress, BluetoothDevice device) {
final boolean result = deviceAddress == null
|| (device != null && deviceAddress.equals(device.getAddress()));
diff --git a/core/java/android/companion/BluetoothLeDeviceFilter.java b/core/java/android/companion/BluetoothLeDeviceFilter.java
index dccfb0346c9c..8c071fe99104 100644
--- a/core/java/android/companion/BluetoothLeDeviceFilter.java
+++ b/core/java/android/companion/BluetoothLeDeviceFilter.java
@@ -37,7 +37,6 @@ import android.util.Log;
import com.android.internal.util.BitUtils;
import com.android.internal.util.ObjectUtils;
-import com.android.internal.util.Preconditions;
import libcore.util.HexEncoding;
@@ -166,21 +165,18 @@ public final class BluetoothLeDeviceFilter implements DeviceFilter<ScanResult> {
/** @hide */
@Override
- public boolean matches(ScanResult device) {
- boolean result = matches(device.getDevice())
+ public boolean matches(ScanResult scanResult) {
+ BluetoothDevice device = scanResult.getDevice();
+ boolean result = getScanFilter().matches(scanResult)
+ && BluetoothDeviceFilterUtils.matchesName(getNamePattern(), device)
&& (mRawDataFilter == null
- || BitUtils.maskedEquals(device.getScanRecord().getBytes(),
+ || BitUtils.maskedEquals(scanResult.getScanRecord().getBytes(),
mRawDataFilter, mRawDataFilterMask));
if (DEBUG) Log.i(LOG_TAG, "matches(this = " + this + ", device = " + device +
") -> " + result);
return result;
}
- private boolean matches(BluetoothDevice device) {
- return BluetoothDeviceFilterUtils.matches(getScanFilter(), device)
- && BluetoothDeviceFilterUtils.matchesName(getNamePattern(), device);
- }
-
/** @hide */
@Override
public int getMediumType() {
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index be3cfeff729e..ededd0d2ea30 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -6445,7 +6445,7 @@ public class Intent implements Parcelable, Cloneable {
public static final int FLAG_ACTIVITY_RETAIN_IN_RECENTS = 0x00002000;
/**
- * This flag is only used in split-screen multi-window mode. The new activity will be displayed
+ * This flag is only used for split-screen multi-window mode. The new activity will be displayed
* adjacent to the one launching it. This can only be used in conjunction with
* {@link #FLAG_ACTIVITY_NEW_TASK}. Also, setting {@link #FLAG_ACTIVITY_MULTIPLE_TASK} is
* required if you want a new instance of an existing activity to be created.
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index c8dd4d9d9d51..70e4e6cbf622 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -205,6 +205,7 @@ public class PackageParser {
public static final String TAG_USES_PERMISSION_SDK_M = "uses-permission-sdk-m";
public static final String TAG_USES_SDK = "uses-sdk";
public static final String TAG_USES_SPLIT = "uses-split";
+ public static final String TAG_PROFILEABLE = "profileable";
public static final String METADATA_MAX_ASPECT_RATIO = "android.max_aspect";
public static final String METADATA_SUPPORTS_SIZE_CHANGES = "android.supports_size_changes";
@@ -459,6 +460,9 @@ public class PackageParser {
public final SigningDetails signingDetails;
public final boolean coreApp;
public final boolean debuggable;
+ // This does not represent the actual manifest structure since the 'profilable' tag
+ // could be used with attributes other than 'shell'. Extend if necessary.
+ public final boolean profilableByShell;
public final boolean multiArch;
public final boolean use32bitAbi;
public final boolean extractNativeLibs;
@@ -470,15 +474,13 @@ public class PackageParser {
public final int overlayPriority;
public ApkLite(String codePath, String packageName, String splitName,
- boolean isFeatureSplit,
- String configForSplit, String usesSplitName, boolean isSplitRequired,
- int versionCode, int versionCodeMajor,
- int revisionCode, int installLocation, List<VerifierInfo> verifiers,
- SigningDetails signingDetails, boolean coreApp,
- boolean debuggable, boolean multiArch, boolean use32bitAbi,
- boolean useEmbeddedDex, boolean extractNativeLibs, boolean isolatedSplits,
- String targetPackageName, boolean overlayIsStatic, int overlayPriority,
- int minSdkVersion, int targetSdkVersion) {
+ boolean isFeatureSplit, String configForSplit, String usesSplitName,
+ boolean isSplitRequired, int versionCode, int versionCodeMajor, int revisionCode,
+ int installLocation, List<VerifierInfo> verifiers, SigningDetails signingDetails,
+ boolean coreApp, boolean debuggable, boolean profilableByShell, boolean multiArch,
+ boolean use32bitAbi, boolean useEmbeddedDex, boolean extractNativeLibs,
+ boolean isolatedSplits, String targetPackageName, boolean overlayIsStatic,
+ int overlayPriority, int minSdkVersion, int targetSdkVersion) {
this.codePath = codePath;
this.packageName = packageName;
this.splitName = splitName;
@@ -493,6 +495,7 @@ public class PackageParser {
this.verifiers = verifiers.toArray(new VerifierInfo[verifiers.size()]);
this.coreApp = coreApp;
this.debuggable = debuggable;
+ this.profilableByShell = profilableByShell;
this.multiArch = multiArch;
this.use32bitAbi = use32bitAbi;
this.useEmbeddedDex = useEmbeddedDex;
@@ -1374,9 +1377,11 @@ public class PackageParser {
}
SigningDetails verified;
if (skipVerify) {
- // systemDir APKs are already trusted, save time by not verifying
+ // systemDir APKs are already trusted, save time by not verifying; since the signature
+ // is not verified and some system apps can have their V2+ signatures stripped allow
+ // pulling the certs from the jar signature.
verified = ApkSignatureVerifier.unsafeGetCertsWithoutVerification(
- apkPath, minSignatureScheme);
+ apkPath, SigningDetails.SignatureSchemeVersion.JAR);
} else {
verified = ApkSignatureVerifier.verify(apkPath, minSignatureScheme);
}
@@ -1573,6 +1578,7 @@ public class PackageParser {
int revisionCode = 0;
boolean coreApp = false;
boolean debuggable = false;
+ boolean profilableByShell = false;
boolean multiArch = false;
boolean use32bitAbi = false;
boolean extractNativeLibs = true;
@@ -1638,6 +1644,10 @@ public class PackageParser {
final String attr = attrs.getAttributeName(i);
if ("debuggable".equals(attr)) {
debuggable = attrs.getAttributeBooleanValue(i, false);
+ if (debuggable) {
+ // Debuggable implies profileable
+ profilableByShell = true;
+ }
}
if ("multiArch".equals(attr)) {
multiArch = attrs.getAttributeBooleanValue(i, false);
@@ -1690,6 +1700,13 @@ public class PackageParser {
minSdkVersion = attrs.getAttributeIntValue(i, DEFAULT_MIN_SDK_VERSION);
}
}
+ } else if (TAG_PROFILEABLE.equals(parser.getName())) {
+ for (int i = 0; i < attrs.getAttributeCount(); ++i) {
+ final String attr = attrs.getAttributeName(i);
+ if ("shell".equals(attr)) {
+ profilableByShell = attrs.getAttributeBooleanValue(i, profilableByShell);
+ }
+ }
}
}
@@ -1707,8 +1724,9 @@ public class PackageParser {
return new ApkLite(codePath, packageSplit.first, packageSplit.second, isFeatureSplit,
configForSplit, usesSplitName, isSplitRequired, versionCode, versionCodeMajor,
revisionCode, installLocation, verifiers, signingDetails, coreApp, debuggable,
- multiArch, use32bitAbi, useEmbeddedDex, extractNativeLibs, isolatedSplits,
- targetPackage, overlayIsStatic, overlayPriority, minSdkVersion, targetSdkVersion);
+ profilableByShell, multiArch, use32bitAbi, useEmbeddedDex, extractNativeLibs,
+ isolatedSplits, targetPackage, overlayIsStatic, overlayPriority, minSdkVersion,
+ targetSdkVersion);
}
/**
diff --git a/core/java/android/content/pm/dex/ArtManagerInternal.java b/core/java/android/content/pm/dex/ArtManagerInternal.java
index 62ab9e02f858..23fef29803e7 100644
--- a/core/java/android/content/pm/dex/ArtManagerInternal.java
+++ b/core/java/android/content/pm/dex/ArtManagerInternal.java
@@ -30,5 +30,5 @@ public abstract class ArtManagerInternal {
* in executes using the specified {@code abi}.
*/
public abstract PackageOptimizationInfo getPackageOptimizationInfo(
- ApplicationInfo info, String abi);
+ ApplicationInfo info, String abi, String activityName);
}
diff --git a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
index d2172d3741d1..c3e9402a389e 100644
--- a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
+++ b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
@@ -20,7 +20,6 @@ import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE
import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
-import android.compat.annotation.UnsupportedAppUsage;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageParser;
@@ -303,6 +302,7 @@ public class ApkLiteParseUtils {
int revisionCode = 0;
boolean coreApp = false;
boolean debuggable = false;
+ boolean profilableByShell = false;
boolean multiArch = false;
boolean use32bitAbi = false;
boolean extractNativeLibs = true;
@@ -379,6 +379,10 @@ public class ApkLiteParseUtils {
switch (attr) {
case "debuggable":
debuggable = attrs.getAttributeBooleanValue(i, false);
+ if (debuggable) {
+ // Debuggable implies profileable
+ profilableByShell = true;
+ }
break;
case "multiArch":
multiArch = attrs.getAttributeBooleanValue(i, false);
@@ -431,6 +435,13 @@ public class ApkLiteParseUtils {
minSdkVersion = attrs.getAttributeIntValue(i, DEFAULT_MIN_SDK_VERSION);
}
}
+ } else if (PackageParser.TAG_PROFILEABLE.equals(parser.getName())) {
+ for (int i = 0; i < attrs.getAttributeCount(); ++i) {
+ final String attr = attrs.getAttributeName(i);
+ if ("shell".equals(attr)) {
+ profilableByShell = attrs.getAttributeBooleanValue(i, profilableByShell);
+ }
+ }
}
}
@@ -445,12 +456,13 @@ public class ApkLiteParseUtils {
overlayPriority = 0;
}
- return input.success(new PackageParser.ApkLite(codePath, packageSplit.first,
- packageSplit.second, isFeatureSplit, configForSplit, usesSplitName, isSplitRequired,
- versionCode, versionCodeMajor, revisionCode, installLocation, verifiers,
- signingDetails, coreApp, debuggable, multiArch, use32bitAbi, useEmbeddedDex,
- extractNativeLibs, isolatedSplits, targetPackage, overlayIsStatic, overlayPriority,
- minSdkVersion, targetSdkVersion));
+ return input.success(
+ new PackageParser.ApkLite(codePath, packageSplit.first, packageSplit.second,
+ isFeatureSplit, configForSplit, usesSplitName, isSplitRequired, versionCode,
+ versionCodeMajor, revisionCode, installLocation, verifiers, signingDetails,
+ coreApp, debuggable, profilableByShell, multiArch, use32bitAbi,
+ useEmbeddedDex, extractNativeLibs, isolatedSplits, targetPackage,
+ overlayIsStatic, overlayPriority, minSdkVersion, targetSdkVersion));
}
public static ParseResult<Pair<String, String>> parsePackageSplitNames(ParseInput input,
diff --git a/core/java/android/content/pm/parsing/ParsingPackageUtils.java b/core/java/android/content/pm/parsing/ParsingPackageUtils.java
index 317107829623..bc9c71e7a68e 100644
--- a/core/java/android/content/pm/parsing/ParsingPackageUtils.java
+++ b/core/java/android/content/pm/parsing/ParsingPackageUtils.java
@@ -2748,9 +2748,11 @@ public class ParsingPackageUtils {
SigningDetails verified;
try {
if (skipVerify) {
- // systemDir APKs are already trusted, save time by not verifying
+ // systemDir APKs are already trusted, save time by not verifying; since the
+ // signature is not verified and some system apps can have their V2+ signatures
+ // stripped allow pulling the certs from the jar signature.
verified = ApkSignatureVerifier.unsafeGetCertsWithoutVerification(
- baseCodePath, minSignatureScheme);
+ baseCodePath, SigningDetails.SignatureSchemeVersion.JAR);
} else {
verified = ApkSignatureVerifier.verify(baseCodePath, minSignatureScheme);
}
diff --git a/core/java/android/hardware/biometrics/BiometricManager.java b/core/java/android/hardware/biometrics/BiometricManager.java
index 570cc2c11738..2d2dda04b146 100644
--- a/core/java/android/hardware/biometrics/BiometricManager.java
+++ b/core/java/android/hardware/biometrics/BiometricManager.java
@@ -26,6 +26,8 @@ import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.content.Context;
import android.os.RemoteException;
+import android.security.keystore.KeyGenParameterSpec;
+import android.security.keystore.KeyProperties;
import android.util.Slog;
/**
@@ -82,6 +84,9 @@ public class BiometricManager {
*
* <p>Types may combined via bitwise OR into a single integer representing multiple
* authenticators (e.g. <code>DEVICE_CREDENTIAL | BIOMETRIC_WEAK</code>).
+ *
+ * @see #canAuthenticate(int)
+ * @see BiometricPrompt.Builder#setAllowedAuthenticators(int)
*/
public interface Authenticators {
/**
@@ -118,6 +123,10 @@ public class BiometricManager {
* Any biometric (e.g. fingerprint, iris, or face) on the device that meets or exceeds the
* requirements for <strong>Tier 3</strong> (formerly <strong>Strong</strong>), as defined
* by the Android CDD.
+ *
+ * <p>This corresponds to {@link KeyProperties#AUTH_BIOMETRIC_STRONG} during key generation.
+ *
+ * @see KeyGenParameterSpec.Builder#setUserAuthenticationParameters(int, int)
*/
int BIOMETRIC_STRONG = 0x000F;
@@ -156,6 +165,11 @@ public class BiometricManager {
* The non-biometric credential used to secure the device (i.e., PIN, pattern, or password).
* This should typically only be used in combination with a biometric auth type, such as
* {@link #BIOMETRIC_WEAK}.
+ *
+ * <p>This corresponds to {@link KeyProperties#AUTH_DEVICE_CREDENTIAL} during key
+ * generation.
+ *
+ * @see KeyGenParameterSpec.Builder#setUserAuthenticationParameters(int, int)
*/
int DEVICE_CREDENTIAL = 1 << 15;
}
diff --git a/core/java/android/hardware/biometrics/BiometricPrompt.java b/core/java/android/hardware/biometrics/BiometricPrompt.java
index 5af7cef3e2b4..74caceae07c9 100644
--- a/core/java/android/hardware/biometrics/BiometricPrompt.java
+++ b/core/java/android/hardware/biometrics/BiometricPrompt.java
@@ -36,6 +36,8 @@ import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.security.identity.IdentityCredential;
+import android.security.keystore.KeyGenParameterSpec;
+import android.security.keystore.KeyProperties;
import android.text.TextUtils;
import android.util.Log;
@@ -371,6 +373,14 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan
* button on the prompt, making it an error to also call
* {@link #setNegativeButton(CharSequence, Executor, DialogInterface.OnClickListener)}.
*
+ * <p>If unlocking cryptographic operation(s), it is the application's responsibility to
+ * request authentication with the proper set of authenticators (e.g. match the
+ * authenticators specified during key generation).
+ *
+ * @see KeyGenParameterSpec.Builder#setUserAuthenticationParameters(int, int)
+ * @see KeyProperties#AUTH_BIOMETRIC_STRONG
+ * @see KeyProperties#AUTH_DEVICE_CREDENTIAL
+ *
* @param authenticators A bit field representing all valid authenticator types that may be
* invoked by the prompt.
* @return This builder.
@@ -606,8 +616,24 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan
}
/**
- * A wrapper class for the crypto objects supported by BiometricPrompt. Currently the framework
- * supports {@link Signature}, {@link Cipher} and {@link Mac} objects.
+ * A wrapper class for the cryptographic operations supported by BiometricPrompt.
+ *
+ * <p>Currently the framework supports {@link Signature}, {@link Cipher}, {@link Mac}, and
+ * {@link IdentityCredential}.
+ *
+ * <p>Cryptographic operations in Android can be split into two categories: auth-per-use and
+ * time-based. This is specified during key creation via the timeout parameter of the
+ * {@link KeyGenParameterSpec.Builder#setUserAuthenticationParameters(int, int)} API.
+ *
+ * <p>CryptoObjects are used to unlock auth-per-use keys via
+ * {@link BiometricPrompt#authenticate(CryptoObject, CancellationSignal, Executor,
+ * AuthenticationCallback)}, whereas time-based keys are unlocked for their specified duration
+ * any time the user authenticates with the specified authenticators (e.g. unlocking keyguard).
+ * If a time-based key is not available for use (i.e. none of the allowed authenticators have
+ * been unlocked recently), applications can prompt the user to authenticate via
+ * {@link BiometricPrompt#authenticate(CancellationSignal, Executor, AuthenticationCallback)}
+ *
+ * @see Builder#setAllowedAuthenticators(int)
*/
public static final class CryptoObject extends android.hardware.biometrics.CryptoObject {
public CryptoObject(@NonNull Signature signature) {
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index b149d7798aab..dc56963ffd8c 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -4086,10 +4086,11 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
/**
* <p>The accuracy of frame timestamp synchronization between physical cameras</p>
* <p>The accuracy of the frame timestamp synchronization determines the physical cameras'
- * ability to start exposure at the same time. If the sensorSyncType is CALIBRATED,
- * the physical camera sensors usually run in master-slave mode so that their shutter
- * time is synchronized. For APPROXIMATE sensorSyncType, the camera sensors usually run in
- * master-master mode, and there could be offset between their start of exposure.</p>
+ * ability to start exposure at the same time. If the sensorSyncType is CALIBRATED, the
+ * physical camera sensors usually run in leader/follower mode where one sensor generates a
+ * timing signal for the other, so that their shutter time is synchronized. For APPROXIMATE
+ * sensorSyncType, the camera sensors usually run in leader/leader mode, where both sensors
+ * use their own timing generator, and there could be offset between their start of exposure.</p>
* <p>In both cases, all images generated for a particular capture request still carry the same
* timestamps, so that they can be used to look up the matching frame number and
* onCaptureStarted callback.</p>
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index aa75f6042db8..53fdf38101bc 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -952,19 +952,35 @@ public abstract class CameraMetadata<TKey> {
* <li>{@link CameraCharacteristics#LENS_POSE_REFERENCE android.lens.poseReference}</li>
* <li>{@link CameraCharacteristics#LENS_DISTORTION android.lens.distortion}</li>
* </ul>
- * <p>The field of view of all non-RAW physical streams must be the same or as close as
- * possible to that of non-RAW logical streams. If the requested FOV is outside of the
- * range supported by the physical camera, the physical stream for that physical camera
- * will use either the maximum or minimum scaler crop region, depending on which one is
- * closer to the requested FOV. For example, for a logical camera with wide-tele lens
- * configuration where the wide lens is the default, if the logical camera's crop region
- * is set to maximum, the physical stream for the tele lens will be configured to its
- * maximum crop region. On the other hand, if the logical camera has a normal-wide lens
- * configuration where the normal lens is the default, when the logical camera's crop
- * region is set to maximum, the FOV of the logical streams will be that of the normal
- * lens. The FOV of the physical streams for the wide lens will be the same as the
- * logical stream, by making the crop region smaller than its active array size to
- * compensate for the smaller focal length.</p>
+ * <p>The field of view of non-RAW physical streams must not be smaller than that of the
+ * non-RAW logical streams, or the maximum field-of-view of the physical camera,
+ * whichever is smaller. The application should check the physical capture result
+ * metadata for how the physical streams are cropped or zoomed. More specifically, given
+ * the physical camera result metadata, the effective horizontal field-of-view of the
+ * physical camera is:</p>
+ * <pre><code>fov = 2 * atan2(cropW * sensorW / (2 * zoomRatio * activeArrayW), focalLength)
+ * </code></pre>
+ * <p>where the equation parameters are the physical camera's crop region width, physical
+ * sensor width, zoom ratio, active array width, and focal length respectively. Typically
+ * the physical stream of active physical camera has the same field-of-view as the
+ * logical streams. However, the same may not be true for physical streams from
+ * non-active physical cameras. For example, if the logical camera has a wide-ultrawide
+ * configuration where the wide lens is the default, when the crop region is set to the
+ * logical camera's active array size, (and the zoom ratio set to 1.0 starting from
+ * Android 11), a physical stream for the ultrawide camera may prefer outputing images
+ * with larger field-of-view than that of the wide camera for better stereo matching
+ * margin or more robust motion tracking. At the same time, the physical non-RAW streams'
+ * field of view must not be smaller than the requested crop region and zoom ratio, as
+ * long as it's within the physical lens' capability. For example, for a logical camera
+ * with wide-tele lens configuration where the wide lens is the default, if the logical
+ * camera's crop region is set to maximum size, and zoom ratio set to 1.0, the physical
+ * stream for the tele lens will be configured to its maximum size crop region (no zoom).</p>
+ * <p><em>Deprecated:</em> Prior to Android 11, the field of view of all non-RAW physical streams
+ * cannot be larger than that of non-RAW logical streams. If the logical camera has a
+ * wide-ultrawide lens configuration where the wide lens is the default, when the logical
+ * camera's crop region is set to maximum size, the FOV of the physical streams for the
+ * ultrawide lens will be the same as the logical stream, by making the crop region
+ * smaller than its active array size to compensate for the smaller focal length.</p>
* <p>Even if the underlying physical cameras have different RAW characteristics (such as
* size or CFA pattern), a logical camera can still advertise RAW capability. In this
* case, when the application configures a RAW stream, the camera device will make sure
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index d071037409a7..1b1ccb590e16 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -477,8 +477,8 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>>
* A constrained high speed request list contains some constrained high speed capture requests
* with certain interleaved pattern that is suitable for high speed preview/video streaming. An
* active constrained high speed capture session only accepts constrained high speed request
- * lists. This method can be used to do the sanity check when a constrained high speed capture
- * session receives a request list via {@link CameraCaptureSession#setRepeatingBurst} or
+ * lists. This method can be used to do the correctness check when a constrained high speed
+ * capture session receives a request list via {@link CameraCaptureSession#setRepeatingBurst} or
* {@link CameraCaptureSession#captureBurst}. </p>
*
*
diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
index 6d49add65c5b..e21b45ab6577 100644
--- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
@@ -1072,7 +1072,7 @@ public class CameraDeviceImpl extends CameraDevice
* @param lastFrameNumber last frame number returned from binder.
* @param repeatingRequestTypes the repeating requests' types.
*/
- private void checkEarlyTriggerSequenceComplete(
+ private void checkEarlyTriggerSequenceCompleteLocked(
final int requestId, final long lastFrameNumber,
final int[] repeatingRequestTypes) {
// lastFrameNumber being equal to NO_FRAMES_CAPTURED means that the request
@@ -1154,7 +1154,6 @@ public class CameraDeviceImpl extends CameraDevice
checkIfCameraClosedOrInError();
// Make sure that there all requests have at least 1 surface; all surfaces are non-null;
- // the surface isn't a physical stream surface for reprocessing request
for (CaptureRequest request : requestList) {
if (request.getTargets().isEmpty()) {
throw new IllegalArgumentException(
@@ -1165,17 +1164,6 @@ public class CameraDeviceImpl extends CameraDevice
if (surface == null) {
throw new IllegalArgumentException("Null Surface targets are not allowed");
}
-
- for (int i = 0; i < mConfiguredOutputs.size(); i++) {
- OutputConfiguration configuration = mConfiguredOutputs.valueAt(i);
- if (configuration.isForPhysicalCamera()
- && configuration.getSurfaces().contains(surface)) {
- if (request.isReprocess()) {
- throw new IllegalArgumentException(
- "Reprocess request on physical stream is not allowed");
- }
- }
- }
}
}
@@ -1212,7 +1200,7 @@ public class CameraDeviceImpl extends CameraDevice
if (repeating) {
if (mRepeatingRequestId != REQUEST_ID_NONE) {
- checkEarlyTriggerSequenceComplete(mRepeatingRequestId,
+ checkEarlyTriggerSequenceCompleteLocked(mRepeatingRequestId,
requestInfo.getLastFrameNumber(),
mRepeatingRequestTypes);
}
@@ -1269,7 +1257,7 @@ public class CameraDeviceImpl extends CameraDevice
return;
}
- checkEarlyTriggerSequenceComplete(requestId, lastFrameNumber, requestTypes);
+ checkEarlyTriggerSequenceCompleteLocked(requestId, lastFrameNumber, requestTypes);
}
}
}
@@ -1302,7 +1290,7 @@ public class CameraDeviceImpl extends CameraDevice
long lastFrameNumber = mRemoteDevice.flush();
if (mRepeatingRequestId != REQUEST_ID_NONE) {
- checkEarlyTriggerSequenceComplete(mRepeatingRequestId, lastFrameNumber,
+ checkEarlyTriggerSequenceCompleteLocked(mRepeatingRequestId, lastFrameNumber,
mRepeatingRequestTypes);
mRepeatingRequestId = REQUEST_ID_NONE;
mRepeatingRequestTypes = null;
@@ -1442,78 +1430,137 @@ public class CameraDeviceImpl extends CameraDevice
long completedFrameNumber = mFrameNumberTracker.getCompletedFrameNumber();
long completedReprocessFrameNumber = mFrameNumberTracker.getCompletedReprocessFrameNumber();
long completedZslStillFrameNumber = mFrameNumberTracker.getCompletedZslStillFrameNumber();
- boolean isReprocess = false;
+
Iterator<RequestLastFrameNumbersHolder> iter = mRequestLastFrameNumbersList.iterator();
while (iter.hasNext()) {
final RequestLastFrameNumbersHolder requestLastFrameNumbers = iter.next();
- boolean sequenceCompleted = false;
final int requestId = requestLastFrameNumbers.getRequestId();
final CaptureCallbackHolder holder;
- synchronized(mInterfaceLock) {
- if (mRemoteDevice == null) {
- Log.w(TAG, "Camera closed while checking sequences");
- return;
+ if (mRemoteDevice == null) {
+ Log.w(TAG, "Camera closed while checking sequences");
+ return;
+ }
+ if (!requestLastFrameNumbers.isSequenceCompleted()) {
+ long lastRegularFrameNumber =
+ requestLastFrameNumbers.getLastRegularFrameNumber();
+ long lastReprocessFrameNumber =
+ requestLastFrameNumbers.getLastReprocessFrameNumber();
+ long lastZslStillFrameNumber =
+ requestLastFrameNumbers.getLastZslStillFrameNumber();
+ if (lastRegularFrameNumber <= completedFrameNumber
+ && lastReprocessFrameNumber <= completedReprocessFrameNumber
+ && lastZslStillFrameNumber <= completedZslStillFrameNumber) {
+ if (DEBUG) {
+ Log.v(TAG, String.format(
+ "Mark requestId %d as completed, because lastRegularFrame %d "
+ + "is <= %d, lastReprocessFrame %d is <= %d, "
+ + "lastZslStillFrame %d is <= %d", requestId,
+ lastRegularFrameNumber, completedFrameNumber,
+ lastReprocessFrameNumber, completedReprocessFrameNumber,
+ lastZslStillFrameNumber, completedZslStillFrameNumber));
+ }
+ requestLastFrameNumbers.markSequenceCompleted();
}
+ // Call onCaptureSequenceCompleted
int index = mCaptureCallbackMap.indexOfKey(requestId);
holder = (index >= 0) ?
mCaptureCallbackMap.valueAt(index) : null;
- if (holder != null) {
- long lastRegularFrameNumber =
- requestLastFrameNumbers.getLastRegularFrameNumber();
- long lastReprocessFrameNumber =
- requestLastFrameNumbers.getLastReprocessFrameNumber();
- long lastZslStillFrameNumber =
- requestLastFrameNumbers.getLastZslStillFrameNumber();
- // check if it's okay to remove request from mCaptureCallbackMap
- if (lastRegularFrameNumber <= completedFrameNumber
- && lastReprocessFrameNumber <= completedReprocessFrameNumber
- && lastZslStillFrameNumber <= completedZslStillFrameNumber) {
- sequenceCompleted = true;
- mCaptureCallbackMap.removeAt(index);
- if (DEBUG) {
- Log.v(TAG, String.format(
- "Remove holder for requestId %d, because lastRegularFrame %d "
- + "is <= %d, lastReprocessFrame %d is <= %d, "
- + "lastZslStillFrame %d is <= %d", requestId,
- lastRegularFrameNumber, completedFrameNumber,
- lastReprocessFrameNumber, completedReprocessFrameNumber,
- lastZslStillFrameNumber, completedZslStillFrameNumber));
+ if (holder != null && requestLastFrameNumbers.isSequenceCompleted()) {
+ Runnable resultDispatch = new Runnable() {
+ @Override
+ public void run() {
+ if (!CameraDeviceImpl.this.isClosed()){
+ if (DEBUG) {
+ Log.d(TAG, String.format(
+ "fire sequence complete for request %d",
+ requestId));
+ }
+
+ holder.getCallback().onCaptureSequenceCompleted(
+ CameraDeviceImpl.this,
+ requestId,
+ requestLastFrameNumbers.getLastFrameNumber());
+ }
}
+ };
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ holder.getExecutor().execute(resultDispatch);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
}
}
}
- // If no callback is registered for this requestId or sequence completed, remove it
- // from the frame number->request pair because it's not needed anymore.
- if (holder == null || sequenceCompleted) {
+ if (requestLastFrameNumbers.isSequenceCompleted() &&
+ requestLastFrameNumbers.isInflightCompleted()) {
+ int index = mCaptureCallbackMap.indexOfKey(requestId);
+ if (index >= 0) {
+ mCaptureCallbackMap.removeAt(index);
+ }
+ if (DEBUG) {
+ Log.v(TAG, String.format(
+ "Remove holder for requestId %d", requestId));
+ }
iter.remove();
}
+ }
+ }
- // Call onCaptureSequenceCompleted
- if (sequenceCompleted) {
- Runnable resultDispatch = new Runnable() {
- @Override
- public void run() {
- if (!CameraDeviceImpl.this.isClosed()){
- if (DEBUG) {
- Log.d(TAG, String.format(
- "fire sequence complete for request %d",
- requestId));
- }
+ private void removeCompletedCallbackHolderLocked(long lastCompletedRegularFrameNumber,
+ long lastCompletedReprocessFrameNumber, long lastCompletedZslStillFrameNumber) {
+ if (DEBUG) {
+ Log.v(TAG, String.format("remove completed callback holders for "
+ + "lastCompletedRegularFrameNumber %d, "
+ + "lastCompletedReprocessFrameNumber %d, "
+ + "lastCompletedZslStillFrameNumber %d",
+ lastCompletedRegularFrameNumber,
+ lastCompletedReprocessFrameNumber,
+ lastCompletedZslStillFrameNumber));
+ }
- holder.getCallback().onCaptureSequenceCompleted(
- CameraDeviceImpl.this,
- requestId,
- requestLastFrameNumbers.getLastFrameNumber());
- }
+ Iterator<RequestLastFrameNumbersHolder> iter = mRequestLastFrameNumbersList.iterator();
+ while (iter.hasNext()) {
+ final RequestLastFrameNumbersHolder requestLastFrameNumbers = iter.next();
+ final int requestId = requestLastFrameNumbers.getRequestId();
+ final CaptureCallbackHolder holder;
+ if (mRemoteDevice == null) {
+ Log.w(TAG, "Camera closed while removing completed callback holders");
+ return;
+ }
+
+ long lastRegularFrameNumber =
+ requestLastFrameNumbers.getLastRegularFrameNumber();
+ long lastReprocessFrameNumber =
+ requestLastFrameNumbers.getLastReprocessFrameNumber();
+ long lastZslStillFrameNumber =
+ requestLastFrameNumbers.getLastZslStillFrameNumber();
+
+ if (lastRegularFrameNumber <= lastCompletedRegularFrameNumber
+ && lastReprocessFrameNumber <= lastCompletedReprocessFrameNumber
+ && lastZslStillFrameNumber <= lastCompletedZslStillFrameNumber) {
+
+ if (requestLastFrameNumbers.isSequenceCompleted()) {
+ int index = mCaptureCallbackMap.indexOfKey(requestId);
+ if (index >= 0) {
+ mCaptureCallbackMap.removeAt(index);
}
- };
- final long ident = Binder.clearCallingIdentity();
- try {
- holder.getExecutor().execute(resultDispatch);
- } finally {
- Binder.restoreCallingIdentity(ident);
+ if (DEBUG) {
+ Log.v(TAG, String.format(
+ "Remove holder for requestId %d, because lastRegularFrame %d "
+ + "is <= %d, lastReprocessFrame %d is <= %d, "
+ + "lastZslStillFrame %d is <= %d", requestId,
+ lastRegularFrameNumber, lastCompletedRegularFrameNumber,
+ lastReprocessFrameNumber, lastCompletedReprocessFrameNumber,
+ lastZslStillFrameNumber, lastCompletedZslStillFrameNumber));
+ }
+ iter.remove();
+ } else {
+ if (DEBUG) {
+ Log.v(TAG, "Sequence not yet completed for request id " + requestId);
+ }
+ requestLastFrameNumbers.markInflightCompleted();
}
}
}
@@ -1702,6 +1749,12 @@ public class CameraDeviceImpl extends CameraDevice
return;
}
+ // Remove all capture callbacks now that device has gone to IDLE state.
+ removeCompletedCallbackHolderLocked(
+ Long.MAX_VALUE, /*lastCompletedRegularFrameNumber*/
+ Long.MAX_VALUE, /*lastCompletedReprocessFrameNumber*/
+ Long.MAX_VALUE /*lastCompletedZslStillFrameNumber*/);
+
if (!CameraDeviceImpl.this.mIdle) {
final long ident = Binder.clearCallingIdentity();
try {
@@ -1747,7 +1800,7 @@ public class CameraDeviceImpl extends CameraDevice
return;
}
- checkEarlyTriggerSequenceComplete(mRepeatingRequestId, lastFrameNumber,
+ checkEarlyTriggerSequenceCompleteLocked(mRepeatingRequestId, lastFrameNumber,
mRepeatingRequestTypes);
// Check if there is already a new repeating request
if (mRepeatingRequestId == repeatingRequestId) {
@@ -1766,9 +1819,18 @@ public class CameraDeviceImpl extends CameraDevice
public void onCaptureStarted(final CaptureResultExtras resultExtras, final long timestamp) {
int requestId = resultExtras.getRequestId();
final long frameNumber = resultExtras.getFrameNumber();
+ final long lastCompletedRegularFrameNumber =
+ resultExtras.getLastCompletedRegularFrameNumber();
+ final long lastCompletedReprocessFrameNumber =
+ resultExtras.getLastCompletedReprocessFrameNumber();
+ final long lastCompletedZslFrameNumber =
+ resultExtras.getLastCompletedZslFrameNumber();
if (DEBUG) {
- Log.d(TAG, "Capture started for id " + requestId + " frame number " + frameNumber);
+ Log.d(TAG, "Capture started for id " + requestId + " frame number " + frameNumber
+ + ": completedRegularFrameNumber " + lastCompletedRegularFrameNumber
+ + ", completedReprocessFrameNUmber " + lastCompletedReprocessFrameNumber
+ + ", completedZslFrameNumber " + lastCompletedZslFrameNumber);
}
final CaptureCallbackHolder holder;
@@ -1784,6 +1846,12 @@ public class CameraDeviceImpl extends CameraDevice
return;
}
+ // Check if it's okay to remove completed callbacks from mCaptureCallbackMap.
+ // A callback is completed if the corresponding inflight request has been removed
+ // from the inflight queue in cameraservice.
+ removeCompletedCallbackHolderLocked(lastCompletedRegularFrameNumber,
+ lastCompletedReprocessFrameNumber, lastCompletedZslFrameNumber);
+
// Get the callback for this frame ID, if there is one
holder = CameraDeviceImpl.this.mCaptureCallbackMap.get(requestId);
diff --git a/core/java/android/hardware/camera2/impl/CameraOfflineSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraOfflineSessionImpl.java
index 1d9d644c9306..413caf5e22e0 100644
--- a/core/java/android/hardware/camera2/impl/CameraOfflineSessionImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraOfflineSessionImpl.java
@@ -182,6 +182,12 @@ public class CameraOfflineSessionImpl extends CameraOfflineSession
return;
}
+ // Remove all capture callbacks now that device has gone to IDLE state.
+ removeCompletedCallbackHolderLocked(
+ Long.MAX_VALUE, /*lastCompletedRegularFrameNumber*/
+ Long.MAX_VALUE, /*lastCompletedReprocessFrameNumber*/
+ Long.MAX_VALUE /*lastCompletedZslStillFrameNumber*/);
+
Runnable idleDispatch = new Runnable() {
@Override
public void run() {
@@ -204,10 +210,22 @@ public class CameraOfflineSessionImpl extends CameraOfflineSession
public void onCaptureStarted(final CaptureResultExtras resultExtras, final long timestamp) {
int requestId = resultExtras.getRequestId();
final long frameNumber = resultExtras.getFrameNumber();
+ final long lastCompletedRegularFrameNumber =
+ resultExtras.getLastCompletedRegularFrameNumber();
+ final long lastCompletedReprocessFrameNumber =
+ resultExtras.getLastCompletedReprocessFrameNumber();
+ final long lastCompletedZslFrameNumber =
+ resultExtras.getLastCompletedZslFrameNumber();
final CaptureCallbackHolder holder;
synchronized(mInterfaceLock) {
+ // Check if it's okay to remove completed callbacks from mCaptureCallbackMap.
+ // A callback is completed if the corresponding inflight request has been removed
+ // from the inflight queue in cameraservice.
+ removeCompletedCallbackHolderLocked(lastCompletedRegularFrameNumber,
+ lastCompletedReprocessFrameNumber, lastCompletedZslFrameNumber);
+
// Get the callback for this frame ID, if there is one
holder = CameraOfflineSessionImpl.this.mCaptureCallbackMap.get(requestId);
@@ -601,6 +619,61 @@ public class CameraOfflineSessionImpl extends CameraOfflineSession
}
}
+ private void removeCompletedCallbackHolderLocked(long lastCompletedRegularFrameNumber,
+ long lastCompletedReprocessFrameNumber, long lastCompletedZslStillFrameNumber) {
+ if (DEBUG) {
+ Log.v(TAG, String.format("remove completed callback holders for "
+ + "lastCompletedRegularFrameNumber %d, "
+ + "lastCompletedReprocessFrameNumber %d, "
+ + "lastCompletedZslStillFrameNumber %d",
+ lastCompletedRegularFrameNumber,
+ lastCompletedReprocessFrameNumber,
+ lastCompletedZslStillFrameNumber));
+ }
+
+ boolean isReprocess = false;
+ Iterator<RequestLastFrameNumbersHolder> iter =
+ mOfflineRequestLastFrameNumbersList.iterator();
+ while (iter.hasNext()) {
+ final RequestLastFrameNumbersHolder requestLastFrameNumbers = iter.next();
+ final int requestId = requestLastFrameNumbers.getRequestId();
+ final CaptureCallbackHolder holder;
+
+ int index = mCaptureCallbackMap.indexOfKey(requestId);
+ holder = (index >= 0) ?
+ mCaptureCallbackMap.valueAt(index) : null;
+ if (holder != null) {
+ long lastRegularFrameNumber =
+ requestLastFrameNumbers.getLastRegularFrameNumber();
+ long lastReprocessFrameNumber =
+ requestLastFrameNumbers.getLastReprocessFrameNumber();
+ long lastZslStillFrameNumber =
+ requestLastFrameNumbers.getLastZslStillFrameNumber();
+ if (lastRegularFrameNumber <= lastCompletedRegularFrameNumber
+ && lastReprocessFrameNumber <= lastCompletedReprocessFrameNumber
+ && lastZslStillFrameNumber <= lastCompletedZslStillFrameNumber) {
+ if (requestLastFrameNumbers.isSequenceCompleted()) {
+ mCaptureCallbackMap.removeAt(index);
+ if (DEBUG) {
+ Log.v(TAG, String.format(
+ "Remove holder for requestId %d, because lastRegularFrame %d "
+ + "is <= %d, lastReprocessFrame %d is <= %d, "
+ + "lastZslStillFrame %d is <= %d", requestId,
+ lastRegularFrameNumber, lastCompletedRegularFrameNumber,
+ lastReprocessFrameNumber, lastCompletedReprocessFrameNumber,
+ lastZslStillFrameNumber, lastCompletedZslStillFrameNumber));
+ }
+
+ iter.remove();
+ } else {
+ Log.e(TAG, "Sequence not yet completed for request id " + requestId);
+ continue;
+ }
+ }
+ }
+ }
+ }
+
public void notifyFailedSwitch() {
synchronized(mInterfaceLock) {
Runnable switchFailDispatch = new Runnable() {
diff --git a/core/java/android/hardware/camera2/impl/CaptureResultExtras.java b/core/java/android/hardware/camera2/impl/CaptureResultExtras.java
index 1ff5bd562f2e..5d9da73fd5c0 100644
--- a/core/java/android/hardware/camera2/impl/CaptureResultExtras.java
+++ b/core/java/android/hardware/camera2/impl/CaptureResultExtras.java
@@ -30,6 +30,9 @@ public class CaptureResultExtras implements Parcelable {
private int partialResultCount;
private int errorStreamId;
private String errorPhysicalCameraId;
+ private long lastCompletedRegularFrameNumber;
+ private long lastCompletedReprocessFrameNumber;
+ private long lastCompletedZslFrameNumber;
public static final @android.annotation.NonNull Parcelable.Creator<CaptureResultExtras> CREATOR =
new Parcelable.Creator<CaptureResultExtras>() {
@@ -51,7 +54,9 @@ public class CaptureResultExtras implements Parcelable {
public CaptureResultExtras(int requestId, int subsequenceId, int afTriggerId,
int precaptureTriggerId, long frameNumber,
int partialResultCount, int errorStreamId,
- String errorPhysicalCameraId) {
+ String errorPhysicalCameraId, long lastCompletedRegularFrameNumber,
+ long lastCompletedReprocessFrameNumber,
+ long lastCompletedZslFrameNumber) {
this.requestId = requestId;
this.subsequenceId = subsequenceId;
this.afTriggerId = afTriggerId;
@@ -60,6 +65,9 @@ public class CaptureResultExtras implements Parcelable {
this.partialResultCount = partialResultCount;
this.errorStreamId = errorStreamId;
this.errorPhysicalCameraId = errorPhysicalCameraId;
+ this.lastCompletedRegularFrameNumber = lastCompletedRegularFrameNumber;
+ this.lastCompletedReprocessFrameNumber = lastCompletedReprocessFrameNumber;
+ this.lastCompletedZslFrameNumber = lastCompletedZslFrameNumber;
}
@Override
@@ -82,6 +90,9 @@ public class CaptureResultExtras implements Parcelable {
} else {
dest.writeBoolean(false);
}
+ dest.writeLong(lastCompletedRegularFrameNumber);
+ dest.writeLong(lastCompletedReprocessFrameNumber);
+ dest.writeLong(lastCompletedZslFrameNumber);
}
public void readFromParcel(Parcel in) {
@@ -96,6 +107,9 @@ public class CaptureResultExtras implements Parcelable {
if (errorPhysicalCameraIdPresent) {
errorPhysicalCameraId = in.readString();
}
+ lastCompletedRegularFrameNumber = in.readLong();
+ lastCompletedReprocessFrameNumber = in.readLong();
+ lastCompletedZslFrameNumber = in.readLong();
}
public String getErrorPhysicalCameraId() {
@@ -129,4 +143,16 @@ public class CaptureResultExtras implements Parcelable {
public int getErrorStreamId() {
return errorStreamId;
}
+
+ public long getLastCompletedRegularFrameNumber() {
+ return lastCompletedRegularFrameNumber;
+ }
+
+ public long getLastCompletedReprocessFrameNumber() {
+ return lastCompletedReprocessFrameNumber;
+ }
+
+ public long getLastCompletedZslFrameNumber() {
+ return lastCompletedZslFrameNumber;
+ }
}
diff --git a/core/java/android/hardware/camera2/impl/RequestLastFrameNumbersHolder.java b/core/java/android/hardware/camera2/impl/RequestLastFrameNumbersHolder.java
index bd1df9e1ac7d..0ee4ebc1aa87 100644
--- a/core/java/android/hardware/camera2/impl/RequestLastFrameNumbersHolder.java
+++ b/core/java/android/hardware/camera2/impl/RequestLastFrameNumbersHolder.java
@@ -38,6 +38,10 @@ public class RequestLastFrameNumbersHolder {
// The last ZSL still capture frame number for this request ID. It's
// CaptureCallback.NO_FRAMES_CAPTURED if the request ID has no zsl request.
private final long mLastZslStillFrameNumber;
+ // Whether the sequence is completed. (only consider capture result)
+ private boolean mSequenceCompleted;
+ // Whether the inflight request is completed. (consider result, buffers, and notifies)
+ private boolean mInflightCompleted;
/**
* Create a request-last-frame-numbers holder with a list of requests, request ID, and
@@ -89,6 +93,8 @@ public class RequestLastFrameNumbersHolder {
mLastReprocessFrameNumber = lastReprocessFrameNumber;
mLastZslStillFrameNumber = lastZslStillFrameNumber;
mRequestId = requestInfo.getRequestId();
+ mSequenceCompleted = false;
+ mInflightCompleted = false;
}
/**
@@ -137,6 +143,8 @@ public class RequestLastFrameNumbersHolder {
mLastZslStillFrameNumber = lastZslStillFrameNumber;
mLastReprocessFrameNumber = CameraCaptureSession.CaptureCallback.NO_FRAMES_CAPTURED;
mRequestId = requestId;
+ mSequenceCompleted = false;
+ mInflightCompleted = false;
}
/**
@@ -177,5 +185,34 @@ public class RequestLastFrameNumbersHolder {
public int getRequestId() {
return mRequestId;
}
+
+ /**
+ * Return whether the capture sequence is completed.
+ */
+ public boolean isSequenceCompleted() {
+ return mSequenceCompleted;
+ }
+
+ /**
+ * Mark the capture sequence as completed.
+ */
+ public void markSequenceCompleted() {
+ mSequenceCompleted = true;
+ }
+
+ /**
+ * Return whether the inflight capture is completed.
+ */
+ public boolean isInflightCompleted() {
+ return mInflightCompleted;
+ }
+
+ /**
+ * Mark the inflight capture as completed.
+ */
+ public void markInflightCompleted() {
+ mInflightCompleted = true;
+ }
+
}
diff --git a/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java b/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java
index fbc9ac3229c3..fdd578c419d8 100644
--- a/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java
+++ b/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java
@@ -109,11 +109,12 @@ public class LegacyCameraDevice implements AutoCloseable {
}
if (holder == null) {
return new CaptureResultExtras(ILLEGAL_VALUE, ILLEGAL_VALUE, ILLEGAL_VALUE,
- ILLEGAL_VALUE, ILLEGAL_VALUE, ILLEGAL_VALUE, ILLEGAL_VALUE, null);
+ ILLEGAL_VALUE, ILLEGAL_VALUE, ILLEGAL_VALUE, ILLEGAL_VALUE, null,
+ ILLEGAL_VALUE, ILLEGAL_VALUE, ILLEGAL_VALUE);
}
return new CaptureResultExtras(holder.getRequestId(), holder.getSubsequeceId(),
/*afTriggerId*/0, /*precaptureTriggerId*/0, holder.getFrameNumber(),
- /*partialResultCount*/1, errorStreamId, null);
+ /*partialResultCount*/1, errorStreamId, null, holder.getFrameNumber(), -1, -1);
}
/**
diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java
index ea5cc7f2e8bc..c1ba2094d3cf 100644
--- a/core/java/android/hardware/display/DisplayManager.java
+++ b/core/java/android/hardware/display/DisplayManager.java
@@ -303,13 +303,25 @@ public final class DisplayManager {
/**
* Virtual display flag: Indicates that the display should support system decorations. Virtual
* displays without this flag shouldn't show home, IME or any other system decorations.
+ * <p>This flag doesn't work without {@link #VIRTUAL_DISPLAY_FLAG_TRUSTED}</p>
*
* @see #createVirtualDisplay
+ * @see #VIRTUAL_DISPLAY_FLAG_TRUSTED
* @hide
*/
// TODO (b/114338689): Remove the flag and use IWindowManager#setShouldShowSystemDecors
public static final int VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS = 1 << 9;
+ /**
+ * Virtual display flags: Indicates that the display is trusted to show system decorations and
+ * receive inputs without users' touch.
+ *
+ * @see #createVirtualDisplay
+ * @see #VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS
+ * @hide
+ */
+ public static final int VIRTUAL_DISPLAY_FLAG_TRUSTED = 1 << 10;
+
/** @hide */
public DisplayManager(Context context) {
mContext = context;
diff --git a/core/java/android/inputmethodservice/InlineSuggestionSession.java b/core/java/android/inputmethodservice/InlineSuggestionSession.java
index 26197883c32f..509cbe09df69 100644
--- a/core/java/android/inputmethodservice/InlineSuggestionSession.java
+++ b/core/java/android/inputmethodservice/InlineSuggestionSession.java
@@ -38,6 +38,7 @@ import com.android.internal.view.IInlineSuggestionsResponseCallback;
import com.android.internal.view.InlineSuggestionsRequestInfo;
import java.lang.ref.WeakReference;
+import java.util.Collections;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
@@ -58,6 +59,9 @@ import java.util.function.Supplier;
class InlineSuggestionSession {
private static final String TAG = "ImsInlineSuggestionSession";
+ static final InlineSuggestionsResponse EMPTY_RESPONSE = new InlineSuggestionsResponse(
+ Collections.emptyList());
+
@NonNull
private final Handler mMainThreadHandler;
@NonNull
@@ -72,6 +76,10 @@ class InlineSuggestionSession {
private final Supplier<IBinder> mHostInputTokenSupplier;
@NonNull
private final Consumer<InlineSuggestionsResponse> mResponseConsumer;
+ // Indicate whether the previous call to the mResponseConsumer is empty or not. If it hasn't
+ // been called yet, the value would be null.
+ @Nullable
+ private Boolean mPreviousResponseIsEmpty;
/**
@@ -142,6 +150,7 @@ class InlineSuggestionSession {
@MainThread
void invalidate() {
if (mResponseCallback != null) {
+ consumeInlineSuggestionsResponse(EMPTY_RESPONSE);
mResponseCallback.invalidate();
mResponseCallback = null;
}
@@ -188,6 +197,17 @@ class InlineSuggestionSession {
if (DEBUG) {
Log.d(TAG, "IME receives response: " + response.getInlineSuggestions().size());
}
+ consumeInlineSuggestionsResponse(response);
+ }
+
+ @MainThread
+ void consumeInlineSuggestionsResponse(@NonNull InlineSuggestionsResponse response) {
+ boolean isResponseEmpty = response.getInlineSuggestions().isEmpty();
+ if (isResponseEmpty && Boolean.TRUE.equals(mPreviousResponseIsEmpty)) {
+ // No-op if both the previous response and current response are empty.
+ return;
+ }
+ mPreviousResponseIsEmpty = isResponseEmpty;
mResponseConsumer.accept(response);
}
diff --git a/core/java/android/inputmethodservice/InlineSuggestionSessionController.java b/core/java/android/inputmethodservice/InlineSuggestionSessionController.java
index c9f9059bed4f..8c0dd2a9bf59 100644
--- a/core/java/android/inputmethodservice/InlineSuggestionSessionController.java
+++ b/core/java/android/inputmethodservice/InlineSuggestionSessionController.java
@@ -213,6 +213,7 @@ class InlineSuggestionSessionController {
mImeInputViewStarted = false;
mImeInputStarted = false;
if (mSession != null && mSession.shouldSendImeStatus()) {
+ mSession.consumeInlineSuggestionsResponse(InlineSuggestionSession.EMPTY_RESPONSE);
try {
mSession.getRequestCallback().onInputMethodFinishInput();
} catch (RemoteException e) {
diff --git a/core/java/android/net/DhcpResults.java b/core/java/android/net/DhcpResults.java
index 5ab035496a43..1ef4f1741e3a 100644
--- a/core/java/android/net/DhcpResults.java
+++ b/core/java/android/net/DhcpResults.java
@@ -18,12 +18,13 @@ package android.net;
import android.annotation.Nullable;
import android.compat.annotation.UnsupportedAppUsage;
-import android.net.shared.InetAddressUtils;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
import android.util.Log;
+import com.android.net.module.util.InetAddressUtils;
+
import java.net.Inet4Address;
import java.net.InetAddress;
import java.util.ArrayList;
diff --git a/core/java/android/net/DnsPacket.java b/core/java/android/net/DnsPacket.java
deleted file mode 100644
index 83e57e0a047b..000000000000
--- a/core/java/android/net/DnsPacket.java
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.text.TextUtils;
-
-import com.android.internal.util.BitUtils;
-
-import java.nio.BufferUnderflowException;
-import java.nio.ByteBuffer;
-import java.text.DecimalFormat;
-import java.text.FieldPosition;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Defines basic data for DNS protocol based on RFC 1035.
- * Subclasses create the specific format used in DNS packet.
- *
- * @hide
- */
-public abstract class DnsPacket {
- public class DnsHeader {
- private static final String TAG = "DnsHeader";
- public final int id;
- public final int flags;
- public final int rcode;
- private final int[] mRecordCount;
-
- /**
- * Create a new DnsHeader from a positioned ByteBuffer.
- *
- * The ByteBuffer must be in network byte order (which is the default).
- * Reads the passed ByteBuffer from its current position and decodes a DNS header.
- * When this constructor returns, the reading position of the ByteBuffer has been
- * advanced to the end of the DNS header record.
- * This is meant to chain with other methods reading a DNS response in sequence.
- */
- DnsHeader(@NonNull ByteBuffer buf) throws BufferUnderflowException {
- id = BitUtils.uint16(buf.getShort());
- flags = BitUtils.uint16(buf.getShort());
- rcode = flags & 0xF;
- mRecordCount = new int[NUM_SECTIONS];
- for (int i = 0; i < NUM_SECTIONS; ++i) {
- mRecordCount[i] = BitUtils.uint16(buf.getShort());
- }
- }
-
- /**
- * Get record count by type.
- */
- public int getRecordCount(int type) {
- return mRecordCount[type];
- }
- }
-
- /**
- * Superclass for DNS questions and DNS resource records.
- *
- * DNS questions (No TTL/RDATA)
- * DNS resource records (With TTL/RDATA)
- */
- public class DnsRecord {
- private static final int MAXNAMESIZE = 255;
- private static final int MAXLABELSIZE = 63;
- private static final int MAXLABELCOUNT = 128;
- private static final int NAME_NORMAL = 0;
- private static final int NAME_COMPRESSION = 0xC0;
- private final DecimalFormat byteFormat = new DecimalFormat();
- private final FieldPosition pos = new FieldPosition(0);
-
- private static final String TAG = "DnsRecord";
-
- public final String dName;
- public final int nsType;
- public final int nsClass;
- public final long ttl;
- private final byte[] mRdata;
-
- /**
- * Create a new DnsRecord from a positioned ByteBuffer.
- *
- * Reads the passed ByteBuffer from its current position and decodes a DNS record.
- * When this constructor returns, the reading position of the ByteBuffer has been
- * advanced to the end of the DNS header record.
- * This is meant to chain with other methods reading a DNS response in sequence.
- *
- * @param ByteBuffer input of record, must be in network byte order
- * (which is the default).
- */
- DnsRecord(int recordType, @NonNull ByteBuffer buf)
- throws BufferUnderflowException, ParseException {
- dName = parseName(buf, 0 /* Parse depth */);
- if (dName.length() > MAXNAMESIZE) {
- throw new ParseException(
- "Parse name fail, name size is too long: " + dName.length());
- }
- nsType = BitUtils.uint16(buf.getShort());
- nsClass = BitUtils.uint16(buf.getShort());
-
- if (recordType != QDSECTION) {
- ttl = BitUtils.uint32(buf.getInt());
- final int length = BitUtils.uint16(buf.getShort());
- mRdata = new byte[length];
- buf.get(mRdata);
- } else {
- ttl = 0;
- mRdata = null;
- }
- }
-
- /**
- * Get a copy of rdata.
- */
- @Nullable
- public byte[] getRR() {
- return (mRdata == null) ? null : mRdata.clone();
- }
-
- /**
- * Convert label from {@code byte[]} to {@code String}
- *
- * Follows the same conversion rules of the native code (ns_name.c in libc)
- */
- private String labelToString(@NonNull byte[] label) {
- final StringBuffer sb = new StringBuffer();
- for (int i = 0; i < label.length; ++i) {
- int b = BitUtils.uint8(label[i]);
- // Control characters and non-ASCII characters.
- if (b <= 0x20 || b >= 0x7f) {
- // Append the byte as an escaped decimal number, e.g., "\19" for 0x13.
- sb.append('\\');
- byteFormat.format(b, sb, pos);
- } else if (b == '"' || b == '.' || b == ';' || b == '\\'
- || b == '(' || b == ')' || b == '@' || b == '$') {
- // Append the byte as an escaped character, e.g., "\:" for 0x3a.
- sb.append('\\');
- sb.append((char) b);
- } else {
- // Append the byte as a character, e.g., "a" for 0x61.
- sb.append((char) b);
- }
- }
- return sb.toString();
- }
-
- private String parseName(@NonNull ByteBuffer buf, int depth) throws
- BufferUnderflowException, ParseException {
- if (depth > MAXLABELCOUNT) {
- throw new ParseException("Failed to parse name, too many labels");
- }
- final int len = BitUtils.uint8(buf.get());
- final int mask = len & NAME_COMPRESSION;
- if (0 == len) {
- return "";
- } else if (mask != NAME_NORMAL && mask != NAME_COMPRESSION) {
- throw new ParseException("Parse name fail, bad label type");
- } else if (mask == NAME_COMPRESSION) {
- // Name compression based on RFC 1035 - 4.1.4 Message compression
- final int offset = ((len & ~NAME_COMPRESSION) << 8) + BitUtils.uint8(buf.get());
- final int oldPos = buf.position();
- if (offset >= oldPos - 2) {
- throw new ParseException("Parse compression name fail, invalid compression");
- }
- buf.position(offset);
- final String pointed = parseName(buf, depth + 1);
- buf.position(oldPos);
- return pointed;
- } else {
- final byte[] label = new byte[len];
- buf.get(label);
- final String head = labelToString(label);
- if (head.length() > MAXLABELSIZE) {
- throw new ParseException("Parse name fail, invalid label length");
- }
- final String tail = parseName(buf, depth + 1);
- return TextUtils.isEmpty(tail) ? head : head + "." + tail;
- }
- }
- }
-
- public static final int QDSECTION = 0;
- public static final int ANSECTION = 1;
- public static final int NSSECTION = 2;
- public static final int ARSECTION = 3;
- private static final int NUM_SECTIONS = ARSECTION + 1;
-
- private static final String TAG = DnsPacket.class.getSimpleName();
-
- protected final DnsHeader mHeader;
- protected final List<DnsRecord>[] mRecords;
-
- protected DnsPacket(@NonNull byte[] data) throws ParseException {
- if (null == data) throw new ParseException("Parse header failed, null input data");
- final ByteBuffer buffer;
- try {
- buffer = ByteBuffer.wrap(data);
- mHeader = new DnsHeader(buffer);
- } catch (BufferUnderflowException e) {
- throw new ParseException("Parse Header fail, bad input data", e);
- }
-
- mRecords = new ArrayList[NUM_SECTIONS];
-
- for (int i = 0; i < NUM_SECTIONS; ++i) {
- final int count = mHeader.getRecordCount(i);
- if (count > 0) {
- mRecords[i] = new ArrayList(count);
- }
- for (int j = 0; j < count; ++j) {
- try {
- mRecords[i].add(new DnsRecord(i, buffer));
- } catch (BufferUnderflowException e) {
- throw new ParseException("Parse record fail", e);
- }
- }
- }
- }
-}
diff --git a/core/java/android/net/DnsResolver.java b/core/java/android/net/DnsResolver.java
index 0b1a84534e38..3f7660f5709a 100644
--- a/core/java/android/net/DnsResolver.java
+++ b/core/java/android/net/DnsResolver.java
@@ -38,6 +38,8 @@ import android.os.MessageQueue;
import android.system.ErrnoException;
import android.util.Log;
+import com.android.net.module.util.DnsPacket;
+
import java.io.FileDescriptor;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -97,7 +99,7 @@ public final class DnsResolver {
@interface DnsError {}
/**
* Indicates that there was an error parsing the response the query.
- * The cause of this error is available via getCause() and is a ParseException.
+ * The cause of this error is available via getCause() and is a {@link ParseException}.
*/
public static final int ERROR_PARSE = 0;
/**
@@ -290,8 +292,15 @@ public final class DnsResolver {
}
try {
mAllAnswers.addAll(new DnsAddressAnswer(answer).getAddresses());
- } catch (ParseException e) {
- mDnsException = new DnsException(ERROR_PARSE, e);
+ } catch (DnsPacket.ParseException e) {
+ // Convert the com.android.net.module.util.DnsPacket.ParseException to an
+ // android.net.ParseException. This is the type that was used in Q and is implied
+ // by the public documentation of ERROR_PARSE.
+ //
+ // DnsPacket cannot throw android.net.ParseException directly because it's @hide.
+ ParseException pe = new ParseException(e.reason, e.getCause());
+ pe.setStackTrace(e.getStackTrace());
+ mDnsException = new DnsException(ERROR_PARSE, pe);
}
maybeReportAnswer();
}
diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java
index a3fd60e9d3b0..004f84422b44 100644
--- a/core/java/android/net/NetworkCapabilities.java
+++ b/core/java/android/net/NetworkCapabilities.java
@@ -900,9 +900,17 @@ public final class NetworkCapabilities implements Parcelable {
* <p>For NetworkCapability instances being sent from ConnectivityService, this value MUST be
* reset to Process.INVALID_UID unless all the following conditions are met:
*
+ * <p>The caller is the network owner, AND one of the following sets of requirements is met:
+ *
+ * <ol>
+ * <li>The described Network is a VPN
+ * </ol>
+ *
+ * <p>OR:
+ *
* <ol>
- * <li>The destination app is the network owner
- * <li>The destination app has the ACCESS_FINE_LOCATION permission granted
+ * <li>The calling app is the network owner
+ * <li>The calling app has the ACCESS_FINE_LOCATION permission granted
* <li>The user's location toggle is on
* </ol>
*
@@ -928,7 +936,16 @@ public final class NetworkCapabilities implements Parcelable {
/**
* Retrieves the UID of the app that owns this network.
*
- * <p>For user privacy reasons, this field will only be populated if:
+ * <p>For user privacy reasons, this field will only be populated if the following conditions
+ * are met:
+ *
+ * <p>The caller is the network owner, AND one of the following sets of requirements is met:
+ *
+ * <ol>
+ * <li>The described Network is a VPN
+ * </ol>
+ *
+ * <p>OR:
*
* <ol>
* <li>The calling app is the network owner
@@ -936,8 +953,8 @@ public final class NetworkCapabilities implements Parcelable {
* <li>The user's location toggle is on
* </ol>
*
- * Instances of NetworkCapabilities sent to apps without the appropriate permissions will
- * have this field cleared out.
+ * Instances of NetworkCapabilities sent to apps without the appropriate permissions will have
+ * this field cleared out.
*/
public int getOwnerUid() {
return mOwnerUid;
diff --git a/core/java/android/net/NetworkUtils.java b/core/java/android/net/NetworkUtils.java
index 779f7bc91e8f..97a7ecc3fb15 100644
--- a/core/java/android/net/NetworkUtils.java
+++ b/core/java/android/net/NetworkUtils.java
@@ -21,13 +21,14 @@ import static android.system.OsConstants.AF_INET6;
import android.annotation.NonNull;
import android.compat.annotation.UnsupportedAppUsage;
-import android.net.shared.Inet4AddressUtils;
import android.os.Build;
import android.system.ErrnoException;
import android.system.Os;
import android.util.Log;
import android.util.Pair;
+import com.android.net.module.util.Inet4AddressUtils;
+
import java.io.FileDescriptor;
import java.math.BigInteger;
import java.net.Inet4Address;
@@ -155,6 +156,14 @@ public class NetworkUtils {
public static native Network getDnsNetwork() throws ErrnoException;
/**
+ * Allow/Disallow creating AF_INET/AF_INET6 sockets and DNS lookups for current process.
+ *
+ * @param allowNetworking whether to allow or disallow creating AF_INET/AF_INET6 sockets
+ * and DNS lookups.
+ */
+ public static native void setAllowNetworkingForProcess(boolean allowNetworking);
+
+ /**
* Get the tcp repair window associated with the {@code fd}.
*
* @param fd the tcp socket's {@link FileDescriptor}.
diff --git a/core/java/android/net/RouteInfo.java b/core/java/android/net/RouteInfo.java
index e550f85e6b9a..98760761736d 100644
--- a/core/java/android/net/RouteInfo.java
+++ b/core/java/android/net/RouteInfo.java
@@ -26,7 +26,6 @@ import android.net.util.NetUtils;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
-import android.util.Pair;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -554,15 +553,45 @@ public final class RouteInfo implements Parcelable {
}
/**
- * A helper class that contains the destination and the gateway in a {@code RouteInfo},
- * used by {@link ConnectivityService#updateRoutes} or
+ * A helper class that contains the destination, the gateway and the interface in a
+ * {@code RouteInfo}, used by {@link ConnectivityService#updateRoutes} or
* {@link LinkProperties#addRoute} to calculate the list to be updated.
+ * {@code RouteInfo} objects with different interfaces are treated as different routes because
+ * *usually* on Android different interfaces use different routing tables, and moving a route
+ * to a new routing table never constitutes an update, but is always a remove and an add.
*
* @hide
*/
- public static class RouteKey extends Pair<IpPrefix, InetAddress> {
- RouteKey(@NonNull IpPrefix destination, @Nullable InetAddress gateway) {
- super(destination, gateway);
+ public static class RouteKey {
+ @NonNull private final IpPrefix mDestination;
+ @Nullable private final InetAddress mGateway;
+ @Nullable private final String mInterface;
+
+ RouteKey(@NonNull IpPrefix destination, @Nullable InetAddress gateway,
+ @Nullable String iface) {
+ mDestination = destination;
+ mGateway = gateway;
+ mInterface = iface;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof RouteKey)) {
+ return false;
+ }
+ RouteKey p = (RouteKey) o;
+ // No need to do anything special for scoped addresses. Inet6Address#equals does not
+ // consider the scope ID, but the netd route IPCs (e.g., INetd#networkAddRouteParcel)
+ // and the kernel ignore scoped addresses both in the prefix and in the nexthop and only
+ // look at RTA_OIF.
+ return Objects.equals(p.mDestination, mDestination)
+ && Objects.equals(p.mGateway, mGateway)
+ && Objects.equals(p.mInterface, mInterface);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mDestination, mGateway, mInterface);
}
}
@@ -574,7 +603,7 @@ public final class RouteInfo implements Parcelable {
*/
@NonNull
public RouteKey getRouteKey() {
- return new RouteKey(mDestination, mGateway);
+ return new RouteKey(mDestination, mGateway, mInterface);
}
/**
diff --git a/core/java/android/net/StaticIpConfiguration.java b/core/java/android/net/StaticIpConfiguration.java
index f24a9bd53039..a973455baa04 100644
--- a/core/java/android/net/StaticIpConfiguration.java
+++ b/core/java/android/net/StaticIpConfiguration.java
@@ -21,11 +21,11 @@ import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage;
-import android.net.shared.InetAddressUtils;
import android.os.Parcel;
import android.os.Parcelable;
import com.android.internal.util.Preconditions;
+import com.android.net.module.util.InetAddressUtils;
import java.net.InetAddress;
import java.util.ArrayList;
diff --git a/core/java/android/net/shared/Inet4AddressUtils.java b/core/java/android/net/shared/Inet4AddressUtils.java
deleted file mode 100644
index bec0c84fa689..000000000000
--- a/core/java/android/net/shared/Inet4AddressUtils.java
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.shared;
-
-import java.net.Inet4Address;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-
-/**
- * Collection of utilities to work with IPv4 addresses.
- * @hide
- */
-public class Inet4AddressUtils {
-
- /**
- * Convert a IPv4 address from an integer to an InetAddress (0x04030201 -> 1.2.3.4)
- *
- * <p>This method uses the higher-order int bytes as the lower-order IPv4 address bytes,
- * which is an unusual convention. Consider {@link #intToInet4AddressHTH(int)} instead.
- * @param hostAddress an int coding for an IPv4 address, where higher-order int byte is
- * lower-order IPv4 address byte
- */
- public static Inet4Address intToInet4AddressHTL(int hostAddress) {
- return intToInet4AddressHTH(Integer.reverseBytes(hostAddress));
- }
-
- /**
- * Convert a IPv4 address from an integer to an InetAddress (0x01020304 -> 1.2.3.4)
- * @param hostAddress an int coding for an IPv4 address
- */
- public static Inet4Address intToInet4AddressHTH(int hostAddress) {
- byte[] addressBytes = { (byte) (0xff & (hostAddress >> 24)),
- (byte) (0xff & (hostAddress >> 16)),
- (byte) (0xff & (hostAddress >> 8)),
- (byte) (0xff & hostAddress) };
-
- try {
- return (Inet4Address) InetAddress.getByAddress(addressBytes);
- } catch (UnknownHostException e) {
- throw new AssertionError();
- }
- }
-
- /**
- * Convert an IPv4 address from an InetAddress to an integer (1.2.3.4 -> 0x01020304)
- *
- * <p>This conversion can help order IP addresses: considering the ordering
- * 192.0.2.1 < 192.0.2.2 < ..., resulting ints will follow that ordering if read as unsigned
- * integers with {@link Integer#toUnsignedLong}.
- * @param inetAddr is an InetAddress corresponding to the IPv4 address
- * @return the IP address as integer
- */
- public static int inet4AddressToIntHTH(Inet4Address inetAddr)
- throws IllegalArgumentException {
- byte [] addr = inetAddr.getAddress();
- return ((addr[0] & 0xff) << 24) | ((addr[1] & 0xff) << 16)
- | ((addr[2] & 0xff) << 8) | (addr[3] & 0xff);
- }
-
- /**
- * Convert a IPv4 address from an InetAddress to an integer (1.2.3.4 -> 0x04030201)
- *
- * <p>This method stores the higher-order IPv4 address bytes in the lower-order int bytes,
- * which is an unusual convention. Consider {@link #inet4AddressToIntHTH(Inet4Address)} instead.
- * @param inetAddr is an InetAddress corresponding to the IPv4 address
- * @return the IP address as integer
- */
- public static int inet4AddressToIntHTL(Inet4Address inetAddr) {
- return Integer.reverseBytes(inet4AddressToIntHTH(inetAddr));
- }
-
- /**
- * Convert a network prefix length to an IPv4 netmask integer (prefixLength 17 -> 0xffff8000)
- * @return the IPv4 netmask as an integer
- */
- public static int prefixLengthToV4NetmaskIntHTH(int prefixLength)
- throws IllegalArgumentException {
- if (prefixLength < 0 || prefixLength > 32) {
- throw new IllegalArgumentException("Invalid prefix length (0 <= prefix <= 32)");
- }
- // (int)a << b is equivalent to a << (b & 0x1f): can't shift by 32 (-1 << 32 == -1)
- return prefixLength == 0 ? 0 : 0xffffffff << (32 - prefixLength);
- }
-
- /**
- * Convert a network prefix length to an IPv4 netmask integer (prefixLength 17 -> 0x0080ffff).
- *
- * <p>This method stores the higher-order IPv4 address bytes in the lower-order int bytes,
- * which is an unusual convention. Consider {@link #prefixLengthToV4NetmaskIntHTH(int)} instead.
- * @return the IPv4 netmask as an integer
- */
- public static int prefixLengthToV4NetmaskIntHTL(int prefixLength)
- throws IllegalArgumentException {
- return Integer.reverseBytes(prefixLengthToV4NetmaskIntHTH(prefixLength));
- }
-
- /**
- * Convert an IPv4 netmask to a prefix length, checking that the netmask is contiguous.
- * @param netmask as a {@code Inet4Address}.
- * @return the network prefix length
- * @throws IllegalArgumentException the specified netmask was not contiguous.
- * @hide
- */
- public static int netmaskToPrefixLength(Inet4Address netmask) {
- // inetAddressToInt returns an int in *network* byte order.
- int i = inet4AddressToIntHTH(netmask);
- int prefixLength = Integer.bitCount(i);
- int trailingZeros = Integer.numberOfTrailingZeros(i);
- if (trailingZeros != 32 - prefixLength) {
- throw new IllegalArgumentException("Non-contiguous netmask: " + Integer.toHexString(i));
- }
- return prefixLength;
- }
-
- /**
- * Returns the implicit netmask of an IPv4 address, as was the custom before 1993.
- */
- public static int getImplicitNetmask(Inet4Address address) {
- int firstByte = address.getAddress()[0] & 0xff; // Convert to an unsigned value.
- if (firstByte < 128) {
- return 8;
- } else if (firstByte < 192) {
- return 16;
- } else if (firstByte < 224) {
- return 24;
- } else {
- return 32; // Will likely not end well for other reasons.
- }
- }
-
- /**
- * Get the broadcast address for a given prefix.
- *
- * <p>For example 192.168.0.1/24 -> 192.168.0.255
- */
- public static Inet4Address getBroadcastAddress(Inet4Address addr, int prefixLength)
- throws IllegalArgumentException {
- final int intBroadcastAddr = inet4AddressToIntHTH(addr)
- | ~prefixLengthToV4NetmaskIntHTH(prefixLength);
- return intToInet4AddressHTH(intBroadcastAddr);
- }
-
- /**
- * Get a prefix mask as Inet4Address for a given prefix length.
- *
- * <p>For example 20 -> 255.255.240.0
- */
- public static Inet4Address getPrefixMaskAsInet4Address(int prefixLength)
- throws IllegalArgumentException {
- return intToInet4AddressHTH(prefixLengthToV4NetmaskIntHTH(prefixLength));
- }
-}
diff --git a/core/java/android/net/shared/InetAddressUtils.java b/core/java/android/net/shared/InetAddressUtils.java
deleted file mode 100644
index c9ee3a7cce4b..000000000000
--- a/core/java/android/net/shared/InetAddressUtils.java
+++ /dev/null
@@ -1,58 +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.net.shared;
-
-import android.os.Parcel;
-
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-
-/**
- * Collection of utilities to interact with {@link InetAddress}
- * @hide
- */
-public class InetAddressUtils {
-
- /**
- * Writes an InetAddress to a parcel. The address may be null. This is likely faster than
- * calling writeSerializable.
- * @hide
- */
- public static void parcelInetAddress(Parcel parcel, InetAddress address, int flags) {
- byte[] addressArray = (address != null) ? address.getAddress() : null;
- parcel.writeByteArray(addressArray);
- }
-
- /**
- * Reads an InetAddress from a parcel. Returns null if the address that was written was null
- * or if the data is invalid.
- * @hide
- */
- public static InetAddress unparcelInetAddress(Parcel in) {
- byte[] addressArray = in.createByteArray();
- if (addressArray == null) {
- return null;
- }
- try {
- return InetAddress.getByAddress(addressArray);
- } catch (UnknownHostException e) {
- return null;
- }
- }
-
- private InetAddressUtils() {}
-}
diff --git a/core/java/android/os/CarrierAssociatedAppEntry.aidl b/core/java/android/os/CarrierAssociatedAppEntry.aidl
new file mode 100644
index 000000000000..a9b1055ee174
--- /dev/null
+++ b/core/java/android/os/CarrierAssociatedAppEntry.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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 android.os;
+
+parcelable CarrierAssociatedAppEntry;
diff --git a/core/java/android/os/CarrierAssociatedAppEntry.java b/core/java/android/os/CarrierAssociatedAppEntry.java
new file mode 100644
index 000000000000..13f6eb63e29c
--- /dev/null
+++ b/core/java/android/os/CarrierAssociatedAppEntry.java
@@ -0,0 +1,68 @@
+/*
+ * 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 android.os;
+
+/**
+ * Represents a carrier app entry for use with {@link SystemConfigService}.
+ *
+ * @hide
+ */
+public final class CarrierAssociatedAppEntry implements Parcelable {
+
+ /**
+ * For carrier-associated app entries that don't specify the addedInSdk XML
+ * attribute.
+ */
+ public static final int SDK_UNSPECIFIED = -1;
+
+ public final String packageName;
+ /** May be {@link #SDK_UNSPECIFIED}. */
+ public final int addedInSdk;
+
+ public CarrierAssociatedAppEntry(String packageName, int addedInSdk) {
+ this.packageName = packageName;
+ this.addedInSdk = addedInSdk;
+ }
+
+ public CarrierAssociatedAppEntry(Parcel in) {
+ packageName = in.readString();
+ addedInSdk = in.readInt();
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString(packageName);
+ dest.writeInt(addedInSdk);
+ }
+
+ public static final Parcelable.Creator<CarrierAssociatedAppEntry> CREATOR =
+ new Parcelable.Creator<CarrierAssociatedAppEntry>() {
+ @Override
+ public CarrierAssociatedAppEntry createFromParcel(Parcel source) {
+ return new CarrierAssociatedAppEntry(source);
+ }
+
+ @Override
+ public CarrierAssociatedAppEntry[] newArray(int size) {
+ return new CarrierAssociatedAppEntry[size];
+ }
+ };
+}
diff --git a/core/java/android/os/ISystemConfig.aidl b/core/java/android/os/ISystemConfig.aidl
index d3b029854112..52f0ce1f054f 100644
--- a/core/java/android/os/ISystemConfig.aidl
+++ b/core/java/android/os/ISystemConfig.aidl
@@ -30,4 +30,9 @@ interface ISystemConfig {
* @see SystemConfigManager#getDisabledUntilUsedPreinstalledCarrierAssociatedApps
*/
Map getDisabledUntilUsedPreinstalledCarrierAssociatedApps();
+
+ /**
+ * @see SystemConfigManager#getDisabledUntilUsedPreinstalledCarrierAssociatedAppEntries
+ */
+ Map getDisabledUntilUsedPreinstalledCarrierAssociatedAppEntries();
}
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index 5d2c9d18c00c..a4077fbee892 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -228,6 +228,13 @@ public class Process {
*/
public static final int EXT_OBB_RW_GID = 1079;
+ /**
+ * GID that corresponds to the INTERNET permission.
+ * Must match the value of AID_INET.
+ * @hide
+ */
+ public static final int INET_GID = 3003;
+
/** {@hide} */
public static final int NOBODY_UID = 9999;
diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java
index 772845d4e683..8d65c92db52e 100644
--- a/core/java/android/os/StrictMode.java
+++ b/core/java/android/os/StrictMode.java
@@ -84,6 +84,8 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Deque;
import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
import java.util.concurrent.Executor;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.atomic.AtomicInteger;
@@ -189,6 +191,9 @@ public final class StrictMode {
// Only show an annoying dialog at most every 30 seconds
private static final long MIN_DIALOG_INTERVAL_MS = 30000;
+ // Only log a dropbox entry at most every 30 seconds
+ private static final long MIN_DROPBOX_INTERVAL_MS = 3000;
+
// How many Span tags (e.g. animations) to report.
private static final int MAX_SPAN_TAGS = 20;
@@ -1752,16 +1757,20 @@ public final class StrictMode {
// Not perfect, but fast and good enough for dup suppression.
Integer crashFingerprint = info.hashCode();
long lastViolationTime = 0;
- if (mLastViolationTime != null) {
- Long vtime = mLastViolationTime.get(crashFingerprint);
- if (vtime != null) {
- lastViolationTime = vtime;
+ long now = SystemClock.uptimeMillis();
+ if (sLogger == LOGCAT_LOGGER) { // Don't throttle it if there is a non-default logger
+ if (mLastViolationTime != null) {
+ Long vtime = mLastViolationTime.get(crashFingerprint);
+ if (vtime != null) {
+ lastViolationTime = vtime;
+ }
+ clampViolationTimeMap(mLastViolationTime, Math.max(MIN_LOG_INTERVAL_MS,
+ Math.max(MIN_DIALOG_INTERVAL_MS, MIN_DROPBOX_INTERVAL_MS)));
+ } else {
+ mLastViolationTime = new ArrayMap<>(1);
}
- } else {
- mLastViolationTime = new ArrayMap<>(1);
+ mLastViolationTime.put(crashFingerprint, now);
}
- long now = SystemClock.uptimeMillis();
- mLastViolationTime.put(crashFingerprint, now);
long timeSinceLastViolationMillis =
lastViolationTime == 0 ? Long.MAX_VALUE : (now - lastViolationTime);
@@ -1780,7 +1789,8 @@ public final class StrictMode {
penaltyMask |= PENALTY_DIALOG;
}
- if (info.penaltyEnabled(PENALTY_DROPBOX) && lastViolationTime == 0) {
+ if (info.penaltyEnabled(PENALTY_DROPBOX)
+ && timeSinceLastViolationMillis > MIN_DROPBOX_INTERVAL_MS) {
penaltyMask |= PENALTY_DROPBOX;
}
@@ -2215,6 +2225,23 @@ public final class StrictMode {
@UnsupportedAppUsage
private static final HashMap<Integer, Long> sLastVmViolationTime = new HashMap<>();
+ /**
+ * Clamp the given map by removing elements with timestamp older than the given retainSince.
+ */
+ private static void clampViolationTimeMap(final @NonNull Map<Integer, Long> violationTime,
+ final long retainSince) {
+ final Iterator<Map.Entry<Integer, Long>> iterator = violationTime.entrySet().iterator();
+ while (iterator.hasNext()) {
+ Map.Entry<Integer, Long> e = iterator.next();
+ if (e.getValue() < retainSince) {
+ // Remove stale entries
+ iterator.remove();
+ }
+ }
+ // Ideally we'd cap the total size of the map, though it'll involve quickselect of topK,
+ // seems not worth it (saving some space immediately but they will be obsoleted soon anyway)
+ }
+
/** @hide */
public static void onVmPolicyViolation(Violation originStack) {
onVmPolicyViolation(originStack, false);
@@ -2238,13 +2265,17 @@ public final class StrictMode {
final long now = SystemClock.uptimeMillis();
long lastViolationTime;
long timeSinceLastViolationMillis = Long.MAX_VALUE;
- synchronized (sLastVmViolationTime) {
- if (sLastVmViolationTime.containsKey(fingerprint)) {
- lastViolationTime = sLastVmViolationTime.get(fingerprint);
- timeSinceLastViolationMillis = now - lastViolationTime;
- }
- if (timeSinceLastViolationMillis > MIN_VM_INTERVAL_MS) {
- sLastVmViolationTime.put(fingerprint, now);
+ if (sLogger == LOGCAT_LOGGER) { // Don't throttle it if there is a non-default logger
+ synchronized (sLastVmViolationTime) {
+ if (sLastVmViolationTime.containsKey(fingerprint)) {
+ lastViolationTime = sLastVmViolationTime.get(fingerprint);
+ timeSinceLastViolationMillis = now - lastViolationTime;
+ }
+ if (timeSinceLastViolationMillis > MIN_VM_INTERVAL_MS) {
+ sLastVmViolationTime.put(fingerprint, now);
+ }
+ clampViolationTimeMap(sLastVmViolationTime,
+ now - Math.max(MIN_VM_INTERVAL_MS, MIN_LOG_INTERVAL_MS));
}
}
if (timeSinceLastViolationMillis <= MIN_VM_INTERVAL_MS) {
diff --git a/core/java/android/os/SystemConfigManager.java b/core/java/android/os/SystemConfigManager.java
index 3a9ce2fa85f1..12a1ffaf69c1 100644
--- a/core/java/android/os/SystemConfigManager.java
+++ b/core/java/android/os/SystemConfigManager.java
@@ -88,4 +88,29 @@ public class SystemConfigManager {
return Collections.emptyMap();
}
}
+
+ /**
+ * Returns a map that describes helper apps associated with carrier apps that, like the apps
+ * returned by {@link #getDisabledUntilUsedPreinstalledCarrierApps()}, should be disabled until
+ * the correct SIM is inserted into the device.
+ *
+ * <p>TODO(b/159069037) expose this and get rid of the other method that omits SDK version.
+ *
+ * @return A map with keys corresponding to package names returned by
+ * {@link #getDisabledUntilUsedPreinstalledCarrierApps()} and values as lists of package
+ * names of helper apps and the SDK versions when they were first added.
+ *
+ * @hide
+ */
+ @RequiresPermission(Manifest.permission.READ_CARRIER_APP_INFO)
+ public @NonNull Map<String, List<CarrierAssociatedAppEntry>>
+ getDisabledUntilUsedPreinstalledCarrierAssociatedAppEntries() {
+ try {
+ return (Map<String, List<CarrierAssociatedAppEntry>>)
+ mInterface.getDisabledUntilUsedPreinstalledCarrierAssociatedAppEntries();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Caught remote exception", e);
+ return Collections.emptyMap();
+ }
+ }
}
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index a415dc57e160..2465b0e41876 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -2699,15 +2699,12 @@ public class UserManager {
* @param name the user's name
* @param userType the type of user, such as {@link UserManager#USER_TYPE_FULL_GUEST}.
* @param flags UserInfo flags that specify user properties.
- * @return the {@link UserInfo} object for the created user,
- * or throws {@link UserOperationException} if the user could not be created
- * and calling app is targeting {@link android.os.Build.VERSION_CODES#R} or above
- * (otherwise returns {@code null}).
+ * @return the {@link UserInfo} object for the created user, or {@code null} if the user
+ * could not be created.
*
- * @throws UserOperationException if the user could not be created and the calling app is
- * targeting {@link android.os.Build.VERSION_CODES#R} or above.
- * @hide
* @see UserInfo
+ *
+ * @hide
*/
@RequiresPermission(anyOf = {Manifest.permission.MANAGE_USERS,
Manifest.permission.CREATE_USERS})
@@ -2716,8 +2713,7 @@ public class UserManager {
try {
return mService.createUserWithThrow(name, userType, flags);
} catch (ServiceSpecificException e) {
- return returnNullOrThrowUserOperationException(e,
- mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.R);
+ return null;
} catch (RemoteException re) {
throw re.rethrowFromSystemServer();
}
@@ -2743,25 +2739,19 @@ public class UserManager {
* com.android.server.pm.UserManagerService#ALLOWED_FLAGS_FOR_CREATE_USERS_PERMISSION}.
*
* @param userType the type of user, such as {@link UserManager#USER_TYPE_FULL_GUEST}.
- * @return the {@link UserInfo} object for the created user,
- * or throws {@link UserOperationException} if the user could not be created
- * and calling app is targeting {@link android.os.Build.VERSION_CODES#R} or above
- * (otherwise returns {@code null}).
- *
- * @throws UserOperationException if the user could not be created and the calling app is
- * targeting {@link android.os.Build.VERSION_CODES#R} or above.
+ * @return the {@link UserInfo} object for the created user.
*
+ * @throws UserOperationException if the user could not be created.
* @hide
*/
@RequiresPermission(anyOf = {Manifest.permission.MANAGE_USERS,
Manifest.permission.CREATE_USERS})
- public @Nullable UserInfo preCreateUser(@NonNull String userType)
+ public @NonNull UserInfo preCreateUser(@NonNull String userType)
throws UserOperationException {
try {
return mService.preCreateUserWithThrow(userType);
} catch (ServiceSpecificException e) {
- return returnNullOrThrowUserOperationException(e,
- mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.R);
+ throw UserOperationException.from(e);
} catch (RemoteException re) {
throw re.rethrowFromSystemServer();
}
@@ -2771,18 +2761,14 @@ public class UserManager {
* Creates a guest user and configures it.
* @param context an application context
* @param name the name to set for the user
- * @return the {@link UserInfo} object for the created user,
- * or throws {@link UserOperationException} if the user could not be created
- * and calling app is targeting {@link android.os.Build.VERSION_CODES#R} or above
- * (otherwise returns {@code null}).
+ * @return the {@link UserInfo} object for the created user, or {@code null} if the user
+ * could not be created.
*
- * @throws UserOperationException if the user could not be created and the calling app is
- * targeting {@link android.os.Build.VERSION_CODES#R} or above.
* @hide
*/
@RequiresPermission(anyOf = {Manifest.permission.MANAGE_USERS,
Manifest.permission.CREATE_USERS})
- public UserInfo createGuest(Context context, String name) throws UserOperationException {
+ public UserInfo createGuest(Context context, String name) {
UserInfo guest = null;
try {
guest = mService.createUserWithThrow(name, USER_TYPE_FULL_GUEST, 0);
@@ -2791,8 +2777,7 @@ public class UserManager {
Settings.Secure.SKIP_FIRST_USE_HINTS, "1", guest.id);
}
} catch (ServiceSpecificException e) {
- return returnNullOrThrowUserOperationException(e,
- context.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.R);
+ return null;
} catch (RemoteException re) {
throw re.rethrowFromSystemServer();
}
@@ -2902,26 +2887,20 @@ public class UserManager {
* @param userId new user will be a profile of this user.
* @param disallowedPackages packages that will not be installed in the profile being created.
*
- * @return the {@link UserInfo} object for the created user,
- * or throws {@link UserOperationException} if the user could not be created
- * and calling app is targeting {@link android.os.Build.VERSION_CODES#R} or above
- * (otherwise returns {@code null}).
+ * @return the {@link UserInfo} object for the created user, or {@code null} if the user could
+ * not be created.
*
- * @throws UserOperationException if the user could not be created and the calling app is
- * targeting {@link android.os.Build.VERSION_CODES#R} or above.
* @hide
*/
@RequiresPermission(anyOf = {Manifest.permission.MANAGE_USERS,
Manifest.permission.CREATE_USERS})
public UserInfo createProfileForUser(String name, @NonNull String userType,
- @UserInfoFlag int flags, @UserIdInt int userId, String[] disallowedPackages)
- throws UserOperationException {
+ @UserInfoFlag int flags, @UserIdInt int userId, String[] disallowedPackages) {
try {
return mService.createProfileForUserWithThrow(name, userType, flags, userId,
disallowedPackages);
} catch (ServiceSpecificException e) {
- return returnNullOrThrowUserOperationException(e,
- mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.R);
+ return null;
} catch (RemoteException re) {
throw re.rethrowFromSystemServer();
}
@@ -2938,13 +2917,12 @@ public class UserManager {
Manifest.permission.CREATE_USERS})
public UserInfo createProfileForUserEvenWhenDisallowed(String name,
@NonNull String userType, @UserInfoFlag int flags, @UserIdInt int userId,
- String[] disallowedPackages) throws UserOperationException {
+ String[] disallowedPackages) {
try {
return mService.createProfileForUserEvenWhenDisallowedWithThrow(name, userType, flags,
userId, disallowedPackages);
} catch (ServiceSpecificException e) {
- return returnNullOrThrowUserOperationException(e,
- mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.R);
+ return null;
} catch (RemoteException re) {
throw re.rethrowFromSystemServer();
}
@@ -2955,18 +2933,14 @@ public class UserManager {
* restrictions and adds shared accounts.
*
* @param name profile's name
- * @return the {@link UserInfo} object for the created user,
- * or throws {@link UserOperationException} if the user could not be created
- * and calling app is targeting {@link android.os.Build.VERSION_CODES#R} or above
- * (otherwise returns {@code null}).
+ * @return the {@link UserInfo} object for the created user, or {@code null} if the user
+ * could not be created.
*
- * @throws UserOperationException if the user could not be created and the calling app is
- * targeting {@link android.os.Build.VERSION_CODES#R} or above.
* @hide
*/
@RequiresPermission(anyOf = {Manifest.permission.MANAGE_USERS,
Manifest.permission.CREATE_USERS})
- public UserInfo createRestrictedProfile(String name) throws UserOperationException {
+ public UserInfo createRestrictedProfile(String name) {
try {
UserHandle parentUserHandle = Process.myUserHandle();
UserInfo user = mService.createRestrictedProfileWithThrow(name,
@@ -2977,8 +2951,7 @@ public class UserManager {
}
return user;
} catch (ServiceSpecificException e) {
- return returnNullOrThrowUserOperationException(e,
- mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.R);
+ return null;
} catch (RemoteException re) {
throw re.rethrowFromSystemServer();
}
@@ -4009,15 +3982,15 @@ public class UserManager {
* Sets the user's photo.
* @param userId the user for whom to change the photo.
* @param icon the bitmap to set as the photo.
+ *
* @hide
*/
@RequiresPermission(android.Manifest.permission.MANAGE_USERS)
- public void setUserIcon(@UserIdInt int userId, @NonNull Bitmap icon)
- throws UserOperationException {
+ public void setUserIcon(@UserIdInt int userId, @NonNull Bitmap icon) {
try {
mService.setUserIcon(userId, icon);
} catch (ServiceSpecificException e) {
- throw UserOperationException.from(e);
+ return;
} catch (RemoteException re) {
throw re.rethrowFromSystemServer();
}
@@ -4027,6 +4000,10 @@ public class UserManager {
* Sets the context user's photo.
*
* @param icon the bitmap to set as the photo.
+ *
+ * @throws UserOperationException according to the function signature, but may not actually
+ * throw it in practice. Catch RuntimeException instead.
+ *
* @hide
*/
@SystemApi
diff --git a/core/java/android/os/Users.md b/core/java/android/os/Users.md
index 3bbbe5452fd3..b019b0dc178b 100644
--- a/core/java/android/os/Users.md
+++ b/core/java/android/os/Users.md
@@ -18,54 +18,80 @@
## Concepts
-### User
+### Users and profiles
-A user of a device e.g. usually a human being. Each user has its own home screen.
+#### User
-#### User Profile
+A user is a representation of a person using a device, with their own distinct application data
+and some unique settings. Throughout this document, the word 'user' will be used in this technical
+sense, i.e. for this virtual environment, whereas the word 'person' will be used to denote an actual
+human interacting with the device.
-A user can have multiple profiles. E.g. one for the private life and one for work. Each profile
-has a different set of apps and accounts but they share one home screen. All profiles of a
-profile group can be active at the same time.
-
-Each profile has a separate [`userId`](#int-userid). Unless needed user profiles are treated as
-completely separate users.
+Each user has a separate [`userId`](#int-userid).
#### Profile Group
-All user profiles that share a home screen. You can list the profiles of a user via
-`UserManager#getEnabledProfiles` (you usually don't deal with disabled profiles)
+Often, there is a 1-to-1 mapping of people who use a device to 'users'; e.g. there may be two users
+on a device - the owner and a guest, each with their own separate home screen.
-#### Foreground user vs background user
+However, Android also supports multiple profiles for a single person, e.g. one for their private
+life and one for work, both sharing a single home screen.
+Each profile in a profile group is a distinct user, with a unique [`userId`](#int-userid), and have
+a different set of apps and accounts,
+but they share a single UI, single launcher, and single wallpaper.
+All profiles of a profile group can be active at the same time.
-Only a single user profile group can be in the foreground. This is the user profile the user
-currently interacts with.
+You can list the profiles of a user via `UserManager#getEnabledProfiles` (you usually don't deal
+with disabled profiles)
-#### Parent user (profile)
+#### Parent user
-The main profile of a profile group, usually the personal (as opposed to work) profile. Get this via
-`UserManager#getProfileParent` (returns `null` if the user does not have profiles)
+The main user of a profile group, to which the other profiles of the group 'belong'.
+This is usually the personal (as opposed to work) profile. Get this via
+`UserManager#getProfileParent` (returns `null` if the user does not have profiles).
-#### Managed user (profile)
+#### Profile (Managed profile)
-The other profiles of a profile group. The name comes from the fact that these profiles are usually
+A profile of the parent user, i.e. a profile belonging to the same profile group as a parent user,
+with whom they share a single home screen.
+Currently, the only type of profile supported in AOSP is a 'Managed Profile'.
+The name comes from the fact that these profiles are usually
managed by a device policy controller app. You can create a managed profile from within the device
policy controller app on your phone.
+Note that, as a member of the profile group, the parent user may sometimes also be considered a
+'profile', but generally speaking, the word 'profile' denotes a user that is subordinate to a
+parent.
+
+#### Foreground user vs background user
+
+Only a single user can be in the foreground.
+This is the user with whom the person using the device is currently interacting, or, in the case
+of profiles, the parent profile of this user.
+All other running users are background users.
+Some users may not be running at all, neither in the foreground nor the background.
+
#### Account
-An account of a user profile with a (usually internet based) service. E.g. aname@gmail.com or
-aname@yahoo.com. Each profile can have multiple accounts. A profile does not have to have a
+An account of a user with a (usually internet based) service. E.g. aname@gmail.com or
+aname@yahoo.com. Each user can have multiple accounts. A user does not have to have a
account.
+#### System User
+
+The user with [`userId`](#int-userid) 0 denotes the system user, which is always required to be
+running.
+
+On most devices, the system user is also used by the primary person using the device; however,
+on certain types of devices, the system user may be a stand-alone user, not intended for direct
+human interaction.
+
## Data types
### int userId
-... usually marked as `@UserIdInt`
-
-The id of a user profile. List all users via `adb shell dumpsys user`. There is no data type for a
-user, all you can do is using the user id of the parent profile as a proxy for the user.
+The id of a user. List all users via `adb shell dumpsys user`.
+In code, these are sometimes marked as `@UserIdInt`.
### int uid
@@ -97,10 +123,10 @@ mechanism should be access controlled by permissions.
A system service should deal with users being started and stopped by overriding
`SystemService.onSwitchUser` and `SystemService.onStopUser`.
-If users profiles become inactive the system should stop all apps of this profile from interacting
+If a user become inactive the system should stop all apps of this user from interacting
with other apps or the system.
-Another important lifecycle event is `onUnlockUser`. Only for unlocked user profiles you can access
+Another important lifecycle event is `onUnlockUser`. Only for an unlocked user can you access
all data, e.g. which packages are installed.
You only want to deal with user profiles that
diff --git a/core/java/android/os/incremental/IIncrementalService.aidl b/core/java/android/os/incremental/IIncrementalService.aidl
index 220ce22ded5c..61e6a05fce37 100644
--- a/core/java/android/os/incremental/IIncrementalService.aidl
+++ b/core/java/android/os/incremental/IIncrementalService.aidl
@@ -111,6 +111,11 @@ interface IIncrementalService {
void deleteStorage(int storageId);
/**
+ * Permanently disable readlogs reporting for a storage given its ID.
+ */
+ void disableReadLogs(int storageId);
+
+ /**
* Setting up native library directories and extract native libs onto a storage if needed.
*/
boolean configureNativeBinaries(int storageId, in @utf8InCpp String apkFullPath, in @utf8InCpp String libDirRelativePath, in @utf8InCpp String abi, boolean extractNativeLibs);
diff --git a/core/java/android/os/incremental/IncrementalFileStorages.java b/core/java/android/os/incremental/IncrementalFileStorages.java
index 863d86ef88c9..31ccf95ba16f 100644
--- a/core/java/android/os/incremental/IncrementalFileStorages.java
+++ b/core/java/android/os/incremental/IncrementalFileStorages.java
@@ -153,6 +153,13 @@ public final class IncrementalFileStorages {
}
/**
+ * Permanently disables readlogs.
+ */
+ public void disableReadLogs() {
+ mDefaultStorage.disableReadLogs();
+ }
+
+ /**
* Resets the states and unbinds storage instances for an installation session.
* TODO(b/136132412): make sure unnecessary binds are removed but useful storages are kept
*/
diff --git a/core/java/android/os/incremental/IncrementalStorage.java b/core/java/android/os/incremental/IncrementalStorage.java
index 6200a38fe13c..ca6114f29b9c 100644
--- a/core/java/android/os/incremental/IncrementalStorage.java
+++ b/core/java/android/os/incremental/IncrementalStorage.java
@@ -418,6 +418,17 @@ public final class IncrementalStorage {
private static final int INCFS_MAX_ADD_DATA_SIZE = 128;
/**
+ * Permanently disable readlogs collection.
+ */
+ public void disableReadLogs() {
+ try {
+ mService.disableReadLogs(mId);
+ } catch (RemoteException e) {
+ e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Deserialize and validate v4 signature bytes.
*/
private static void validateV4Signature(@Nullable byte[] v4signatureBytes)
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index e8806a03d00e..0abf8ae352af 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -16,9 +16,11 @@
package android.os.storage;
+import static android.Manifest.permission.MANAGE_EXTERNAL_STORAGE;
import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
import static android.app.AppOpsManager.OP_LEGACY_STORAGE;
+import static android.app.AppOpsManager.OP_MANAGE_EXTERNAL_STORAGE;
import static android.app.AppOpsManager.OP_READ_EXTERNAL_STORAGE;
import static android.app.AppOpsManager.OP_READ_MEDIA_AUDIO;
import static android.app.AppOpsManager.OP_READ_MEDIA_IMAGES;
@@ -1853,7 +1855,7 @@ public class StorageManager {
/** {@hide} */
public boolean checkPermissionReadAudio(boolean enforce,
int pid, int uid, String packageName, @Nullable String featureId) {
- if (!checkPermissionAndAppOp(enforce, pid, uid, packageName, featureId,
+ if (!checkExternalStoragePermissionAndAppOp(enforce, pid, uid, packageName, featureId,
READ_EXTERNAL_STORAGE, OP_READ_EXTERNAL_STORAGE)) {
return false;
}
@@ -1864,7 +1866,7 @@ public class StorageManager {
/** {@hide} */
public boolean checkPermissionWriteAudio(boolean enforce,
int pid, int uid, String packageName, @Nullable String featureId) {
- if (!checkPermissionAndAppOp(enforce, pid, uid, packageName, featureId,
+ if (!checkExternalStoragePermissionAndAppOp(enforce, pid, uid, packageName, featureId,
WRITE_EXTERNAL_STORAGE, OP_WRITE_EXTERNAL_STORAGE)) {
return false;
}
@@ -1875,7 +1877,7 @@ public class StorageManager {
/** {@hide} */
public boolean checkPermissionReadVideo(boolean enforce,
int pid, int uid, String packageName, @Nullable String featureId) {
- if (!checkPermissionAndAppOp(enforce, pid, uid, packageName, featureId,
+ if (!checkExternalStoragePermissionAndAppOp(enforce, pid, uid, packageName, featureId,
READ_EXTERNAL_STORAGE, OP_READ_EXTERNAL_STORAGE)) {
return false;
}
@@ -1886,7 +1888,7 @@ public class StorageManager {
/** {@hide} */
public boolean checkPermissionWriteVideo(boolean enforce,
int pid, int uid, String packageName, @Nullable String featureId) {
- if (!checkPermissionAndAppOp(enforce, pid, uid, packageName, featureId,
+ if (!checkExternalStoragePermissionAndAppOp(enforce, pid, uid, packageName, featureId,
WRITE_EXTERNAL_STORAGE, OP_WRITE_EXTERNAL_STORAGE)) {
return false;
}
@@ -1897,7 +1899,7 @@ public class StorageManager {
/** {@hide} */
public boolean checkPermissionReadImages(boolean enforce,
int pid, int uid, String packageName, @Nullable String featureId) {
- if (!checkPermissionAndAppOp(enforce, pid, uid, packageName, featureId,
+ if (!checkExternalStoragePermissionAndAppOp(enforce, pid, uid, packageName, featureId,
READ_EXTERNAL_STORAGE, OP_READ_EXTERNAL_STORAGE)) {
return false;
}
@@ -1908,7 +1910,7 @@ public class StorageManager {
/** {@hide} */
public boolean checkPermissionWriteImages(boolean enforce,
int pid, int uid, String packageName, @Nullable String featureId) {
- if (!checkPermissionAndAppOp(enforce, pid, uid, packageName, featureId,
+ if (!checkExternalStoragePermissionAndAppOp(enforce, pid, uid, packageName, featureId,
WRITE_EXTERNAL_STORAGE, OP_WRITE_EXTERNAL_STORAGE)) {
return false;
}
@@ -1916,6 +1918,24 @@ public class StorageManager {
OP_WRITE_MEDIA_IMAGES);
}
+ private boolean checkExternalStoragePermissionAndAppOp(boolean enforce,
+ int pid, int uid, String packageName, @Nullable String featureId, String permission,
+ int op) {
+ // First check if app has MANAGE_EXTERNAL_STORAGE.
+ final int mode = mAppOps.noteOpNoThrow(OP_MANAGE_EXTERNAL_STORAGE, uid, packageName,
+ featureId, null);
+ if (mode == AppOpsManager.MODE_ALLOWED) {
+ return true;
+ }
+ if (mode == AppOpsManager.MODE_DEFAULT && mContext.checkPermission(
+ MANAGE_EXTERNAL_STORAGE, pid, uid) == PERMISSION_GRANTED) {
+ return true;
+ }
+ // If app doesn't have MANAGE_EXTERNAL_STORAGE, then check if it has requested granular
+ // permission.
+ return checkPermissionAndAppOp(enforce, pid, uid, packageName, featureId, permission, op);
+ }
+
/** {@hide} */
@VisibleForTesting
public @NonNull ParcelFileDescriptor openProxyFileDescriptor(
diff --git a/core/java/android/os/strictmode/Violation.java b/core/java/android/os/strictmode/Violation.java
index 31c7d584fd65..0edb78a64243 100644
--- a/core/java/android/os/strictmode/Violation.java
+++ b/core/java/android/os/strictmode/Violation.java
@@ -18,7 +18,58 @@ package android.os.strictmode;
/** Root class for all StrictMode violations. */
public abstract class Violation extends Throwable {
+ private int mHashCode;
+ private boolean mHashCodeValid;
+
Violation(String message) {
super(message);
}
+
+ @Override
+ public int hashCode() {
+ synchronized (this) {
+ if (mHashCodeValid) {
+ return mHashCode;
+ }
+ final String message = getMessage();
+ final Throwable cause = getCause();
+ int hashCode = message != null ? message.hashCode() : getClass().hashCode();
+ hashCode = hashCode * 37 + calcStackTraceHashCode(getStackTrace());
+ hashCode = hashCode * 37 + (cause != null ? cause.toString().hashCode() : 0);
+ mHashCodeValid = true;
+ return mHashCode = hashCode;
+ }
+ }
+
+ @Override
+ public synchronized Throwable initCause(Throwable cause) {
+ mHashCodeValid = false;
+ return super.initCause(cause);
+ }
+
+ @Override
+ public void setStackTrace(StackTraceElement[] stackTrace) {
+ super.setStackTrace(stackTrace);
+ synchronized (this) {
+ mHashCodeValid = false;
+ }
+ }
+
+ @Override
+ public synchronized Throwable fillInStackTrace() {
+ mHashCodeValid = false;
+ return super.fillInStackTrace();
+ }
+
+ private static int calcStackTraceHashCode(final StackTraceElement[] stackTrace) {
+ int hashCode = 17;
+ if (stackTrace != null) {
+ for (int i = 0; i < stackTrace.length; i++) {
+ if (stackTrace[i] != null) {
+ hashCode = hashCode * 37 + stackTrace[i].hashCode();
+ }
+ }
+ }
+ return hashCode;
+ }
}
diff --git a/core/java/android/permission/Permissions.md b/core/java/android/permission/Permissions.md
index 2bf08e2ff2d4..1ef3ad211cee 100644
--- a/core/java/android/permission/Permissions.md
+++ b/core/java/android/permission/Permissions.md
@@ -706,9 +706,9 @@ App-op permissions are user-switchable permissions that are not runtime permissi
be used for permissions that are really only meant to be ever granted to a very small amount of
apps. Traditionally granting these permissions is intentionally very heavy weight so that the
user really needs to understand the use case. For example one use case is the
-`INTERACT_ACROSS_PROFILES` permission that allows apps of different
-[user profiles](../os/Users.md#user-profile) to interact. Of course this is breaking a very basic
-security container and hence should only every be granted with a lot of care.
+`INTERACT_ACROSS_PROFILES` permission that allows apps of different users within the same
+[profile group](../os/Users.md#profile-group) to interact. Of course this is breaking a very basic
+security container and hence should only ever be granted with a lot of care.
**Warning:** Most app-op permissions follow this logic, but most of them also have exceptions
and special behavior. Hence this section is a guideline, not a rule.
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 4f0a9728fcf8..64d9c9dcc6e0 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -1898,6 +1898,15 @@ public final class Settings {
"android.settings.ACTION_DEVICE_CONTROLS_SETTINGS";
/**
+ * Activity Action: Show media control settings
+ *
+ * @hide
+ */
+ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+ public static final String ACTION_MEDIA_CONTROLS_SETTINGS =
+ "android.settings.ACTION_MEDIA_CONTROLS_SETTINGS";
+
+ /**
* Activity Action: Show a dialog with disabled by policy message.
* <p> If an user action is disabled by policy, this dialog can be triggered to let
* the user know about this.
@@ -1972,6 +1981,10 @@ public final class Settings {
* Input: Nothing.
* <p>
* Output: Nothing.
+ * <p class="note">
+ * In some cases, a matching Activity may not exist, so ensure you
+ * safeguard against this.
+
*/
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
public static final String ACTION_WEBVIEW_SETTINGS = "android.settings.WEBVIEW_SETTINGS";
@@ -8517,14 +8530,15 @@ public final class Settings {
public static final int VR_DISPLAY_MODE_OFF = 1;
/**
- * Whether CarrierAppUtils#disableCarrierAppsUntilPrivileged has been executed at least
- * once.
+ * The latest SDK version that CarrierAppUtils#disableCarrierAppsUntilPrivileged has been
+ * executed for.
*
* <p>This is used to ensure that we only take one pass which will disable apps that are not
* privileged (if any). From then on, we only want to enable apps (when a matching SIM is
* inserted), to avoid disabling an app that the user might actively be using.
*
- * <p>Will be set to 1 once executed.
+ * <p>Will be set to {@link android.os.Build.VERSION#SDK_INT} once executed. Note that older
+ * SDK versions prior to R set 1 for this value.
*
* @hide
*/
@@ -8906,6 +8920,15 @@ public final class Settings {
public static final String PEOPLE_STRIP = "people_strip";
/**
+ * Whether or not to enable media resumption
+ * When enabled, media controls in quick settings will populate on boot and persist if
+ * resumable via a MediaBrowserService.
+ * @see Settings.Global#SHOW_MEDIA_ON_QUICK_SETTINGS
+ * @hide
+ */
+ public static final String MEDIA_CONTROLS_RESUME = "qs_media_resumption";
+
+ /**
* Controls if window magnification is enabled.
* @hide
*/
@@ -11986,7 +12009,7 @@ public final class Settings {
* @see #ENABLE_RESTRICTED_BUCKET
* @hide
*/
- public static final int DEFAULT_ENABLE_RESTRICTED_BUCKET = 1;
+ public static final int DEFAULT_ENABLE_RESTRICTED_BUCKET = 0;
/**
* Whether or not app auto restriction is enabled. When it is enabled, settings app will
diff --git a/core/java/android/service/autofill/InlineSuggestionRenderService.java b/core/java/android/service/autofill/InlineSuggestionRenderService.java
index 3ea443bab3f8..8790fb2299f5 100644
--- a/core/java/android/service/autofill/InlineSuggestionRenderService.java
+++ b/core/java/android/service/autofill/InlineSuggestionRenderService.java
@@ -64,7 +64,7 @@ public abstract class InlineSuggestionRenderService extends Service {
public static final String SERVICE_INTERFACE =
"android.service.autofill.InlineSuggestionRenderService";
- private final Handler mHandler = new Handler(Looper.getMainLooper(), null, true);
+ private final Handler mMainHandler = new Handler(Looper.getMainLooper(), null, true);
private IInlineSuggestionUiCallback mCallback;
@@ -192,15 +192,22 @@ public abstract class InlineSuggestionRenderService extends Service {
}
return true;
});
-
- try {
- InlineSuggestionUiImpl uiImpl = new InlineSuggestionUiImpl(host, mHandler);
- mActiveInlineSuggestions.put(uiImpl, true);
- callback.onContent(new InlineSuggestionUiWrapper(uiImpl), host.getSurfacePackage(),
- measuredSize.getWidth(), measuredSize.getHeight());
- } catch (RemoteException e) {
- Log.w(TAG, "RemoteException calling onContent()");
- }
+ final InlineSuggestionUiImpl uiImpl = new InlineSuggestionUiImpl(host, mMainHandler);
+ mActiveInlineSuggestions.put(uiImpl, true);
+
+ // We post the callback invocation to the end of the main thread handler queue, to make
+ // sure the callback happens after the views are drawn. This is needed because calling
+ // {@link SurfaceControlViewHost#setView()} will post a task to the main thread
+ // to draw the view asynchronously.
+ mMainHandler.post(() -> {
+ try {
+ callback.onContent(new InlineSuggestionUiWrapper(uiImpl),
+ host.getSurfacePackage(),
+ measuredSize.getWidth(), measuredSize.getHeight());
+ } catch (RemoteException e) {
+ Log.w(TAG, "RemoteException calling onContent()");
+ }
+ });
} finally {
updateDisplay(Display.DEFAULT_DISPLAY);
}
@@ -305,7 +312,7 @@ public abstract class InlineSuggestionRenderService extends Service {
public void renderSuggestion(@NonNull IInlineSuggestionUiCallback callback,
@NonNull InlinePresentation presentation, int width, int height,
@Nullable IBinder hostInputToken, int displayId) {
- mHandler.sendMessage(
+ mMainHandler.sendMessage(
obtainMessage(InlineSuggestionRenderService::handleRenderSuggestion,
InlineSuggestionRenderService.this, callback, presentation,
width, height, hostInputToken, displayId));
@@ -313,7 +320,7 @@ public abstract class InlineSuggestionRenderService extends Service {
@Override
public void getInlineSuggestionsRendererInfo(@NonNull RemoteCallback callback) {
- mHandler.sendMessage(obtainMessage(
+ mMainHandler.sendMessage(obtainMessage(
InlineSuggestionRenderService::handleGetInlineSuggestionsRendererInfo,
InlineSuggestionRenderService.this, callback));
}
diff --git a/core/java/android/service/autofill/augmented/AugmentedAutofillService.java b/core/java/android/service/autofill/augmented/AugmentedAutofillService.java
index c2234bad3803..95cc64ae8aab 100644
--- a/core/java/android/service/autofill/augmented/AugmentedAutofillService.java
+++ b/core/java/android/service/autofill/augmented/AugmentedAutofillService.java
@@ -564,9 +564,9 @@ public abstract class AugmentedAutofillService extends Service {
}
void reportResult(@Nullable List<Dataset> inlineSuggestionsData,
- @Nullable Bundle clientState) {
+ @Nullable Bundle clientState, boolean showingFillWindow) {
try {
- mCallback.onSuccess(inlineSuggestionsData, clientState);
+ mCallback.onSuccess(inlineSuggestionsData, clientState, showingFillWindow);
} catch (RemoteException e) {
Log.e(TAG, "Error calling back with the inline suggestions data: " + e);
}
diff --git a/core/java/android/service/autofill/augmented/FillCallback.java b/core/java/android/service/autofill/augmented/FillCallback.java
index 8ba5c173890c..fc3baf1c9836 100644
--- a/core/java/android/service/autofill/augmented/FillCallback.java
+++ b/core/java/android/service/autofill/augmented/FillCallback.java
@@ -56,23 +56,24 @@ public final class FillCallback {
if (response == null) {
mProxy.logEvent(AutofillProxy.REPORT_EVENT_NO_RESPONSE);
- mProxy.reportResult(/* inlineSuggestionsData */ null, /* clientState */ null);
+ mProxy.reportResult(/* inlineSuggestionsData */ null, /* clientState */
+ null, /* showingFillWindow */ false);
return;
}
- List<Dataset> inlineSuggestions = response.getInlineSuggestions();
- Bundle clientState = response.getClientState();
- // We need to report result regardless of whether inline suggestions are returned or not.
- mProxy.reportResult(inlineSuggestions, clientState);
+ final List<Dataset> inlineSuggestions = response.getInlineSuggestions();
+ final Bundle clientState = response.getClientState();
+ final FillWindow fillWindow = response.getFillWindow();
+ boolean showingFillWindow = false;
if (inlineSuggestions != null && !inlineSuggestions.isEmpty()) {
mProxy.logEvent(AutofillProxy.REPORT_EVENT_INLINE_RESPONSE);
- return;
- }
-
- final FillWindow fillWindow = response.getFillWindow();
- if (fillWindow != null) {
+ } else if (fillWindow != null) {
fillWindow.show();
+ showingFillWindow = true;
}
+ // We need to report result regardless of whether inline suggestions are returned or not.
+ mProxy.reportResult(inlineSuggestions, clientState, showingFillWindow);
+
// TODO(b/123099468): must notify the server so it can update the session state to avoid
// showing conflicting UIs (for example, if a new request is made to the main autofill
// service and it now wants to show something).
diff --git a/core/java/android/service/autofill/augmented/FillWindow.java b/core/java/android/service/autofill/augmented/FillWindow.java
index 077df6cf16ef..8e866466e8df 100644
--- a/core/java/android/service/autofill/augmented/FillWindow.java
+++ b/core/java/android/service/autofill/augmented/FillWindow.java
@@ -208,12 +208,18 @@ public final class FillWindow implements AutoCloseable {
if (sDebug) Log.d(TAG, "handleShow()");
synchronized (mLock) {
if (mWm != null && mFillView != null) {
- p.flags |= WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
- if (!mShowing) {
- mWm.addView(mFillView, p);
- mShowing = true;
- } else {
- mWm.updateViewLayout(mFillView, p);
+ try {
+ p.flags |= WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
+ if (!mShowing) {
+ mWm.addView(mFillView, p);
+ mShowing = true;
+ } else {
+ mWm.updateViewLayout(mFillView, p);
+ }
+ } catch (WindowManager.BadTokenException e) {
+ if (sDebug) Log.d(TAG, "Filed with token " + p.token + " gone.");
+ } catch (IllegalStateException e) {
+ if (sDebug) Log.d(TAG, "Exception showing window.");
}
}
}
@@ -223,8 +229,12 @@ public final class FillWindow implements AutoCloseable {
if (sDebug) Log.d(TAG, "handleHide()");
synchronized (mLock) {
if (mWm != null && mFillView != null && mShowing) {
- mWm.removeView(mFillView);
- mShowing = false;
+ try {
+ mWm.removeView(mFillView);
+ mShowing = false;
+ } catch (IllegalStateException e) {
+ if (sDebug) Log.d(TAG, "Exception hiding window.");
+ }
}
}
}
diff --git a/core/java/android/service/autofill/augmented/IFillCallback.aidl b/core/java/android/service/autofill/augmented/IFillCallback.aidl
index 609e382e2b96..4dfdd4db27e5 100644
--- a/core/java/android/service/autofill/augmented/IFillCallback.aidl
+++ b/core/java/android/service/autofill/augmented/IFillCallback.aidl
@@ -30,7 +30,9 @@ import java.util.List;
*/
interface IFillCallback {
void onCancellable(in ICancellationSignal cancellation);
- void onSuccess(in @nullable List<Dataset> inlineSuggestionsData, in @nullable Bundle clientState);
+ void onSuccess(in @nullable List<Dataset> inlineSuggestionsData,
+ in @nullable Bundle clientState,
+ boolean showingFillWindow);
boolean isCompleted();
void cancel();
}
diff --git a/core/java/android/service/controls/Control.java b/core/java/android/service/controls/Control.java
index 8383072a48e3..2868f1bf3547 100644
--- a/core/java/android/service/controls/Control.java
+++ b/core/java/android/service/controls/Control.java
@@ -789,6 +789,13 @@ public final class Control implements Parcelable {
}
/**
+ * Set the {@link ControlTemplate} to define the primary user interaction
+ *
+ * Devices may support a variety of user interactions, and all interactions cannot be
+ * represented with a single {@link ControlTemplate}. Therefore, the selected template
+ * should be most closely aligned with what the expected primary device action will be.
+ * Any secondary interactions can be done via the {@link #setAppIntent(PendingIntent)}.
+ *
* @param controlTemplate instance of {@link ControlTemplate}, that defines how the
* {@link Control} will behave and what interactions are
* available to the user
diff --git a/core/java/android/service/controls/ControlsProviderService.java b/core/java/android/service/controls/ControlsProviderService.java
index 4e5aa0018b61..6bd376a19fc5 100644
--- a/core/java/android/service/controls/ControlsProviderService.java
+++ b/core/java/android/service/controls/ControlsProviderService.java
@@ -296,6 +296,10 @@ public abstract class ControlsProviderService extends Service {
/**
* Request SystemUI to prompt the user to add a control to favorites.
+ * <br>
+ * SystemUI may not honor this request in some cases, for example if the requested
+ * {@link Control} is already a favorite, or the requesting package is not currently in the
+ * foreground.
*
* @param context A context
* @param componentName Component name of the {@link ControlsProviderService}
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index f944dd78dc3d..0d420c5936ae 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -1184,7 +1184,8 @@ public abstract class WallpaperService extends Service {
// may have been destroyed so now we need to make
// sure it is re-created.
doOffsetsChanged(false);
- updateSurface(false, false, false);
+ // force relayout to get new surface
+ updateSurface(true, false, false);
}
onVisibilityChanged(visible);
}
diff --git a/core/java/android/telephony/PhoneStateListener.java b/core/java/android/telephony/PhoneStateListener.java
index ef21900dc3e3..4adcd6948f85 100644
--- a/core/java/android/telephony/PhoneStateListener.java
+++ b/core/java/android/telephony/PhoneStateListener.java
@@ -219,6 +219,9 @@ public class PhoneStateListener {
/**
* Listen for changes to observed cell info.
*
+ * Listening to this event requires the {@link Manifest.permission#ACCESS_FINE_LOCATION}
+ * permission.
+ *
* @see #onCellInfoChanged
*/
public static final int LISTEN_CELL_INFO = 0x00000400;
@@ -461,6 +464,9 @@ public class PhoneStateListener {
* <p>Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE} or
* the calling app has carrier privileges (see {@link TelephonyManager#hasCarrierPrivileges}).
*
+ * <p>Also requires the {@link Manifest.permission#ACCESS_FINE_LOCATION} permission, regardless
+ * of whether the calling app has carrier privileges.
+ *
* @see #onRegistrationFailed
*/
@RequiresPermission(Manifest.permission.READ_PRECISE_PHONE_STATE)
@@ -472,6 +478,9 @@ public class PhoneStateListener {
* <p>Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE} or
* the calling app has carrier privileges (see {@link TelephonyManager#hasCarrierPrivileges}).
*
+ * <p>Also requires the {@link Manifest.permission#ACCESS_FINE_LOCATION} permission, regardless
+ * of whether the calling app has carrier privileges.
+ *
* @see #onBarringInfoChanged
*/
@RequiresPermission(Manifest.permission.READ_PRECISE_PHONE_STATE)
@@ -569,6 +578,11 @@ public class PhoneStateListener {
* subId. Otherwise, this callback applies to
* {@link SubscriptionManager#getDefaultSubscriptionId()}.
*
+ * The instance of {@link ServiceState} passed as an argument here will have various levels of
+ * location information stripped from it depending on the location permissions that your app
+ * holds. Only apps holding the {@link Manifest.permission#ACCESS_FINE_LOCATION} permission will
+ * receive all the information in {@link ServiceState}.
+ *
* @see ServiceState#STATE_EMERGENCY_ONLY
* @see ServiceState#STATE_IN_SERVICE
* @see ServiceState#STATE_OUT_OF_SERVICE
diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java
index 8acf5fa8bdfe..537498c44d5e 100644
--- a/core/java/android/util/FeatureFlagUtils.java
+++ b/core/java/android/util/FeatureFlagUtils.java
@@ -67,7 +67,6 @@ public class FeatureFlagUtils {
DEFAULT_FLAGS.put(SETTINGS_DO_NOT_RESTORE_PRESERVED, "true");
DEFAULT_FLAGS.put("settings_tether_all_in_one", "false");
- DEFAULT_FLAGS.put("settings_contextual_home2", "true");
}
/**
diff --git a/core/java/android/util/apk/ApkSigningBlockUtils.java b/core/java/android/util/apk/ApkSigningBlockUtils.java
index 2a4b65d23e64..6efe95cb9e92 100644
--- a/core/java/android/util/apk/ApkSigningBlockUtils.java
+++ b/core/java/android/util/apk/ApkSigningBlockUtils.java
@@ -420,6 +420,7 @@ final class ApkSigningBlockUtils {
static final int CONTENT_DIGEST_CHUNKED_SHA256 = 1;
static final int CONTENT_DIGEST_CHUNKED_SHA512 = 2;
static final int CONTENT_DIGEST_VERITY_CHUNKED_SHA256 = 3;
+ static final int CONTENT_DIGEST_SHA256 = 4;
private static final int[] V4_CONTENT_DIGEST_ALGORITHMS =
{CONTENT_DIGEST_CHUNKED_SHA512, CONTENT_DIGEST_VERITY_CHUNKED_SHA256,
diff --git a/core/java/android/util/apk/SourceStampVerifier.java b/core/java/android/util/apk/SourceStampVerifier.java
index a7ae32d1baa2..5fc242353d51 100644
--- a/core/java/android/util/apk/SourceStampVerifier.java
+++ b/core/java/android/util/apk/SourceStampVerifier.java
@@ -16,6 +16,7 @@
package android.util.apk;
+import static android.util.apk.ApkSigningBlockUtils.CONTENT_DIGEST_SHA256;
import static android.util.apk.ApkSigningBlockUtils.compareSignatureAlgorithm;
import static android.util.apk.ApkSigningBlockUtils.getLengthPrefixedSlice;
import static android.util.apk.ApkSigningBlockUtils.getSignatureAlgorithmContentDigestAlgorithm;
@@ -27,12 +28,10 @@ import android.util.Pair;
import android.util.Slog;
import android.util.jar.StrictJarFile;
-import libcore.io.IoUtils;
+import libcore.io.Streams;
import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
import java.io.IOException;
-import java.io.InputStream;
import java.io.RandomAccessFile;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
@@ -49,11 +48,13 @@ import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.spec.AlgorithmParameterSpec;
+import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.stream.Collectors;
+import java.util.jar.JarFile;
import java.util.zip.ZipEntry;
/**
@@ -74,7 +75,11 @@ public abstract class SourceStampVerifier {
private static final int APK_SIGNATURE_SCHEME_V2_BLOCK_ID = 0x7109871a;
private static final int APK_SIGNATURE_SCHEME_V3_BLOCK_ID = 0xf05368c0;
- private static final int SOURCE_STAMP_BLOCK_ID = 0x2b09189e;
+ private static final int SOURCE_STAMP_BLOCK_ID = 0x6dff800d;
+
+ private static final int VERSION_JAR_SIGNATURE_SCHEME = 1;
+ private static final int VERSION_APK_SIGNATURE_SCHEME_V2 = 2;
+ private static final int VERSION_APK_SIGNATURE_SCHEME_V3 = 3;
/** Name of the SourceStamp certificate hash ZIP entry in APKs. */
private static final String SOURCE_STAMP_CERTIFICATE_HASH_ZIP_ENTRY_NAME = "stamp-cert-sha256";
@@ -115,7 +120,8 @@ public abstract class SourceStampVerifier {
// SourceStamp present.
return SourceStampVerificationResult.notPresent();
}
- return verify(apk, sourceStampCertificateDigest);
+ byte[] manifestBytes = getManifestBytes(apkJar);
+ return verify(apk, sourceStampCertificateDigest, manifestBytes);
} catch (IOException e) {
// Any exception in reading the APK returns a non-present SourceStamp outcome
// without affecting the outcome of any of the other signature schemes.
@@ -126,22 +132,71 @@ public abstract class SourceStampVerifier {
}
private static SourceStampVerificationResult verify(
- RandomAccessFile apk, byte[] sourceStampCertificateDigest) {
+ RandomAccessFile apk, byte[] sourceStampCertificateDigest, byte[] manifestBytes) {
try {
SignatureInfo signatureInfo =
ApkSigningBlockUtils.findSignature(apk, SOURCE_STAMP_BLOCK_ID);
- Map<Integer, byte[]> apkContentDigests = getApkContentDigests(apk);
- return verify(signatureInfo, apkContentDigests, sourceStampCertificateDigest);
- } catch (IOException | SignatureNotFoundException e) {
+ Map<Integer, Map<Integer, byte[]>> signatureSchemeApkContentDigests =
+ getSignatureSchemeApkContentDigests(apk, manifestBytes);
+ return verify(
+ signatureInfo,
+ getSignatureSchemeDigests(signatureSchemeApkContentDigests),
+ sourceStampCertificateDigest);
+ } catch (IOException | SignatureNotFoundException | RuntimeException e) {
return SourceStampVerificationResult.notVerified();
}
}
private static SourceStampVerificationResult verify(
SignatureInfo signatureInfo,
- Map<Integer, byte[]> apkContentDigests,
+ Map<Integer, byte[]> signatureSchemeDigests,
byte[] sourceStampCertificateDigest)
throws SecurityException, IOException {
+ ByteBuffer sourceStampBlock = signatureInfo.signatureBlock;
+ ByteBuffer sourceStampBlockData =
+ ApkSigningBlockUtils.getLengthPrefixedSlice(sourceStampBlock);
+
+ X509Certificate sourceStampCertificate =
+ verifySourceStampCertificate(sourceStampBlockData, sourceStampCertificateDigest);
+
+ // Parse signed signature schemes block.
+ ByteBuffer signedSignatureSchemes =
+ ApkSigningBlockUtils.getLengthPrefixedSlice(sourceStampBlockData);
+ Map<Integer, ByteBuffer> signedSignatureSchemeData = new HashMap<>();
+ while (signedSignatureSchemes.hasRemaining()) {
+ ByteBuffer signedSignatureScheme =
+ ApkSigningBlockUtils.getLengthPrefixedSlice(signedSignatureSchemes);
+ int signatureSchemeId = signedSignatureScheme.getInt();
+ signedSignatureSchemeData.put(signatureSchemeId, signedSignatureScheme);
+ }
+
+ for (Map.Entry<Integer, byte[]> signatureSchemeDigest : signatureSchemeDigests.entrySet()) {
+ if (!signedSignatureSchemeData.containsKey(signatureSchemeDigest.getKey())) {
+ throw new SecurityException(
+ String.format(
+ "No signatures found for signature scheme %d",
+ signatureSchemeDigest.getKey()));
+ }
+ verifySourceStampSignature(
+ signedSignatureSchemeData.get(signatureSchemeDigest.getKey()),
+ sourceStampCertificate,
+ signatureSchemeDigest.getValue());
+ }
+
+ return SourceStampVerificationResult.verified(sourceStampCertificate);
+ }
+
+ /**
+ * Verify the SourceStamp certificate found in the signing block is the same as the SourceStamp
+ * certificate found in the APK. It returns the verified certificate.
+ *
+ * @param sourceStampBlockData the source stamp block in the APK signing block which contains
+ * the certificate used to sign the stamp digests.
+ * @param sourceStampCertificateDigest the source stamp certificate digest found in the APK.
+ */
+ private static X509Certificate verifySourceStampCertificate(
+ ByteBuffer sourceStampBlockData, byte[] sourceStampCertificateDigest)
+ throws IOException {
CertificateFactory certFactory;
try {
certFactory = CertificateFactory.getInstance("X.509");
@@ -149,17 +204,6 @@ public abstract class SourceStampVerifier {
throw new RuntimeException("Failed to obtain X.509 CertificateFactory", e);
}
- List<Pair<Integer, byte[]>> digests =
- apkContentDigests.entrySet().stream()
- .sorted(Map.Entry.comparingByKey())
- .map(e -> Pair.create(e.getKey(), e.getValue()))
- .collect(Collectors.toList());
- byte[] digestBytes = encodeApkContentDigests(digests);
-
- ByteBuffer sourceStampBlock = signatureInfo.signatureBlock;
- ByteBuffer sourceStampBlockData =
- ApkSigningBlockUtils.getLengthPrefixedSlice(sourceStampBlock);
-
// Parse the SourceStamp certificate.
byte[] sourceStampEncodedCertificate =
ApkSigningBlockUtils.readLengthPrefixedByteArray(sourceStampBlockData);
@@ -172,24 +216,30 @@ public abstract class SourceStampVerifier {
} catch (CertificateException e) {
throw new SecurityException("Failed to decode certificate", e);
}
- sourceStampCertificate =
- new VerbatimX509Certificate(sourceStampCertificate, sourceStampEncodedCertificate);
- // Verify the SourceStamp certificate found in the signing block is the same as the
- // SourceStamp certificate found in the APK.
- try {
- MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
- messageDigest.update(sourceStampEncodedCertificate);
- byte[] sourceStampBlockCertificateDigest = messageDigest.digest();
- if (!Arrays.equals(sourceStampCertificateDigest, sourceStampBlockCertificateDigest)) {
- throw new SecurityException("Certificate mismatch between APK and signature block");
- }
- } catch (NoSuchAlgorithmException e) {
- throw new SecurityException("Failed to find SHA-256", e);
+ byte[] sourceStampBlockCertificateDigest =
+ computeSha256Digest(sourceStampEncodedCertificate);
+ if (!Arrays.equals(sourceStampCertificateDigest, sourceStampBlockCertificateDigest)) {
+ throw new SecurityException("Certificate mismatch between APK and signature block");
}
+ return new VerbatimX509Certificate(sourceStampCertificate, sourceStampEncodedCertificate);
+ }
+
+ /**
+ * Verify the SourceStamp signature found in the signing block is signed by the SourceStamp
+ * certificate found in the APK.
+ *
+ * @param signedBlockData the source stamp block in the APK signing block which contains the
+ * stamp signed digests.
+ * @param sourceStampCertificate the source stamp certificate used to sign the stamp digests.
+ * @param digest the digest to be verified being signed by the source stamp certificate.
+ */
+ private static void verifySourceStampSignature(
+ ByteBuffer signedBlockData, X509Certificate sourceStampCertificate, byte[] digest)
+ throws IOException {
// Parse the signatures block and identify supported signatures
- ByteBuffer signatures = ApkSigningBlockUtils.getLengthPrefixedSlice(sourceStampBlockData);
+ ByteBuffer signatures = ApkSigningBlockUtils.getLengthPrefixedSlice(signedBlockData);
int signatureCount = 0;
int bestSigAlgorithm = -1;
byte[] bestSigAlgorithmSignatureBytes = null;
@@ -235,7 +285,7 @@ public abstract class SourceStampVerifier {
if (jcaSignatureAlgorithmParams != null) {
sig.setParameter(jcaSignatureAlgorithmParams);
}
- sig.update(digestBytes);
+ sig.update(digest);
sigVerified = sig.verify(bestSigAlgorithmSignatureBytes);
} catch (InvalidKeyException
| InvalidAlgorithmParameterException
@@ -247,27 +297,44 @@ public abstract class SourceStampVerifier {
if (!sigVerified) {
throw new SecurityException(jcaSignatureAlgorithm + " signature did not verify");
}
-
- return SourceStampVerificationResult.verified(sourceStampCertificate);
}
- private static Map<Integer, byte[]> getApkContentDigests(RandomAccessFile apk)
- throws IOException, SignatureNotFoundException {
- // Retrieve APK content digests in V3 signing block. If a V3 signature is not found, the APK
- // content digests would be re-tried from V2 signature.
+ private static Map<Integer, Map<Integer, byte[]>> getSignatureSchemeApkContentDigests(
+ RandomAccessFile apk, byte[] manifestBytes) throws IOException {
+ Map<Integer, Map<Integer, byte[]>> signatureSchemeApkContentDigests = new HashMap<>();
+
+ // Retrieve APK content digests in V3 signing block.
try {
SignatureInfo v3SignatureInfo =
ApkSigningBlockUtils.findSignature(apk, APK_SIGNATURE_SCHEME_V3_BLOCK_ID);
- return getApkContentDigestsFromSignatureBlock(v3SignatureInfo.signatureBlock);
+ signatureSchemeApkContentDigests.put(
+ VERSION_APK_SIGNATURE_SCHEME_V3,
+ getApkContentDigestsFromSignatureBlock(v3SignatureInfo.signatureBlock));
} catch (SignatureNotFoundException e) {
// It's fine not to find a V3 signature.
}
- // Retrieve APK content digests in V2 signing block. If a V2 signature is not found, the
- // process of retrieving APK content digests stops, and the stamp is considered un-verified.
- SignatureInfo v2SignatureInfo =
- ApkSigningBlockUtils.findSignature(apk, APK_SIGNATURE_SCHEME_V2_BLOCK_ID);
- return getApkContentDigestsFromSignatureBlock(v2SignatureInfo.signatureBlock);
+ // Retrieve APK content digests in V2 signing block.
+ try {
+ SignatureInfo v2SignatureInfo =
+ ApkSigningBlockUtils.findSignature(apk, APK_SIGNATURE_SCHEME_V2_BLOCK_ID);
+ signatureSchemeApkContentDigests.put(
+ VERSION_APK_SIGNATURE_SCHEME_V2,
+ getApkContentDigestsFromSignatureBlock(v2SignatureInfo.signatureBlock));
+ } catch (SignatureNotFoundException e) {
+ // It's fine not to find a V2 signature.
+ }
+
+ // Retrieve manifest digest.
+ if (manifestBytes != null) {
+ Map<Integer, byte[]> jarSignatureSchemeApkContentDigests = new HashMap<>();
+ jarSignatureSchemeApkContentDigests.put(
+ CONTENT_DIGEST_SHA256, computeSha256Digest(manifestBytes));
+ signatureSchemeApkContentDigests.put(
+ VERSION_JAR_SIGNATURE_SCHEME, jarSignatureSchemeApkContentDigests);
+ }
+
+ return signatureSchemeApkContentDigests;
}
private static Map<Integer, byte[]> getApkContentDigestsFromSignatureBlock(
@@ -289,27 +356,45 @@ public abstract class SourceStampVerifier {
return apkContentDigests;
}
- private static byte[] getSourceStampCertificateDigest(StrictJarFile apkJar) throws IOException {
- InputStream inputStream = null;
- try {
- ZipEntry zipEntry = apkJar.findEntry(SOURCE_STAMP_CERTIFICATE_HASH_ZIP_ENTRY_NAME);
- if (zipEntry == null) {
- // SourceStamp certificate hash file not found, which means that there is not
- // SourceStamp present.
- return null;
- }
- inputStream = apkJar.getInputStream(zipEntry);
- ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ private static Map<Integer, byte[]> getSignatureSchemeDigests(
+ Map<Integer, Map<Integer, byte[]>> signatureSchemeApkContentDigests) {
+ Map<Integer, byte[]> digests = new HashMap<>();
+ for (Map.Entry<Integer, Map<Integer, byte[]>> signatureSchemeApkContentDigest :
+ signatureSchemeApkContentDigests.entrySet()) {
+ List<Pair<Integer, byte[]>> apkDigests =
+ getApkDigests(signatureSchemeApkContentDigest.getValue());
+ digests.put(
+ signatureSchemeApkContentDigest.getKey(), encodeApkContentDigests(apkDigests));
+ }
+ return digests;
+ }
- // Trying to read the certificate digest, which should be less than 1024 bytes.
- byte[] buffer = new byte[1024];
- int count = inputStream.read(buffer, 0, buffer.length);
- byteArrayOutputStream.write(buffer, 0, count);
+ private static List<Pair<Integer, byte[]>> getApkDigests(
+ Map<Integer, byte[]> apkContentDigests) {
+ List<Pair<Integer, byte[]>> digests = new ArrayList<>();
+ for (Map.Entry<Integer, byte[]> apkContentDigest : apkContentDigests.entrySet()) {
+ digests.add(Pair.create(apkContentDigest.getKey(), apkContentDigest.getValue()));
+ }
+ digests.sort(Comparator.comparing(pair -> pair.first));
+ return digests;
+ }
- return byteArrayOutputStream.toByteArray();
- } finally {
- IoUtils.closeQuietly(inputStream);
+ private static byte[] getSourceStampCertificateDigest(StrictJarFile apkJar) throws IOException {
+ ZipEntry zipEntry = apkJar.findEntry(SOURCE_STAMP_CERTIFICATE_HASH_ZIP_ENTRY_NAME);
+ if (zipEntry == null) {
+ // SourceStamp certificate hash file not found, which means that there is not
+ // SourceStamp present.
+ return null;
+ }
+ return Streams.readFully(apkJar.getInputStream(zipEntry));
+ }
+
+ private static byte[] getManifestBytes(StrictJarFile apkJar) throws IOException {
+ ZipEntry zipEntry = apkJar.findEntry(JarFile.MANIFEST_NAME);
+ if (zipEntry == null) {
+ return null;
}
+ return Streams.readFully(apkJar.getInputStream(zipEntry));
}
private static byte[] encodeApkContentDigests(List<Pair<Integer, byte[]>> apkContentDigests) {
@@ -329,6 +414,16 @@ public abstract class SourceStampVerifier {
return result.array();
}
+ private static byte[] computeSha256Digest(byte[] input) {
+ try {
+ MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
+ messageDigest.update(input);
+ return messageDigest.digest();
+ } catch (NoSuchAlgorithmException e) {
+ throw new RuntimeException("Failed to find SHA-256", e);
+ }
+ }
+
private static void closeApkJar(StrictJarFile apkJar) {
try {
if (apkJar == null) {
diff --git a/core/java/android/util/apk/TEST_MAPPING b/core/java/android/util/apk/TEST_MAPPING
new file mode 100644
index 000000000000..8544e82e04e0
--- /dev/null
+++ b/core/java/android/util/apk/TEST_MAPPING
@@ -0,0 +1,12 @@
+{
+ "presubmit": [
+ {
+ "name": "FrameworksCoreTests",
+ "options": [
+ {
+ "include-filter": "android.util.apk.SourceStampVerifierTest"
+ }
+ ]
+ }
+ ]
+}
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index 8db1703a627f..0cc469a2d5eb 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -241,13 +241,26 @@ public final class Display {
* This flag identifies secondary displays that should show system decorations, such as status
* bar, navigation bar, home activity or IME.
* </p>
+ * <p>Note that this flag doesn't work without {@link #FLAG_TRUSTED}</p>
*
+ * @see #getFlags()
* @hide
*/
// TODO (b/114338689): Remove the flag and use IWindowManager#setShouldShowSystemDecors
public static final int FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS = 1 << 6;
/**
+ * Flag: The display is trusted to show system decorations and receive inputs without users'
+ * touch.
+ * @see #FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS
+ *
+ * @see #getFlags()
+ * @hide
+ */
+ @TestApi
+ public static final int FLAG_TRUSTED = 1 << 7;
+
+ /**
* Display flag: Indicates that the contents of the display should not be scaled
* to fit the physical screen dimensions. Used for development only to emulate
* devices with smaller physicals screens while preserving density.
@@ -564,6 +577,7 @@ public final class Display {
* @see #FLAG_SUPPORTS_PROTECTED_BUFFERS
* @see #FLAG_SECURE
* @see #FLAG_PRIVATE
+ * @see #FLAG_ROUND
*/
public int getFlags() {
return mFlags;
@@ -1222,6 +1236,16 @@ public final class Display {
Display.FLAG_PRESENTATION;
}
+ /**
+ * @return {@code true} if the display is a trusted display.
+ *
+ * @see #FLAG_TRUSTED
+ * @hide
+ */
+ public boolean isTrusted() {
+ return (mFlags & FLAG_TRUSTED) == FLAG_TRUSTED;
+ }
+
private void updateDisplayInfoLocked() {
// Note: The display manager caches display info objects on our behalf.
DisplayInfo newInfo = mGlobal.getDisplayInfo(mDisplayId);
diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java
index d369883f3ac3..b1ede4102bec 100644
--- a/core/java/android/view/DisplayInfo.java
+++ b/core/java/android/view/DisplayInfo.java
@@ -717,6 +717,15 @@ public final class DisplayInfo implements Parcelable {
if ((flags & Display.FLAG_ROUND) != 0) {
result.append(", FLAG_ROUND");
}
+ if ((flags & Display.FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD) != 0) {
+ result.append(", FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD");
+ }
+ if ((flags & Display.FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS) != 0) {
+ result.append(", FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS");
+ }
+ if ((flags & Display.FLAG_TRUSTED) != 0) {
+ result.append(", FLAG_TRUSTED");
+ }
return result.toString();
}
}
diff --git a/core/java/android/view/ImeInsetsSourceConsumer.java b/core/java/android/view/ImeInsetsSourceConsumer.java
index 8b5af29517cb..ef9d990168d2 100644
--- a/core/java/android/view/ImeInsetsSourceConsumer.java
+++ b/core/java/android/view/ImeInsetsSourceConsumer.java
@@ -21,6 +21,7 @@ import static android.view.InsetsState.ITYPE_IME;
import android.annotation.Nullable;
import android.inputmethodservice.InputMethodService;
+import android.os.IBinder;
import android.os.Parcel;
import android.text.TextUtils;
import android.view.SurfaceControl.Transaction;
@@ -153,6 +154,15 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer {
return mIsRequestedVisibleAwaitingControl || isRequestedVisible();
}
+ @Override
+ public void onPerceptible(boolean perceptible) {
+ super.onPerceptible(perceptible);
+ final IBinder window = mController.getHost().getWindowToken();
+ if (window != null) {
+ getImm().reportPerceptible(window, perceptible);
+ }
+ }
+
private boolean isDummyOrEmptyEditor(EditorInfo info) {
// TODO(b/123044812): Handle dummy input gracefully in IME Insets API
return info == null || (info.fieldId <= 0 && info.inputType <= 0);
diff --git a/core/java/android/view/InsetsAnimationControlCallbacks.java b/core/java/android/view/InsetsAnimationControlCallbacks.java
index 74c186948b2f..3431c3ecc310 100644
--- a/core/java/android/view/InsetsAnimationControlCallbacks.java
+++ b/core/java/android/view/InsetsAnimationControlCallbacks.java
@@ -16,6 +16,7 @@
package android.view;
+import android.view.WindowInsets.Type.InsetsType;
import android.view.WindowInsetsAnimation.Bounds;
/**
@@ -64,4 +65,15 @@ public interface InsetsAnimationControlCallbacks {
* previous calls to applySurfaceParams.
*/
void releaseSurfaceControlFromRt(SurfaceControl sc);
+
+ /**
+ * Reports that the perceptibility of the given types has changed to the given value.
+ *
+ * A type is perceptible if it is not (almost) entirely off-screen and not (almost) entirely
+ * transparent.
+ *
+ * @param types the (public) types whose perceptibility has changed
+ * @param perceptible true, if the types are now perceptible, false if they are not perceptible
+ */
+ void reportPerceptible(@InsetsType int types, boolean perceptible);
}
diff --git a/core/java/android/view/InsetsAnimationControlImpl.java b/core/java/android/view/InsetsAnimationControlImpl.java
index cd56ca9251ab..31da83ad5137 100644
--- a/core/java/android/view/InsetsAnimationControlImpl.java
+++ b/core/java/android/view/InsetsAnimationControlImpl.java
@@ -16,13 +16,14 @@
package android.view;
+import static android.view.InsetsController.ANIMATION_TYPE_SHOW;
import static android.view.InsetsController.AnimationType;
import static android.view.InsetsController.DEBUG;
import static android.view.InsetsState.ISIDE_BOTTOM;
-import static android.view.InsetsState.ISIDE_FLOATING;
import static android.view.InsetsState.ISIDE_LEFT;
import static android.view.InsetsState.ISIDE_RIGHT;
import static android.view.InsetsState.ISIDE_TOP;
+import static android.view.InsetsState.ITYPE_IME;
import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;
@@ -74,6 +75,8 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll
private final @InsetsType int mTypes;
private final InsetsAnimationControlCallbacks mController;
private final WindowInsetsAnimation mAnimation;
+ /** @see WindowInsetsAnimationController#hasZeroInsetsIme */
+ private final boolean mHasZeroInsetsIme;
private Insets mCurrentInsets;
private Insets mPendingInsets;
private float mPendingFraction;
@@ -84,6 +87,7 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll
private float mPendingAlpha = 1.0f;
@VisibleForTesting(visibility = PACKAGE)
public boolean mReadyDispatched;
+ private Boolean mPerceptible;
@VisibleForTesting
public InsetsAnimationControlImpl(SparseArray<InsetsSourceControl> controls, Rect frame,
@@ -102,6 +106,12 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll
null /* typeSideMap */);
mShownInsets = calculateInsets(mInitialInsetsState, frame, controls, true /* shown */,
mTypeSideMap);
+ mHasZeroInsetsIme = mShownInsets.bottom == 0 && controlsInternalType(ITYPE_IME);
+ if (mHasZeroInsetsIme) {
+ // IME has shownInsets of ZERO, and can't map to a side by default.
+ // Map zero insets IME to bottom, making it a special case of bottom insets.
+ mTypeSideMap.put(ITYPE_IME, ISIDE_BOTTOM);
+ }
buildTypeSourcesMap(mTypeSideMap, mSideSourceMap, mControls);
mAnimation = new WindowInsetsAnimation(mTypes, interpolator,
@@ -112,6 +122,19 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll
new Bounds(mHiddenInsets, mShownInsets));
}
+ private boolean calculatePerceptible(Insets currentInsets, float currentAlpha) {
+ return 100 * currentInsets.left >= 5 * (mShownInsets.left - mHiddenInsets.left)
+ && 100 * currentInsets.top >= 5 * (mShownInsets.top - mHiddenInsets.top)
+ && 100 * currentInsets.right >= 5 * (mShownInsets.right - mHiddenInsets.right)
+ && 100 * currentInsets.bottom >= 5 * (mShownInsets.bottom - mHiddenInsets.bottom)
+ && currentAlpha >= 0.5f;
+ }
+
+ @Override
+ public boolean hasZeroInsetsIme() {
+ return mHasZeroInsetsIme;
+ }
+
@Override
public Insets getHiddenStateInsets() {
return mHiddenInsets;
@@ -161,6 +184,11 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll
mPendingInsets = sanitize(insets);
mPendingAlpha = sanitize(alpha);
mController.scheduleApplyChangeInsets(this);
+ boolean perceptible = calculatePerceptible(mPendingInsets, mPendingAlpha);
+ if (mPerceptible == null || perceptible != mPerceptible) {
+ mController.reportPerceptible(mTypes, perceptible);
+ mPerceptible = perceptible;
+ }
}
@VisibleForTesting
@@ -182,8 +210,6 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll
params, state, mPendingAlpha);
updateLeashesForSide(ISIDE_BOTTOM, offset.bottom, mShownInsets.bottom,
mPendingInsets.bottom, params, state, mPendingAlpha);
- updateLeashesForSide(ISIDE_FLOATING, 0 /* offset */, 0 /* inset */, 0 /* maxInset */,
- params, state, mPendingAlpha);
mController.applySurfaceParams(params.toArray(new SurfaceParams[params.size()]));
mCurrentInsets = mPendingInsets;
@@ -290,6 +316,9 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll
if (insets == null) {
insets = getCurrentInsets();
}
+ if (hasZeroInsetsIme()) {
+ return insets;
+ }
return Insets.max(Insets.min(insets, mShownInsets), mHiddenInsets);
}
@@ -313,17 +342,19 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll
mTmpFrame.set(source.getFrame());
addTranslationToMatrix(side, offset, mTmpMatrix, mTmpFrame);
- state.getSource(source.getType()).setVisible(side == ISIDE_FLOATING || inset != 0);
+ final boolean visible = mHasZeroInsetsIme && side == ISIDE_BOTTOM
+ ? (mAnimationType == ANIMATION_TYPE_SHOW ? true : !mFinished)
+ : inset != 0;
+
+ state.getSource(source.getType()).setVisible(visible);
state.getSource(source.getType()).setFrame(mTmpFrame);
// If the system is controlling the insets source, the leash can be null.
if (leash != null) {
SurfaceParams params = new SurfaceParams.Builder(leash)
- .withAlpha(side == ISIDE_FLOATING ? 1 : alpha)
+ .withAlpha(alpha)
.withMatrix(mTmpMatrix)
- .withVisibility(side == ISIDE_FLOATING
- ? mShownOnFinish
- : inset != 0 /* visible */)
+ .withVisibility(visible)
.build();
surfaceParams.add(params);
}
diff --git a/core/java/android/view/InsetsAnimationThreadControlRunner.java b/core/java/android/view/InsetsAnimationThreadControlRunner.java
index 0e71b7643b7d..123604489da4 100644
--- a/core/java/android/view/InsetsAnimationThreadControlRunner.java
+++ b/core/java/android/view/InsetsAnimationThreadControlRunner.java
@@ -90,6 +90,11 @@ public class InsetsAnimationThreadControlRunner implements InsetsAnimationContro
// Since we don't push the SurfaceParams to the RT we can release directly
sc.release();
}
+
+ @Override
+ public void reportPerceptible(int types, boolean perceptible) {
+ mMainThreadHandler.post(() -> mOuterCallbacks.reportPerceptible(types, perceptible));
+ }
};
@UiThread
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index 9a9396c45b66..a3c88bacb627 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -35,6 +35,7 @@ import android.graphics.Insets;
import android.graphics.Rect;
import android.os.CancellationSignal;
import android.os.Handler;
+import android.os.IBinder;
import android.os.Trace;
import android.util.ArraySet;
import android.util.Log;
@@ -162,6 +163,15 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
*/
@Nullable
String getRootViewTitle();
+
+ /** @see ViewRootImpl#dipToPx */
+ int dipToPx(int dips);
+
+ /**
+ * @return token associated with the host, if it has one.
+ */
+ @Nullable
+ IBinder getWindowToken();
}
private static final String TAG = "InsetsController";
@@ -254,12 +264,17 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
public static class InternalAnimationControlListener
implements WindowInsetsAnimationControlListener {
+ /** The amount IME will move up/down when animating in floating mode. */
+ protected static final int FLOATING_IME_BOTTOM_INSET = -80;
+
private WindowInsetsAnimationController mController;
private ValueAnimator mAnimator;
private final boolean mShow;
private final boolean mHasAnimationCallbacks;
private final @InsetsType int mRequestedTypes;
private final long mDurationMs;
+ private final boolean mDisable;
+ private final int mFloatingImeBottomInset;
private ThreadLocal<AnimationHandler> mSfAnimationHandlerThreadLocal =
new ThreadLocal<AnimationHandler>() {
@@ -272,11 +287,13 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
};
public InternalAnimationControlListener(boolean show, boolean hasAnimationCallbacks,
- int requestedTypes) {
+ int requestedTypes, boolean disable, int floatingImeBottomInset) {
mShow = show;
mHasAnimationCallbacks = hasAnimationCallbacks;
mRequestedTypes = requestedTypes;
mDurationMs = calculateDurationMs();
+ mDisable = disable;
+ mFloatingImeBottomInset = floatingImeBottomInset;
}
@Override
@@ -284,15 +301,26 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
mController = controller;
if (DEBUG) Log.d(TAG, "default animation onReady types: " + types);
+ if (mDisable) {
+ onAnimationFinish();
+ return;
+ }
mAnimator = ValueAnimator.ofFloat(0f, 1f);
mAnimator.setDuration(mDurationMs);
mAnimator.setInterpolator(new LinearInterpolator());
+ Insets hiddenInsets = controller.getHiddenStateInsets();
+ // IME with zero insets is a special case: it will animate-in from offscreen and end
+ // with final insets of zero and vice-versa.
+ hiddenInsets = controller.hasZeroInsetsIme()
+ ? Insets.of(hiddenInsets.left, hiddenInsets.top, hiddenInsets.right,
+ mFloatingImeBottomInset)
+ : hiddenInsets;
Insets start = mShow
- ? controller.getHiddenStateInsets()
+ ? hiddenInsets
: controller.getShownStateInsets();
Insets end = mShow
? controller.getShownStateInsets()
- : controller.getHiddenStateInsets();
+ : hiddenInsets;
Interpolator insetsInterpolator = getInterpolator();
Interpolator alphaInterpolator = getAlphaInterpolator();
mAnimator.addUpdateListener(animation -> {
@@ -477,6 +505,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
private DisplayCutout mLastDisplayCutout;
private boolean mStartingAnimation;
private int mCaptionInsetsHeight = 0;
+ private boolean mAnimationsDisabled;
private Runnable mPendingControlTimeout = this::abortPendingImeControlRequest;
private final ArrayList<OnControllableInsetsChangedListener> mControllableInsetsChangedListeners
@@ -599,12 +628,14 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
private void updateState(InsetsState newState) {
mState.setDisplayFrame(newState.getDisplayFrame());
- for (int i = newState.getSourcesCount() - 1; i >= 0; i--) {
- InsetsSource source = newState.sourceAt(i);
+ for (int i = 0; i < InsetsState.SIZE; i++) {
+ InsetsSource source = newState.peekSource(i);
+ if (source == null) continue;;
getSourceConsumer(source.getType()).updateSource(source);
}
- for (int i = mState.getSourcesCount() - 1; i >= 0; i--) {
- InsetsSource source = mState.sourceAt(i);
+ for (int i = 0; i < InsetsState.SIZE; i++) {
+ InsetsSource source = mState.peekSource(i);
+ if (source == null) continue;
if (newState.peekSource(source.getType()) == null) {
mState.removeSource(source.getType());
}
@@ -700,7 +731,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
if (hideTypes[0] != 0) {
applyAnimation(hideTypes[0], false /* show */, false /* fromIme */);
}
- if (hasControl && mRequestedState.getSourcesCount() > 0) {
+ if (hasControl && mRequestedState.hasSources()) {
// We might have changed our requested visibilities while we don't have the control,
// so we need to update our requested state once we have control. Otherwise, our
// requested state at the server side might be incorrect.
@@ -1163,8 +1194,9 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
}
boolean hasAnimationCallbacks = mHost.hasAnimationCallbacks();
- final InternalAnimationControlListener listener =
- new InternalAnimationControlListener(show, hasAnimationCallbacks, types);
+ final InternalAnimationControlListener listener = new InternalAnimationControlListener(
+ show, hasAnimationCallbacks, types, mAnimationsDisabled,
+ mHost.dipToPx(InternalAnimationControlListener.FLOATING_IME_BOTTOM_INSET));
// Show/hide animations always need to be relative to the display frame, in order that shown
// and hidden state insets are correct.
@@ -1279,6 +1311,11 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
return mHost.getSystemBarsBehavior();
}
+ @Override
+ public void setAnimationsDisabled(boolean disable) {
+ mAnimationsDisabled = disable;
+ }
+
private @InsetsType int calculateControllableTypes() {
@InsetsType int result = 0;
for (int i = mSourceConsumers.size() - 1; i >= 0; i--) {
@@ -1323,6 +1360,18 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
mHost.releaseSurfaceControlFromRt(sc);
}
+ @Override
+ public void reportPerceptible(int types, boolean perceptible) {
+ final ArraySet<Integer> internalTypes = toInternalType(types);
+ final int size = mSourceConsumers.size();
+ for (int i = 0; i < size; i++) {
+ final InsetsSourceConsumer consumer = mSourceConsumers.valueAt(i);
+ if (internalTypes.contains(consumer.getType())) {
+ consumer.onPerceptible(perceptible);
+ }
+ }
+ }
+
Host getHost() {
return mHost;
}
diff --git a/core/java/android/view/InsetsSourceConsumer.java b/core/java/android/view/InsetsSourceConsumer.java
index 3aa246441dbc..b62e67c8f9e1 100644
--- a/core/java/android/view/InsetsSourceConsumer.java
+++ b/core/java/android/view/InsetsSourceConsumer.java
@@ -18,8 +18,8 @@ package android.view;
import static android.view.InsetsController.ANIMATION_TYPE_NONE;
import static android.view.InsetsController.AnimationType;
-import static android.view.InsetsController.DEBUG;
import static android.view.InsetsState.getDefaultVisibility;
+import static android.view.InsetsController.DEBUG;
import static android.view.InsetsState.toPublicType;
import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;
@@ -261,6 +261,15 @@ public class InsetsSourceConsumer {
}
/**
+ * Reports that this source's perceptibility has changed
+ *
+ * @param perceptible true if the source is perceptible, false otherwise.
+ * @see InsetsAnimationControlCallbacks#reportPerceptible
+ */
+ public void onPerceptible(boolean perceptible) {
+ }
+
+ /**
* Notify listeners that window is now hidden.
*/
void notifyHidden() {
@@ -339,5 +348,6 @@ public class InsetsSourceConsumer {
t.hide(mSourceControl.getLeash());
}
t.apply();
+ onPerceptible(mRequestedVisible);
}
}
diff --git a/core/java/android/view/InsetsState.java b/core/java/android/view/InsetsState.java
index 397b04e9c023..9bf2e01a6bd1 100644
--- a/core/java/android/view/InsetsState.java
+++ b/core/java/android/view/InsetsState.java
@@ -50,6 +50,7 @@ import com.android.internal.annotations.VisibleForTesting;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.Arrays;
import java.util.Objects;
import java.util.StringJoiner;
@@ -117,6 +118,7 @@ public class InsetsState implements Parcelable {
public static final int ITYPE_EXTRA_NAVIGATION_BAR = 15;
static final int LAST_TYPE = ITYPE_EXTRA_NAVIGATION_BAR;
+ public static final int SIZE = LAST_TYPE + 1;
// Derived types
@@ -140,7 +142,7 @@ public class InsetsState implements Parcelable {
static final int ISIDE_FLOATING = 4;
static final int ISIDE_UNKNOWN = 5;
- private final ArrayMap<Integer, InsetsSource> mSources = new ArrayMap<>();
+ private InsetsSource[] mSources = new InsetsSource[SIZE];
/**
* The frame of the display these sources are relative to.
@@ -177,7 +179,7 @@ public class InsetsState implements Parcelable {
final Rect relativeFrame = new Rect(frame);
final Rect relativeFrameMax = new Rect(frame);
for (int type = FIRST_TYPE; type <= LAST_TYPE; type++) {
- InsetsSource source = mSources.get(type);
+ InsetsSource source = mSources[type];
if (source == null) {
int index = indexOf(toPublicType(type));
if (typeInsetsMap[index] == null) {
@@ -227,7 +229,7 @@ public class InsetsState implements Parcelable {
public Rect calculateVisibleInsets(Rect frame, @SoftInputModeFlags int softInputMode) {
Insets insets = Insets.NONE;
for (int type = FIRST_TYPE; type <= LAST_TYPE; type++) {
- InsetsSource source = mSources.get(type);
+ InsetsSource source = mSources[type];
if (source == null) {
continue;
}
@@ -256,7 +258,7 @@ public class InsetsState implements Parcelable {
public int calculateUncontrollableInsetsFromFrame(Rect frame) {
int blocked = 0;
for (int type = FIRST_TYPE; type <= LAST_TYPE; type++) {
- InsetsSource source = mSources.get(type);
+ InsetsSource source = mSources[type];
if (source == null) {
continue;
}
@@ -350,11 +352,39 @@ public class InsetsState implements Parcelable {
}
public InsetsSource getSource(@InternalInsetsType int type) {
- return mSources.computeIfAbsent(type, InsetsSource::new);
+ InsetsSource source = mSources[type];
+ if (source != null) {
+ return source;
+ }
+ source = new InsetsSource(type);
+ mSources[type] = source;
+ return source;
}
public @Nullable InsetsSource peekSource(@InternalInsetsType int type) {
- return mSources.get(type);
+ return mSources[type];
+ }
+
+ public boolean hasSources() {
+ for (int i = 0; i < SIZE; i++) {
+ if (mSources[i] != null) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns the source visibility or the default visibility if the source doesn't exist. This is
+ * useful if when treating this object as a request.
+ *
+ * @param type The {@link InternalInsetsType} to query.
+ * @return {@code true} if the source is visible or the type is default visible and the source
+ * doesn't exist.
+ */
+ public boolean getSourceOrDefaultVisibility(@InternalInsetsType int type) {
+ final InsetsSource source = mSources[type];
+ return source != null ? source.isVisible() : getDefaultVisibility(type);
}
public void setDisplayFrame(Rect frame) {
@@ -372,7 +402,7 @@ public class InsetsState implements Parcelable {
* @param type The {@link InternalInsetsType} of the source to remove
*/
public void removeSource(@InternalInsetsType int type) {
- mSources.remove(type);
+ mSources[type] = null;
}
/**
@@ -382,53 +412,33 @@ public class InsetsState implements Parcelable {
* @param visible {@code true} for visible
*/
public void setSourceVisible(@InternalInsetsType int type, boolean visible) {
- InsetsSource source = mSources.get(type);
+ InsetsSource source = mSources[type];
if (source != null) {
source.setVisible(visible);
}
}
- /**
- * A shortcut for setting the visibility of the source.
- *
- * @param type The {@link InternalInsetsType} of the source to set the visibility
- * @param referenceState The {@link InsetsState} for reference
- */
- public void setSourceVisible(@InternalInsetsType int type, InsetsState referenceState) {
- InsetsSource source = mSources.get(type);
- InsetsSource referenceSource = referenceState.mSources.get(type);
- if (source != null && referenceSource != null) {
- source.setVisible(referenceSource.isVisible());
- }
- }
-
public void set(InsetsState other) {
set(other, false /* copySources */);
}
public void set(InsetsState other, boolean copySources) {
mDisplayFrame.set(other.mDisplayFrame);
- mSources.clear();
if (copySources) {
- for (int i = 0; i < other.mSources.size(); i++) {
- InsetsSource source = other.mSources.valueAt(i);
- mSources.put(source.getType(), new InsetsSource(source));
+ for (int i = 0; i < SIZE; i++) {
+ InsetsSource source = other.mSources[i];
+ if (source == null) continue;
+ mSources[i] = new InsetsSource(source);
}
} else {
- mSources.putAll(other.mSources);
+ for (int i = 0; i < SIZE; i++) {
+ mSources[i] = other.mSources[i];
+ }
}
}
public void addSource(InsetsSource source) {
- mSources.put(source.getType(), source);
- }
-
- public int getSourcesCount() {
- return mSources.size();
- }
-
- public InsetsSource sourceAt(int index) {
- return mSources.valueAt(index);
+ mSources[source.getType()] = source;
}
public static @InternalInsetsType ArraySet<Integer> toInternalType(@InsetsType int types) {
@@ -490,7 +500,7 @@ public class InsetsState implements Parcelable {
}
}
- public static boolean getDefaultVisibility(@InsetsType int type) {
+ public static boolean getDefaultVisibility(@InternalInsetsType int type) {
return type != ITYPE_IME;
}
@@ -509,8 +519,10 @@ public class InsetsState implements Parcelable {
public void dump(String prefix, PrintWriter pw) {
pw.println(prefix + "InsetsState");
- for (int i = mSources.size() - 1; i >= 0; i--) {
- mSources.valueAt(i).dump(prefix + " ", pw);
+ for (int i = 0; i < SIZE; i++) {
+ InsetsSource source = mSources[i];
+ if (source == null) continue;
+ source.dump(prefix + " ", pw);
}
}
@@ -579,26 +591,16 @@ public class InsetsState implements Parcelable {
if (!mDisplayFrame.equals(state.mDisplayFrame)) {
return false;
}
- int size = mSources.size();
- int otherSize = state.mSources.size();
- if (excludingCaptionInsets) {
- if (mSources.get(ITYPE_CAPTION_BAR) != null) {
- size--;
- }
- if (state.mSources.get(ITYPE_CAPTION_BAR) != null) {
- otherSize--;
- }
- }
- if (size != otherSize) {
- return false;
- }
- for (int i = mSources.size() - 1; i >= 0; i--) {
- InsetsSource source = mSources.valueAt(i);
+ for (int i = 0; i < SIZE; i++) {
if (excludingCaptionInsets) {
- if (source.getType() == ITYPE_CAPTION_BAR) continue;
+ if (i == ITYPE_CAPTION_BAR) continue;
}
- InsetsSource otherSource = state.mSources.get(source.getType());
- if (otherSource == null) {
+ InsetsSource source = mSources[i];
+ InsetsSource otherSource = state.mSources[i];
+ if (source == null && otherSource == null) {
+ continue;
+ }
+ if (source != null && otherSource == null || source == null && otherSource != null) {
return false;
}
if (!otherSource.equals(source, excludeInvisibleImeFrames)) {
@@ -610,7 +612,7 @@ public class InsetsState implements Parcelable {
@Override
public int hashCode() {
- return Objects.hash(mDisplayFrame, mSources);
+ return Objects.hash(mDisplayFrame, Arrays.hashCode(mSources));
}
public InsetsState(Parcel in) {
@@ -625,10 +627,7 @@ public class InsetsState implements Parcelable {
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeParcelable(mDisplayFrame, flags);
- dest.writeInt(mSources.size());
- for (int i = 0; i < mSources.size(); i++) {
- dest.writeParcelable(mSources.valueAt(i), flags);
- }
+ dest.writeParcelableArray(mSources, 0);
}
public static final @android.annotation.NonNull Creator<InsetsState> CREATOR = new Creator<InsetsState>() {
@@ -643,19 +642,15 @@ public class InsetsState implements Parcelable {
};
public void readFromParcel(Parcel in) {
- mSources.clear();
mDisplayFrame.set(in.readParcelable(null /* loader */));
- final int size = in.readInt();
- for (int i = 0; i < size; i++) {
- final InsetsSource source = in.readParcelable(null /* loader */);
- mSources.put(source.getType(), source);
- }
+ mSources = in.readParcelableArray(null, InsetsSource.class);
}
@Override
public String toString() {
StringJoiner joiner = new StringJoiner(", ");
- for (InsetsSource source : mSources.values()) {
+ for (int i = 0; i < SIZE; i++) {
+ InsetsSource source = mSources[i];
if (source != null) {
joiner.add(source.toString());
}
diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java
index 19eff72ca814..51b0c6b59f3c 100644
--- a/core/java/android/view/MotionEvent.java
+++ b/core/java/android/view/MotionEvent.java
@@ -487,6 +487,21 @@ public final class MotionEvent extends InputEvent implements Parcelable {
public static final int FLAG_TAINTED = 0x80000000;
/**
+ * Private flag indicating that this event was synthesized by the system and should be delivered
+ * to the accessibility focused view first. When being dispatched such an event is not handled
+ * by predecessors of the accessibility focused view and after the event reaches that view the
+ * flag is cleared and normal event dispatch is performed. This ensures that the platform can
+ * click on any view that has accessibility focus which is semantically equivalent to asking the
+ * view to perform a click accessibility action but more generic as views not implementing click
+ * action correctly can still be activated.
+ *
+ * @hide
+ * @see #isTargetAccessibilityFocus()
+ * @see #setTargetAccessibilityFocus(boolean)
+ */
+ public static final int FLAG_TARGET_ACCESSIBILITY_FOCUS = 0x40000000;
+
+ /**
* Flag indicating the motion event intersected the top edge of the screen.
*/
public static final int EDGE_TOP = 0x00000001;
@@ -2140,6 +2155,20 @@ public final class MotionEvent extends InputEvent implements Parcelable {
}
/** @hide */
+ public boolean isTargetAccessibilityFocus() {
+ final int flags = getFlags();
+ return (flags & FLAG_TARGET_ACCESSIBILITY_FOCUS) != 0;
+ }
+
+ /** @hide */
+ public void setTargetAccessibilityFocus(boolean targetsFocus) {
+ final int flags = getFlags();
+ nativeSetFlags(mNativePtr, targetsFocus
+ ? flags | FLAG_TARGET_ACCESSIBILITY_FOCUS
+ : flags & ~FLAG_TARGET_ACCESSIBILITY_FOCUS);
+ }
+
+ /** @hide */
public final boolean isHoverExitPending() {
final int flags = getFlags();
return (flags & FLAG_HOVER_EXIT_PENDING) != 0;
diff --git a/core/java/android/view/PendingInsetsController.java b/core/java/android/view/PendingInsetsController.java
index 0283ada0dd40..c018d1cf1782 100644
--- a/core/java/android/view/PendingInsetsController.java
+++ b/core/java/android/view/PendingInsetsController.java
@@ -38,6 +38,7 @@ public class PendingInsetsController implements WindowInsetsController {
private @Appearance int mAppearance;
private @Appearance int mAppearanceMask;
private @Behavior int mBehavior = KEEP_BEHAVIOR;
+ private boolean mAnimationsDisabled;
private final InsetsState mDummyState = new InsetsState();
private InsetsController mReplayedInsetsController;
private ArrayList<OnControllableInsetsChangedListener> mControllableInsetsChangedListeners
@@ -103,6 +104,15 @@ public class PendingInsetsController implements WindowInsetsController {
}
@Override
+ public void setAnimationsDisabled(boolean disable) {
+ if (mReplayedInsetsController != null) {
+ mReplayedInsetsController.setAnimationsDisabled(disable);
+ } else {
+ mAnimationsDisabled = disable;
+ }
+ }
+
+ @Override
public InsetsState getState() {
return mDummyState;
}
@@ -151,6 +161,9 @@ public class PendingInsetsController implements WindowInsetsController {
if (mCaptionInsetsHeight != 0) {
controller.setCaptionInsetsHeight(mCaptionInsetsHeight);
}
+ if (mAnimationsDisabled) {
+ controller.setAnimationsDisabled(true);
+ }
int size = mRequests.size();
for (int i = 0; i < size; i++) {
mRequests.get(i).replay(controller);
@@ -167,6 +180,7 @@ public class PendingInsetsController implements WindowInsetsController {
mBehavior = KEEP_BEHAVIOR;
mAppearance = 0;
mAppearanceMask = 0;
+ mAnimationsDisabled = false;
// After replaying, we forward everything directly to the replayed instance.
mReplayedInsetsController = controller;
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 6f73e8985a8a..3b3836582b16 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -49,6 +49,7 @@ import android.os.Build;
import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;
+import android.os.Trace;
import android.util.ArrayMap;
import android.util.Log;
import android.util.SparseIntArray;
@@ -102,6 +103,8 @@ public final class SurfaceControl implements Parcelable {
long otherTransactionObj);
private static native void nativeSetAnimationTransaction(long transactionObj);
private static native void nativeSetEarlyWakeup(long transactionObj);
+ private static native void nativeSetEarlyWakeupStart(long transactionObj);
+ private static native void nativeSetEarlyWakeupEnd(long transactionObj);
private static native void nativeSetLayer(long transactionObj, long nativeObject, int zorder);
private static native void nativeSetRelativeLayer(long transactionObj, long nativeObject,
@@ -230,7 +233,6 @@ public final class SurfaceControl implements Parcelable {
*/
public long mNativeObject;
private long mNativeHandle;
- private Throwable mReleaseStack = null;
// TODO: Move this to native.
private final Object mSizeLock = new Object();
@@ -438,17 +440,12 @@ public final class SurfaceControl implements Parcelable {
release();
}
if (nativeObject != 0) {
+ Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "closeGuard");
mCloseGuard.open("release");
+ Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
}
mNativeObject = nativeObject;
mNativeHandle = mNativeObject != 0 ? nativeGetHandle(nativeObject) : 0;
- if (mNativeObject == 0) {
- if (Build.IS_DEBUGGABLE) {
- mReleaseStack = new Throwable("assigned zero nativeObject here");
- }
- } else {
- mReleaseStack = null;
- }
}
/**
@@ -1024,22 +1021,11 @@ public final class SurfaceControl implements Parcelable {
nativeRelease(mNativeObject);
mNativeObject = 0;
mNativeHandle = 0;
- if (Build.IS_DEBUGGABLE) {
- mReleaseStack = new Throwable("released here");
- }
mCloseGuard.close();
}
}
/**
- * Returns the call stack that assigned mNativeObject to zero.
- * @hide
- */
- public Throwable getReleaseStack() {
- return mReleaseStack;
- }
-
- /**
* Disconnect any client still connected to the surface.
* @hide
*/
@@ -1050,11 +1036,8 @@ public final class SurfaceControl implements Parcelable {
}
private void checkNotReleased() {
- if (mNativeObject == 0) {
- Log.wtf(TAG, "Invalid " + this + " caused by:", mReleaseStack);
- throw new NullPointerException(
- "mNativeObject of " + this + " is null. Have you called release() already?");
- }
+ if (mNativeObject == 0) throw new NullPointerException(
+ "Invalid " + this + ", mNativeObject is null. Have you called release() already?");
}
/**
@@ -2797,6 +2780,8 @@ public final class SurfaceControl implements Parcelable {
}
/**
+ * @deprecated use {@link Transaction#setEarlyWakeupStart()}
+ *
* Indicate that SurfaceFlinger should wake up earlier than usual as a result of this
* transaction. This should be used when the caller thinks that the scene is complex enough
* that it's likely to hit GL composition, and thus, SurfaceFlinger needs to more time in
@@ -2805,11 +2790,35 @@ public final class SurfaceControl implements Parcelable {
* Corresponds to setting ISurfaceComposer::eEarlyWakeup
* @hide
*/
+ @Deprecated
public Transaction setEarlyWakeup() {
nativeSetEarlyWakeup(mNativeObject);
return this;
}
+ /**
+ * Provides a hint to SurfaceFlinger to change its offset so that SurfaceFlinger wakes up
+ * earlier to compose surfaces. The caller should use this as a hint to SurfaceFlinger
+ * when the scene is complex enough to use GPU composition. The hint will remain active
+ * until until the client calls {@link Transaction#setEarlyWakeupEnd}.
+ *
+ * @hide
+ */
+ public Transaction setEarlyWakeupStart() {
+ nativeSetEarlyWakeupStart(mNativeObject);
+ return this;
+ }
+
+ /**
+ * Removes the early wake up hint set by {@link Transaction#setEarlyWakeupStart}.
+ *
+ * @hide
+ */
+ public Transaction setEarlyWakeupEnd() {
+ nativeSetEarlyWakeupEnd(mNativeObject);
+ return this;
+ }
+
/**
* Sets an arbitrary piece of metadata on the surface. This is a helper for int data.
* @hide
diff --git a/core/java/android/view/SurfaceControlViewHost.java b/core/java/android/view/SurfaceControlViewHost.java
index 385078165e84..86a4fe170387 100644
--- a/core/java/android/view/SurfaceControlViewHost.java
+++ b/core/java/android/view/SurfaceControlViewHost.java
@@ -178,6 +178,17 @@ public class SurfaceControlViewHost {
}
/**
+ * @hide
+ */
+ @Override
+ protected void finalize() throws Throwable {
+ // We aren't on the UI thread here so we need to pass false to
+ // doDie
+ mViewRoot.die(false /* immediate */);
+ }
+
+
+ /**
* Return a SurfacePackage for the root SurfaceControl of the embedded hierarchy.
* Rather than be directly reparented using {@link SurfaceControl.Transaction} this
* SurfacePackage should be passed to {@link SurfaceView#setChildSurfacePackage}
@@ -273,6 +284,6 @@ public class SurfaceControlViewHost {
*/
public void release() {
// ViewRoot will release mSurfaceControl for us.
- mViewRoot.die(false /* immediate */);
+ mViewRoot.die(true /* immediate */);
}
}
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index c098fae11b8c..90e1eab09fd6 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -640,7 +640,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
mTmpRect.set(0, 0, mSurfaceWidth, mSurfaceHeight);
}
SyncRtSurfaceTransactionApplier applier = new SyncRtSurfaceTransactionApplier(this);
- applier.scheduleApply(false /* earlyWakeup */,
+ applier.scheduleApply(
new SyncRtSurfaceTransactionApplier.SurfaceParams.Builder(mSurfaceControl)
.withWindowCrop(mTmpRect)
.build());
@@ -1620,9 +1620,14 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
}
private void updateRelativeZ(Transaction t) {
- SurfaceControl viewRoot = getViewRootImpl().getSurfaceControl();
- t.setRelativeLayer(mBackgroundControl, viewRoot, Integer.MIN_VALUE);
- t.setRelativeLayer(mSurfaceControl, viewRoot, mSubLayer);
+ final ViewRootImpl viewRoot = getViewRootImpl();
+ if (viewRoot == null) {
+ // We were just detached.
+ return;
+ }
+ final SurfaceControl viewRootControl = viewRoot.getSurfaceControl();
+ t.setRelativeLayer(mBackgroundControl, viewRootControl, Integer.MIN_VALUE);
+ t.setRelativeLayer(mSurfaceControl, viewRootControl, mSubLayer);
}
/**
diff --git a/core/java/android/view/SyncRtSurfaceTransactionApplier.java b/core/java/android/view/SyncRtSurfaceTransactionApplier.java
index 9c97f3e5b503..062285ff2f5d 100644
--- a/core/java/android/view/SyncRtSurfaceTransactionApplier.java
+++ b/core/java/android/view/SyncRtSurfaceTransactionApplier.java
@@ -53,11 +53,10 @@ public class SyncRtSurfaceTransactionApplier {
/**
* Schedules applying surface parameters on the next frame.
*
- * @param earlyWakeup Whether to set {@link Transaction#setEarlyWakeup()} on transaction.
* @param params The surface parameters to apply. DO NOT MODIFY the list after passing into
* this method to avoid synchronization issues.
*/
- public void scheduleApply(boolean earlyWakeup, final SurfaceParams... params) {
+ public void scheduleApply(final SurfaceParams... params) {
if (mTargetViewRootImpl == null) {
return;
}
@@ -67,7 +66,7 @@ public class SyncRtSurfaceTransactionApplier {
return;
}
Transaction t = new Transaction();
- applyParams(t, frame, earlyWakeup, params);
+ applyParams(t, frame, params);
});
// Make sure a frame gets scheduled.
@@ -78,12 +77,10 @@ public class SyncRtSurfaceTransactionApplier {
* Applies surface parameters on the next frame.
* @param t transaction to apply all parameters in.
* @param frame frame to synchronize to. Set -1 when sync is not required.
- * @param earlyWakeup Whether to set {@link Transaction#setEarlyWakeup()} on transaction.
* @param params The surface parameters to apply. DO NOT MODIFY the list after passing into
* this method to avoid synchronization issues.
*/
- void applyParams(Transaction t, long frame, boolean earlyWakeup,
- final SurfaceParams... params) {
+ void applyParams(Transaction t, long frame, final SurfaceParams... params) {
for (int i = params.length - 1; i >= 0; i--) {
SurfaceParams surfaceParams = params[i];
SurfaceControl surface = surfaceParams.surface;
@@ -92,9 +89,6 @@ public class SyncRtSurfaceTransactionApplier {
}
applyParams(t, surfaceParams, mTmpFloat9);
}
- if (earlyWakeup) {
- t.setEarlyWakeup();
- }
t.apply();
}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 1226202dfdf9..df1c672eb9eb 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -14274,6 +14274,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/
public boolean dispatchTouchEvent(MotionEvent event) {
// If the event should be handled by accessibility focus first.
+ if (event.isTargetAccessibilityFocus()) {
+ // We don't have focus or no virtual descendant has it, do not handle the event.
+ if (!isAccessibilityFocusedViewOrHost()) {
+ return false;
+ }
+ // We have focus and got the event, then use normal event dispatch.
+ event.setTargetAccessibilityFocus(false);
+ }
boolean result = false;
if (mInputEventConsistencyVerifier != null) {
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index e3362aafbcd4..77fedd7c30d4 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -2048,8 +2048,26 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
for (int i = childrenCount - 1; i >= 0; i--) {
final int childIndex = getAndVerifyPreorderedIndex(childrenCount, i, customOrder);
final View child = getAndVerifyPreorderedView(preorderedList, children, childIndex);
+ View childWithAccessibilityFocus =
+ event.isTargetAccessibilityFocus()
+ ? findChildWithAccessibilityFocus()
+ : null;
+
if (!child.canReceivePointerEvents()
|| !isTransformedTouchPointInView(x, y, child, null)) {
+
+ // If there is a view that has accessibility focus we want it
+ // to get the event first and if not handled we will perform a
+ // normal dispatch. We may do a double iteration but this is
+ // safer given the timeframe.
+ if (childWithAccessibilityFocus != null) {
+ if (childWithAccessibilityFocus != child) {
+ continue;
+ }
+ childWithAccessibilityFocus = null;
+ i = childrenCount - 1;
+ }
+ event.setTargetAccessibilityFocus(false);
continue;
}
final PointerIcon pointerIcon =
@@ -2617,6 +2635,12 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
mInputEventConsistencyVerifier.onTouchEvent(ev, 1);
}
+ // If the event targets the accessibility focused view and this is it, start
+ // normal event dispatch. Maybe a descendant is what will handle the click.
+ if (ev.isTargetAccessibilityFocus() && isAccessibilityFocusedViewOrHost()) {
+ ev.setTargetAccessibilityFocus(false);
+ }
+
boolean handled = false;
if (onFilterTouchEventForSecurity(ev)) {
final int action = ev.getAction();
@@ -2647,6 +2671,13 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
// so this view group continues to intercept touches.
intercepted = true;
}
+
+ // If intercepted, start normal event dispatch. Also if there is already
+ // a view that is handling the gesture, do normal event dispatch.
+ if (intercepted || mFirstTouchTarget != null) {
+ ev.setTargetAccessibilityFocus(false);
+ }
+
// Check for cancelation.
final boolean canceled = resetCancelNextUpFlag(this)
|| actionMasked == MotionEvent.ACTION_CANCEL;
@@ -2658,6 +2689,14 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
TouchTarget newTouchTarget = null;
boolean alreadyDispatchedToNewTouchTarget = false;
if (!canceled && !intercepted) {
+ // If the event is targeting accessibility focus we give it to the
+ // view that has accessibility focus and if it does not handle it
+ // we clear the flag and dispatch the event to all children as usual.
+ // We are looking up the accessibility focused host to avoid keeping
+ // state since these events are very rare.
+ View childWithAccessibilityFocus = ev.isTargetAccessibilityFocus()
+ ? findChildWithAccessibilityFocus() : null;
+
if (actionMasked == MotionEvent.ACTION_DOWN
|| (split && actionMasked == MotionEvent.ACTION_POINTER_DOWN)
|| actionMasked == MotionEvent.ACTION_HOVER_MOVE) {
@@ -2720,6 +2759,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
alreadyDispatchedToNewTouchTarget = true;
break;
}
+
+ // The accessibility focus didn't handle the event, so clear
+ // the flag and do a normal dispatch to all children.
+ ev.setTargetAccessibilityFocus(false);
}
if (preorderedList != null) preorderedList.clear();
}
@@ -2803,6 +2846,34 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
return buildOrderedChildList();
}
+ /**
+ * Finds the child which has accessibility focus.
+ *
+ * @return The child that has focus.
+ */
+ private View findChildWithAccessibilityFocus() {
+ ViewRootImpl viewRoot = getViewRootImpl();
+ if (viewRoot == null) {
+ return null;
+ }
+
+ View current = viewRoot.getAccessibilityFocusedHost();
+ if (current == null) {
+ return null;
+ }
+
+ ViewParent parent = current.getParent();
+ while (parent instanceof View) {
+ if (parent == this) {
+ return current;
+ }
+ current = (View) parent;
+ parent = current.getParent();
+ }
+
+ return null;
+ }
+
/**
* Resets all touch state in preparation for a new cycle.
*/
@@ -3257,9 +3328,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
break;
}
default:
- throw new IllegalStateException("descendant focusability must be "
- + "one of FOCUS_BEFORE_DESCENDANTS, FOCUS_AFTER_DESCENDANTS, FOCUS_BLOCK_DESCENDANTS "
- + "but is " + descendantFocusability);
+ throw new IllegalStateException(
+ "descendant focusability must be one of FOCUS_BEFORE_DESCENDANTS,"
+ + " FOCUS_AFTER_DESCENDANTS, FOCUS_BLOCK_DESCENDANTS but is "
+ + descendantFocusability);
}
if (result && !isLayoutValid() && ((mPrivateFlags & PFLAG_WANTS_FOCUS) == 0)) {
mPrivateFlags |= PFLAG_WANTS_FOCUS;
@@ -4925,7 +4997,8 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
if (params == null) {
params = generateDefaultLayoutParams();
if (params == null) {
- throw new IllegalArgumentException("generateDefaultLayoutParams() cannot return null");
+ throw new IllegalArgumentException(
+ "generateDefaultLayoutParams() cannot return null");
}
}
addView(child, index, params);
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 8b5d033072fb..b860bac0d001 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -21,7 +21,7 @@ import static android.view.Display.INVALID_DISPLAY;
import static android.view.InputDevice.SOURCE_CLASS_NONE;
import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
import static android.view.InsetsState.ITYPE_STATUS_BAR;
-import static android.view.InsetsState.LAST_TYPE;
+import static android.view.InsetsState.SIZE;
import static android.view.View.PFLAG_DRAW_ANIMATION;
import static android.view.View.SYSTEM_UI_FLAG_FULLSCREEN;
import static android.view.View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
@@ -564,7 +564,7 @@ public final class ViewRootImpl implements ViewParent,
new DisplayCutout.ParcelableWrapper(DisplayCutout.NO_CUTOUT);
boolean mPendingAlwaysConsumeSystemBars;
private final InsetsState mTempInsets = new InsetsState();
- private final InsetsSourceControl[] mTempControls = new InsetsSourceControl[LAST_TYPE + 1];
+ private final InsetsSourceControl[] mTempControls = new InsetsSourceControl[SIZE];
final ViewTreeObserver.InternalInsetsInfo mLastGivenInsets
= new ViewTreeObserver.InternalInsetsInfo();
@@ -2314,7 +2314,7 @@ public final class ViewRootImpl implements ViewParent,
|| lp.type == TYPE_VOLUME_OVERLAY;
}
- private int dipToPx(int dip) {
+ int dipToPx(int dip) {
final DisplayMetrics displayMetrics = mContext.getResources().getDisplayMetrics();
return (int) (displayMetrics.density * dip + 0.5f);
}
@@ -4616,6 +4616,9 @@ public final class ViewRootImpl implements ViewParent,
}
void dispatchDetachedFromWindow() {
+ // Make sure we free-up insets resources if view never received onWindowFocusLost()
+ // because of a die-signal
+ mInsetsController.onWindowFocusLost();
mFirstInputStage.onDetachedFromWindow();
if (mView != null && mView.mAttachInfo != null) {
mAttachInfo.mTreeObserver.dispatchOnWindowAttachedChange(false);
diff --git a/core/java/android/view/ViewRootInsetsControllerHost.java b/core/java/android/view/ViewRootInsetsControllerHost.java
index 686d561a1a5a..90a80cefc54d 100644
--- a/core/java/android/view/ViewRootInsetsControllerHost.java
+++ b/core/java/android/view/ViewRootInsetsControllerHost.java
@@ -22,6 +22,7 @@ import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_BEHAVIOR_CONT
import android.annotation.NonNull;
import android.os.Handler;
+import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.view.inputmethod.InputMethodManager;
@@ -120,13 +121,12 @@ public class ViewRootInsetsControllerHost implements InsetsController.Host {
mApplier = new SyncRtSurfaceTransactionApplier(mViewRoot.mView);
}
if (mViewRoot.mView.isHardwareAccelerated()) {
- mApplier.scheduleApply(false /* earlyWakeup */, params);
+ mApplier.scheduleApply(params);
} else {
// Window doesn't support hardware acceleration, no synchronization for now.
// TODO(b/149342281): use mViewRoot.mSurface.getNextFrameNumber() to sync on every
// frame instead.
- mApplier.applyParams(new SurfaceControl.Transaction(), -1 /* frame */,
- false /* earlyWakeup */, params);
+ mApplier.applyParams(new SurfaceControl.Transaction(), -1 /* frame */, params);
}
}
@@ -229,4 +229,24 @@ public class ViewRootInsetsControllerHost implements InsetsController.Host {
}
return mViewRoot.getTitle().toString();
}
+
+ @Override
+ public int dipToPx(int dips) {
+ if (mViewRoot != null) {
+ return mViewRoot.dipToPx(dips);
+ }
+ return 0;
+ }
+
+ @Override
+ public IBinder getWindowToken() {
+ if (mViewRoot == null) {
+ return null;
+ }
+ final View view = mViewRoot.getView();
+ if (view == null) {
+ return null;
+ }
+ return view.getWindowToken();
+ }
}
diff --git a/core/java/android/view/WindowInsetsAnimationController.java b/core/java/android/view/WindowInsetsAnimationController.java
index fb9d05e2d730..792b974558bb 100644
--- a/core/java/android/view/WindowInsetsAnimationController.java
+++ b/core/java/android/view/WindowInsetsAnimationController.java
@@ -181,4 +181,11 @@ public interface WindowInsetsAnimationController {
* @return {@code true} if the instance is cancelled, {@code false} otherwise.
*/
boolean isCancelled();
+
+ /**
+ * @hide
+ * @return {@code true} when controller controls IME and IME has no insets (floating,
+ * fullscreen or non-overlapping).
+ */
+ boolean hasZeroInsetsIme();
}
diff --git a/core/java/android/view/WindowInsetsController.java b/core/java/android/view/WindowInsetsController.java
index 3d348efc7f0f..1a9003581078 100644
--- a/core/java/android/view/WindowInsetsController.java
+++ b/core/java/android/view/WindowInsetsController.java
@@ -222,6 +222,13 @@ public interface WindowInsetsController {
@Behavior int getSystemBarsBehavior();
/**
+ * Disables or enables the animations.
+ *
+ * @hide
+ */
+ void setAnimationsDisabled(boolean disable);
+
+ /**
* @hide
*/
InsetsState getState();
diff --git a/core/java/android/view/autofill/AutofillId.java b/core/java/android/view/autofill/AutofillId.java
index 68943bf2a83a..32b9cf7cdbb0 100644
--- a/core/java/android/view/autofill/AutofillId.java
+++ b/core/java/android/view/autofill/AutofillId.java
@@ -73,6 +73,8 @@ public final class AutofillId implements Parcelable {
}
/** @hide */
+ @NonNull
+ @TestApi
public static AutofillId withoutSession(@NonNull AutofillId id) {
final int flags = id.mFlags & ~FLAG_HAS_SESSION;
final long virtualChildId =
diff --git a/core/java/android/view/contentcapture/MainContentCaptureSession.java b/core/java/android/view/contentcapture/MainContentCaptureSession.java
index 6eb71f747be6..c43beea98c7e 100644
--- a/core/java/android/view/contentcapture/MainContentCaptureSession.java
+++ b/core/java/android/view/contentcapture/MainContentCaptureSession.java
@@ -52,6 +52,7 @@ import android.view.contentcapture.ViewNode.ViewStructureImpl;
import com.android.internal.os.IResultReceiver;
import java.io.PrintWriter;
+import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -146,7 +147,44 @@ public final class MainContentCaptureSession extends ContentCaptureSession {
* Binder object used to update the session state.
*/
@NonNull
- private final IResultReceiver.Stub mSessionStateReceiver;
+ private final SessionStateReceiver mSessionStateReceiver;
+
+ private static class SessionStateReceiver extends IResultReceiver.Stub {
+ private final WeakReference<MainContentCaptureSession> mMainSession;
+
+ SessionStateReceiver(MainContentCaptureSession session) {
+ mMainSession = new WeakReference<>(session);
+ }
+
+ @Override
+ public void send(int resultCode, Bundle resultData) {
+ final MainContentCaptureSession mainSession = mMainSession.get();
+ if (mainSession == null) {
+ Log.w(TAG, "received result after mina session released");
+ return;
+ }
+ final IBinder binder;
+ if (resultData != null) {
+ // Change in content capture enabled.
+ final boolean hasEnabled = resultData.getBoolean(EXTRA_ENABLED_STATE);
+ if (hasEnabled) {
+ final boolean disabled = (resultCode == RESULT_CODE_FALSE);
+ mainSession.mDisabled.set(disabled);
+ return;
+ }
+ binder = resultData.getBinder(EXTRA_BINDER);
+ if (binder == null) {
+ Log.wtf(TAG, "No " + EXTRA_BINDER + " extra result");
+ mainSession.mHandler.post(() -> mainSession.resetSession(
+ STATE_DISABLED | STATE_INTERNAL_ERROR));
+ return;
+ }
+ } else {
+ binder = null;
+ }
+ mainSession.mHandler.post(() -> mainSession.onSessionStarted(resultCode, binder));
+ }
+ }
protected MainContentCaptureSession(@NonNull Context context,
@NonNull ContentCaptureManager manager, @NonNull Handler handler,
@@ -159,32 +197,7 @@ public final class MainContentCaptureSession extends ContentCaptureSession {
final int logHistorySize = mManager.mOptions.logHistorySize;
mFlushHistory = logHistorySize > 0 ? new LocalLog(logHistorySize) : null;
- mSessionStateReceiver = new IResultReceiver.Stub() {
- @Override
- public void send(int resultCode, Bundle resultData) {
- final IBinder binder;
- if (resultData != null) {
- // Change in content capture enabled.
- final boolean hasEnabled = resultData.getBoolean(EXTRA_ENABLED_STATE);
- if (hasEnabled) {
- final boolean disabled = (resultCode == RESULT_CODE_FALSE);
- mDisabled.set(disabled);
- return;
- }
- binder = resultData.getBinder(EXTRA_BINDER);
- if (binder == null) {
- Log.wtf(TAG, "No " + EXTRA_BINDER + " extra result");
- mHandler.post(() -> resetSession(
- STATE_DISABLED | STATE_INTERNAL_ERROR));
- return;
- }
- } else {
- binder = null;
- }
- mHandler.post(() -> onSessionStarted(resultCode, binder));
- }
- };
-
+ mSessionStateReceiver = new SessionStateReceiver(this);
}
@Override
@@ -543,6 +556,11 @@ public final class MainContentCaptureSession extends ContentCaptureSession {
Log.e(TAG, "Error destroying system-service session " + mId + " for "
+ getDebugState() + ": " + e);
}
+
+ if (mDirectServiceInterface != null) {
+ mDirectServiceInterface.asBinder().unlinkToDeath(mDirectServiceVulture, 0);
+ }
+ mDirectServiceInterface = null;
}
// TODO(b/122454205): once we support multiple sessions, we might need to move some of these
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 477dd1d13295..aedb59bfee42 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -19,6 +19,9 @@ package android.view.inputmethod;
import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
import static android.Manifest.permission.WRITE_SECURE_SETTINGS;
+import static com.android.internal.inputmethod.StartInputReason.WINDOW_FOCUS_GAIN_REPORT_WITHOUT_EDITOR;
+import static com.android.internal.inputmethod.StartInputReason.WINDOW_FOCUS_GAIN_REPORT_WITH_SAME_EDITOR;
+
import android.annotation.DrawableRes;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -538,6 +541,19 @@ public final class InputMethodManager {
return servedView.hasWindowFocus() || isAutofillUIShowing(servedView);
}
+ /**
+ * Reports whether the IME is currently perceptible or not, according to the leash applied by
+ * {@link android.view.WindowInsetsController}.
+ * @hide
+ */
+ public void reportPerceptible(IBinder windowToken, boolean perceptible) {
+ try {
+ mService.reportPerceptible(windowToken, perceptible);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
private final class DelegateImpl implements
ImeFocusController.InputMethodManagerDelegate {
/**
@@ -622,8 +638,11 @@ public final class InputMethodManager {
Log.v(TAG, "Reporting focus gain, without startInput"
+ ", nextFocusIsServedView=" + nextFocusIsServedView);
}
+ final int startInputReason =
+ nextFocusIsServedView ? WINDOW_FOCUS_GAIN_REPORT_WITH_SAME_EDITOR
+ : WINDOW_FOCUS_GAIN_REPORT_WITHOUT_EDITOR;
mService.startInputOrWindowGainedFocus(
- StartInputReason.WINDOW_FOCUS_GAIN_REPORT_ONLY, mClient,
+ startInputReason, mClient,
focusedView.getWindowToken(), startInputFlags, softInputMode,
windowFlags,
nextFocusIsServedView ? mCurrentTextBoxAttribute : null,
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 51d37a53f21f..07a721f5a9c9 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -6354,6 +6354,8 @@ public class Editor {
// The offsets of that last touch down event. Remembered to start selection there.
private int mMinTouchOffset, mMaxTouchOffset;
+ private boolean mGestureStayedInTapRegion;
+
// Where the user first starts the drag motion.
private int mStartOffset = -1;
@@ -6460,8 +6462,10 @@ public class Editor {
eventX, eventY);
// Double tap detection
- if (mTouchState.isMultiTapInSameArea() && (isMouse
- || mTouchState.isOnHandle() || isPositionOnText(eventX, eventY))) {
+ if (mGestureStayedInTapRegion
+ && mTouchState.isMultiTapInSameArea()
+ && (isMouse || isPositionOnText(eventX, eventY)
+ || mTouchState.isOnHandle())) {
if (TextView.DEBUG_CURSOR) {
logCursor("SelectionModifierCursorController: onTouchEvent",
"ACTION_DOWN: select and start drag");
@@ -6473,6 +6477,7 @@ public class Editor {
}
mDiscardNextActionUp = true;
}
+ mGestureStayedInTapRegion = true;
mHaventMovedEnoughToStartDrag = true;
}
break;
@@ -6488,6 +6493,14 @@ public class Editor {
break;
case MotionEvent.ACTION_MOVE:
+ if (mGestureStayedInTapRegion) {
+ final ViewConfiguration viewConfig = ViewConfiguration.get(
+ mTextView.getContext());
+ mGestureStayedInTapRegion = EditorTouchState.isDistanceWithin(
+ mTouchState.getLastDownX(), mTouchState.getLastDownY(),
+ eventX, eventY, viewConfig.getScaledDoubleTapTouchSlop());
+ }
+
if (mHaventMovedEnoughToStartDrag) {
mHaventMovedEnoughToStartDrag = !mTouchState.isMovedEnoughForDrag();
}
diff --git a/core/java/android/widget/ToastPresenter.java b/core/java/android/widget/ToastPresenter.java
index 2679c69be4f6..fb5d55dd2141 100644
--- a/core/java/android/widget/ToastPresenter.java
+++ b/core/java/android/widget/ToastPresenter.java
@@ -27,7 +27,6 @@ import android.content.res.Resources;
import android.graphics.PixelFormat;
import android.os.IBinder;
import android.os.RemoteException;
-import android.os.UserHandle;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
@@ -90,7 +89,7 @@ public class ToastPresenter {
// context to it. This is problematic for multi-user because callers can pass a context
// created via Context.createContextAsUser().
mAccessibilityManager = new AccessibilityManager(context, accessibilityManager,
- UserHandle.getCallingUserId());
+ context.getUserId());
mParams = createLayoutParams();
}
diff --git a/core/java/android/widget/inline/InlineContentView.java b/core/java/android/widget/inline/InlineContentView.java
index 6a85de5ca757..9e3a292440ab 100644
--- a/core/java/android/widget/inline/InlineContentView.java
+++ b/core/java/android/widget/inline/InlineContentView.java
@@ -20,6 +20,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
import android.graphics.PixelFormat;
+import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceControl;
@@ -27,6 +28,7 @@ import android.view.SurfaceControlViewHost;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.ViewGroup;
+import android.view.ViewTreeObserver.OnPreDrawListener;
import java.util.function.Consumer;
@@ -130,6 +132,16 @@ public class InlineContentView extends ViewGroup {
@Nullable
private SurfacePackageUpdater mSurfacePackageUpdater;
+ @NonNull
+ private final OnPreDrawListener mDrawListener = new OnPreDrawListener() {
+ @Override
+ public boolean onPreDraw() {
+ int visibility = InlineContentView.this.isShown() ? VISIBLE : GONE;
+ mSurfaceView.setVisibility(visibility);
+ return true;
+ }
+ };
+
/**
* @inheritDoc
* @hide
@@ -153,6 +165,7 @@ public class InlineContentView extends ViewGroup {
public InlineContentView(@NonNull Context context, @Nullable AttributeSet attrs,
int defStyleAttr) {
this(context, attrs, defStyleAttr, 0);
+ mSurfaceView.setEnableSurfaceClipping(true);
}
/**
@@ -166,6 +179,12 @@ public class InlineContentView extends ViewGroup {
return mSurfaceView.getSurfaceControl();
}
+ @Override
+ public void setClipBounds(Rect clipBounds) {
+ super.setClipBounds(clipBounds);
+ mSurfaceView.setClipBounds(clipBounds);
+ }
+
/**
* @inheritDoc
* @hide
@@ -202,6 +221,8 @@ public class InlineContentView extends ViewGroup {
}
});
}
+ mSurfaceView.setVisibility(VISIBLE);
+ getViewTreeObserver().addOnPreDrawListener(mDrawListener);
}
@Override
@@ -211,6 +232,7 @@ public class InlineContentView extends ViewGroup {
if (mSurfacePackageUpdater != null) {
mSurfacePackageUpdater.onSurfacePackageReleased();
}
+ getViewTreeObserver().removeOnPreDrawListener(mDrawListener);
}
@Override
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 0a1e3a0caeff..a30c3c52f42c 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -195,6 +195,7 @@ public class ChooserActivity extends ResolverActivity implements
private boolean mIsAppPredictorComponentAvailable;
private Map<ChooserTarget, AppTarget> mDirectShareAppTargetCache;
private Map<ChooserTarget, ShortcutInfo> mDirectShareShortcutInfoCache;
+ private Map<ComponentName, ComponentName> mChooserTargetComponentNameCache;
public static final int TARGET_TYPE_DEFAULT = 0;
public static final int TARGET_TYPE_CHOOSER_TARGET = 1;
@@ -511,6 +512,11 @@ public class ChooserActivity extends ResolverActivity implements
adapterForUserHandle.addServiceResults(sri.originalTarget,
sri.resultTargets, TARGET_TYPE_CHOOSER_TARGET,
/* directShareShortcutInfoCache */ null, mServiceConnections);
+ if (!sri.resultTargets.isEmpty() && sri.originalTarget != null) {
+ mChooserTargetComponentNameCache.put(
+ sri.resultTargets.get(0).getComponentName(),
+ sri.originalTarget.getResolvedComponentName());
+ }
}
}
unbindService(sri.connection);
@@ -685,8 +691,14 @@ public class ChooserActivity extends ResolverActivity implements
mPinnedSharedPrefs = getPinnedSharedPrefs(this);
pa = intent.getParcelableArrayExtra(Intent.EXTRA_EXCLUDE_COMPONENTS);
+
+
+ // Exclude out Nearby from main list if chip is present, to avoid duplication
+ ComponentName nearbySharingComponent = getNearbySharingComponent();
+ boolean hasNearby = nearbySharingComponent != null;
+
if (pa != null) {
- ComponentName[] names = new ComponentName[pa.length];
+ ComponentName[] names = new ComponentName[pa.length + (hasNearby ? 1 : 0)];
for (int i = 0; i < pa.length; i++) {
if (!(pa[i] instanceof ComponentName)) {
Log.w(TAG, "Filtered component #" + i + " not a ComponentName: " + pa[i]);
@@ -695,7 +707,14 @@ public class ChooserActivity extends ResolverActivity implements
}
names[i] = (ComponentName) pa[i];
}
+ if (hasNearby) {
+ names[names.length - 1] = nearbySharingComponent;
+ }
+
mFilteredComponentNames = names;
+ } else if (hasNearby) {
+ mFilteredComponentNames = new ComponentName[1];
+ mFilteredComponentNames[0] = nearbySharingComponent;
}
pa = intent.getParcelableArrayExtra(Intent.EXTRA_CHOOSER_TARGETS);
@@ -772,6 +791,7 @@ public class ChooserActivity extends ResolverActivity implements
target.getAction()
);
mDirectShareShortcutInfoCache = new HashMap<>();
+ mChooserTargetComponentNameCache = new HashMap<>();
}
@Override
@@ -997,11 +1017,17 @@ public class ChooserActivity extends ResolverActivity implements
/**
* Update UI to reflect changes in data.
- * <p>If {@code listAdapter} is {@code null}, both profile list adapters are updated.
+ * <p>If {@code listAdapter} is {@code null}, both profile list adapters are updated if
+ * available.
*/
private void handlePackagesChanged(@Nullable ResolverListAdapter listAdapter) {
+ // Refresh pinned items
+ mPinnedSharedPrefs = getPinnedSharedPrefs(this);
if (listAdapter == null) {
mChooserMultiProfilePagerAdapter.getActiveListAdapter().handlePackagesChanged();
+ if (mChooserMultiProfilePagerAdapter.getCount() > 1) {
+ mChooserMultiProfilePagerAdapter.getInactiveListAdapter().handlePackagesChanged();
+ }
} else {
listAdapter.handlePackagesChanged();
}
@@ -1063,6 +1089,10 @@ public class ChooserActivity extends ResolverActivity implements
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
+ ViewPager viewPager = findViewById(R.id.profile_pager);
+ if (shouldShowTabs() && viewPager.isLayoutRtl()) {
+ mMultiProfilePagerAdapter.setupViewPager(viewPager);
+ }
mShouldDisplayLandscape = shouldDisplayLandscape(newConfig.orientation);
adjustPreviewWidth(newConfig.orientation, null);
@@ -2238,15 +2268,18 @@ public class ChooserActivity extends ResolverActivity implements
List<AppTargetId> targetIds = new ArrayList<>();
for (ChooserTargetInfo chooserTargetInfo : surfacedTargetInfo) {
ChooserTarget chooserTarget = chooserTargetInfo.getChooserTarget();
- String componentName = chooserTarget.getComponentName().flattenToString();
+ ComponentName componentName = mChooserTargetComponentNameCache.getOrDefault(
+ chooserTarget.getComponentName(), chooserTarget.getComponentName());
if (mDirectShareShortcutInfoCache.containsKey(chooserTarget)) {
String shortcutId = mDirectShareShortcutInfoCache.get(chooserTarget).getId();
targetIds.add(new AppTargetId(
- String.format("%s/%s/%s", shortcutId, componentName, SHORTCUT_TARGET)));
+ String.format("%s/%s/%s", shortcutId, componentName.flattenToString(),
+ SHORTCUT_TARGET)));
} else {
String titleHash = ChooserUtil.md5(chooserTarget.getTitle().toString());
targetIds.add(new AppTargetId(
- String.format("%s/%s/%s", titleHash, componentName, CHOOSER_TARGET)));
+ String.format("%s/%s/%s", titleHash, componentName.flattenToString(),
+ CHOOSER_TARGET)));
}
}
directShareAppPredictor.notifyLaunchLocationShown(LAUNCH_LOCATION_DIRECT_SHARE, targetIds);
@@ -2268,7 +2301,8 @@ public class ChooserActivity extends ResolverActivity implements
}
if (mChooserTargetRankingEnabled && appTarget == null) {
// Send ChooserTarget sharing info to AppPredictor.
- ComponentName componentName = chooserTarget.getComponentName();
+ ComponentName componentName = mChooserTargetComponentNameCache.getOrDefault(
+ chooserTarget.getComponentName(), chooserTarget.getComponentName());
try {
appTarget = new AppTarget.Builder(
new AppTargetId(componentName.flattenToString()),
@@ -2796,17 +2830,7 @@ public class ChooserActivity extends ResolverActivity implements
|| chooserListAdapter.mDisplayList.isEmpty()) {
chooserListAdapter.notifyDataSetChanged();
} else {
- new AsyncTask<Void, Void, Void>() {
- @Override
- protected Void doInBackground(Void... voids) {
- chooserListAdapter.updateAlphabeticalList();
- return null;
- }
- @Override
- protected void onPostExecute(Void aVoid) {
- chooserListAdapter.notifyDataSetChanged();
- }
- }.execute();
+ chooserListAdapter.updateAlphabeticalList();
}
// don't support direct share on low ram devices
diff --git a/core/java/com/android/internal/app/ChooserListAdapter.java b/core/java/com/android/internal/app/ChooserListAdapter.java
index d6ff7b13c934..5efd46c4c64a 100644
--- a/core/java/com/android/internal/app/ChooserListAdapter.java
+++ b/core/java/com/android/internal/app/ChooserListAdapter.java
@@ -275,33 +275,43 @@ public class ChooserListAdapter extends ResolverListAdapter {
}
void updateAlphabeticalList() {
- mSortedList.clear();
- List<DisplayResolveInfo> tempList = new ArrayList<>();
- tempList.addAll(mDisplayList);
- tempList.addAll(mCallerTargets);
- if (mEnableStackedApps) {
- // Consolidate multiple targets from same app.
- Map<String, DisplayResolveInfo> consolidated = new HashMap<>();
- for (DisplayResolveInfo info : tempList) {
- String packageName = info.getResolvedComponentName().getPackageName();
- DisplayResolveInfo multiDri = consolidated.get(packageName);
- if (multiDri == null) {
- consolidated.put(packageName, info);
- } else if (multiDri instanceof MultiDisplayResolveInfo) {
- ((MultiDisplayResolveInfo) multiDri).addTarget(info);
- } else {
- // create consolidated target from the single DisplayResolveInfo
- MultiDisplayResolveInfo multiDisplayResolveInfo =
+ new AsyncTask<Void, Void, List<DisplayResolveInfo>>() {
+ @Override
+ protected List<DisplayResolveInfo> doInBackground(Void... voids) {
+ List<DisplayResolveInfo> allTargets = new ArrayList<>();
+ allTargets.addAll(mDisplayList);
+ allTargets.addAll(mCallerTargets);
+ if (!mEnableStackedApps) {
+ return allTargets;
+ }
+ // Consolidate multiple targets from same app.
+ Map<String, DisplayResolveInfo> consolidated = new HashMap<>();
+ for (DisplayResolveInfo info : allTargets) {
+ String packageName = info.getResolvedComponentName().getPackageName();
+ DisplayResolveInfo multiDri = consolidated.get(packageName);
+ if (multiDri == null) {
+ consolidated.put(packageName, info);
+ } else if (multiDri instanceof MultiDisplayResolveInfo) {
+ ((MultiDisplayResolveInfo) multiDri).addTarget(info);
+ } else {
+ // create consolidated target from the single DisplayResolveInfo
+ MultiDisplayResolveInfo multiDisplayResolveInfo =
new MultiDisplayResolveInfo(packageName, multiDri);
- multiDisplayResolveInfo.addTarget(info);
- consolidated.put(packageName, multiDisplayResolveInfo);
+ multiDisplayResolveInfo.addTarget(info);
+ consolidated.put(packageName, multiDisplayResolveInfo);
+ }
}
+ List<DisplayResolveInfo> groupedTargets = new ArrayList<>();
+ groupedTargets.addAll(consolidated.values());
+ Collections.sort(groupedTargets, new ChooserActivity.AzInfoComparator(mContext));
+ return groupedTargets;
}
- mSortedList.addAll(consolidated.values());
- } else {
- mSortedList.addAll(tempList);
- }
- Collections.sort(mSortedList, new ChooserActivity.AzInfoComparator(mContext));
+ @Override
+ protected void onPostExecute(List<DisplayResolveInfo> newList) {
+ mSortedList = newList;
+ notifyDataSetChanged();
+ }
+ }.execute();
}
@Override
@@ -828,6 +838,12 @@ public class ChooserListAdapter extends ResolverListAdapter {
return mServiceTargets.get(value).getChooserTarget();
}
+ protected boolean alwaysShowSubLabel() {
+ // Always show a subLabel for visual consistency across list items. Show an empty
+ // subLabel if the subLabel is the same as the label
+ return true;
+ }
+
/**
* Rather than fully sorting the input list, this sorting task will put the top k elements
* in the head of input list and fill the tail with other elements in undetermined order.
diff --git a/core/java/com/android/internal/app/IAppOpsService.aidl b/core/java/com/android/internal/app/IAppOpsService.aidl
index e614a0eb996b..51e56b7fca43 100644
--- a/core/java/com/android/internal/app/IAppOpsService.aidl
+++ b/core/java/com/android/internal/app/IAppOpsService.aidl
@@ -36,10 +36,10 @@ interface IAppOpsService {
// and not be reordered
int checkOperation(int code, int uid, String packageName);
int noteOperation(int code, int uid, String packageName, @nullable String attributionTag,
- boolean shouldCollectAsyncNotedOp, String message);
+ boolean shouldCollectAsyncNotedOp, String message, boolean shouldCollectMessage);
int startOperation(IBinder clientId, int code, int uid, String packageName,
@nullable String attributionTag, boolean startIfModeDefault,
- boolean shouldCollectAsyncNotedOp, String message);
+ boolean shouldCollectAsyncNotedOp, String message, boolean shouldCollectMessage);
@UnsupportedAppUsage
void finishOperation(IBinder clientId, int code, int uid, String packageName,
@nullable String attributionTag);
@@ -54,7 +54,8 @@ interface IAppOpsService {
int noteProxyOperation(int code, int proxiedUid, String proxiedPackageName,
String proxiedAttributionTag, int proxyUid, String proxyPackageName,
- String proxyAttributionTag, boolean shouldCollectAsyncNotedOp, String message);
+ String proxyAttributionTag, boolean shouldCollectAsyncNotedOp, String message,
+ boolean shouldCollectMessage);
// Remaining methods are only used in Java.
int checkPackage(int uid, String packageName);
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index daacd459a1a7..86c13a0581c2 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -1938,7 +1938,7 @@ public class ResolverActivity extends Activity implements
ResolverListAdapter activeListAdapter =
mMultiProfilePagerAdapter.getActiveListAdapter();
activeListAdapter.notifyDataSetChanged();
- if (activeListAdapter.getCount() == 0) {
+ if (activeListAdapter.getCount() == 0 && !inactiveListAdapterHasItems()) {
// We no longer have any items... just finish the activity.
finish();
}
@@ -1948,6 +1948,13 @@ public class ResolverActivity extends Activity implements
}
}
+ private boolean inactiveListAdapterHasItems() {
+ if (!shouldShowTabs()) {
+ return false;
+ }
+ return mMultiProfilePagerAdapter.getInactiveListAdapter().getCount() > 0;
+ }
+
private BroadcastReceiver createWorkProfileStateReceiver() {
return new BroadcastReceiver() {
@Override
diff --git a/core/java/com/android/internal/app/ResolverListAdapter.java b/core/java/com/android/internal/app/ResolverListAdapter.java
index d63ebda5117e..094fb1e2f23c 100644
--- a/core/java/com/android/internal/app/ResolverListAdapter.java
+++ b/core/java/com/android/internal/app/ResolverListAdapter.java
@@ -427,6 +427,8 @@ public class ResolverListAdapter extends BaseAdapter {
&& dri.getResolveInfo().targetUserId == UserHandle.USER_CURRENT) {
if (shouldAddResolveInfo(dri)) {
mDisplayList.add(dri);
+ Log.i(TAG, "Add DisplayResolveInfo component: " + dri.getResolvedComponentName()
+ + ", intent component: " + dri.getResolvedIntent().getComponent());
}
}
}
@@ -538,7 +540,7 @@ public class ResolverListAdapter extends BaseAdapter {
&& !((DisplayResolveInfo) info).hasDisplayLabel()) {
getLoadLabelTask((DisplayResolveInfo) info, holder).execute();
} else {
- holder.bindLabel(info.getDisplayLabel(), info.getExtendedInfo());
+ holder.bindLabel(info.getDisplayLabel(), info.getExtendedInfo(), alwaysShowSubLabel());
if (info instanceof SelectableTargetInfo) {
// direct share targets should append the application name for a better readout
DisplayResolveInfo rInfo = ((SelectableTargetInfo) info).getDisplayResolveInfo();
@@ -640,6 +642,10 @@ public class ResolverListAdapter extends BaseAdapter {
mIsTabLoaded = true;
}
+ protected boolean alwaysShowSubLabel() {
+ return false;
+ }
+
/**
* Necessary methods to communicate between {@link ResolverListAdapter}
* and {@link ResolverActivity}.
@@ -682,20 +688,18 @@ public class ResolverListAdapter extends BaseAdapter {
icon = (ImageView) view.findViewById(R.id.icon);
}
- public void bindLabel(CharSequence label, CharSequence subLabel) {
- if (!TextUtils.equals(text.getText(), label)) {
- text.setText(label);
- }
+ public void bindLabel(CharSequence label, CharSequence subLabel, boolean showSubLabel) {
+ text.setText(label);
- // Always show a subLabel for visual consistency across list items. Show an empty
- // subLabel if the subLabel is the same as the label
if (TextUtils.equals(label, subLabel)) {
subLabel = null;
}
- if (!TextUtils.equals(text2.getText(), subLabel)) {
+ text2.setText(subLabel);
+ if (showSubLabel || subLabel != null) {
text2.setVisibility(View.VISIBLE);
- text2.setText(subLabel);
+ } else {
+ text2.setVisibility(View.GONE);
}
itemView.setContentDescription(null);
@@ -752,7 +756,7 @@ public class ResolverListAdapter extends BaseAdapter {
protected void onPostExecute(CharSequence[] result) {
mDisplayResolveInfo.setDisplayLabel(result[0]);
mDisplayResolveInfo.setExtendedInfo(result[1]);
- mHolder.bindLabel(result[0], result[1]);
+ mHolder.bindLabel(result[0], result[1], alwaysShowSubLabel());
}
}
diff --git a/core/java/com/android/internal/app/ResolverViewPager.java b/core/java/com/android/internal/app/ResolverViewPager.java
index 9cdfc2f5c763..478cc18f13ee 100644
--- a/core/java/com/android/internal/app/ResolverViewPager.java
+++ b/core/java/com/android/internal/app/ResolverViewPager.java
@@ -74,12 +74,16 @@ public class ResolverViewPager extends ViewPager {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
+ /**
+ * Sets whether swiping sideways should happen.
+ * <p>Note that swiping is always disabled for RTL layouts (b/159110029 for context).
+ */
void setSwipingEnabled(boolean swipingEnabled) {
mSwipingEnabled = swipingEnabled;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
- return mSwipingEnabled && super.onInterceptTouchEvent(ev);
+ return !isLayoutRtl() && mSwipingEnabled && super.onInterceptTouchEvent(ev);
}
}
diff --git a/core/java/com/android/internal/app/UnlaunchableAppActivity.java b/core/java/com/android/internal/app/UnlaunchableAppActivity.java
index 6f7695ce8c34..ca0856238b90 100644
--- a/core/java/com/android/internal/app/UnlaunchableAppActivity.java
+++ b/core/java/com/android/internal/app/UnlaunchableAppActivity.java
@@ -26,6 +26,8 @@ import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentSender;
import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.Log;
@@ -97,7 +99,10 @@ public class UnlaunchableAppActivity extends Activity
@Override
public void onClick(DialogInterface dialog, int which) {
if (mReason == UNLAUNCHABLE_REASON_QUIET_MODE && which == DialogInterface.BUTTON_POSITIVE) {
- UserManager.get(this).requestQuietModeEnabled(false, UserHandle.of(mUserId), mTarget);
+ UserManager userManager = UserManager.get(this);
+ new Handler(Looper.getMainLooper()).post(
+ () -> userManager.requestQuietModeEnabled(
+ /* enableQuietMode= */ false, UserHandle.of(mUserId), mTarget));
}
}
diff --git a/core/java/com/android/internal/app/procstats/ProcessStats.java b/core/java/com/android/internal/app/procstats/ProcessStats.java
index 7455ad009873..11e55b852516 100644
--- a/core/java/com/android/internal/app/procstats/ProcessStats.java
+++ b/core/java/com/android/internal/app/procstats/ProcessStats.java
@@ -2232,24 +2232,43 @@ public final class ProcessStats implements Parcelable {
}
/** Similar to {@code #dumpDebug}, but with a reduced/aggregated subset of states. */
- public void dumpAggregatedProtoForStatsd(ProtoOutputStream proto) {
- dumpProtoPreamble(proto);
+ public void dumpAggregatedProtoForStatsd(ProtoOutputStream[] protoStreams,
+ long maxRawShardSizeBytes) {
+ int shardIndex = 0;
+ dumpProtoPreamble(protoStreams[shardIndex]);
+
final ArrayMap<String, SparseArray<ProcessState>> procMap = mProcesses.getMap();
final ProcessMap<ArraySet<PackageState>> procToPkgMap = new ProcessMap<>();
final SparseArray<ArraySet<String>> uidToPkgMap = new SparseArray<>();
collectProcessPackageMaps(null, false, procToPkgMap, uidToPkgMap);
+
for (int ip = 0; ip < procMap.size(); ip++) {
final String procName = procMap.keyAt(ip);
+ if (protoStreams[shardIndex].getRawSize() > maxRawShardSizeBytes) {
+ shardIndex++;
+ if (shardIndex >= protoStreams.length) {
+ // We have run out of space; we'll drop the rest of the processes.
+ Slog.d(TAG, String.format("Dropping process indices from %d to %d from "
+ + "statsd proto (too large)", ip, procMap.size()));
+ break;
+ }
+ dumpProtoPreamble(protoStreams[shardIndex]);
+ }
+
final SparseArray<ProcessState> uids = procMap.valueAt(ip);
for (int iu = 0; iu < uids.size(); iu++) {
final int uid = uids.keyAt(iu);
final ProcessState procState = uids.valueAt(iu);
- procState.dumpAggregatedProtoForStatsd(proto,
+ procState.dumpAggregatedProtoForStatsd(protoStreams[shardIndex],
ProcessStatsSectionProto.PROCESS_STATS,
procName, uid, mTimePeriodEndRealtime,
procToPkgMap, uidToPkgMap);
}
}
+
+ for (int i = 0; i <= shardIndex; i++) {
+ protoStreams[i].flush();
+ }
}
private void dumpProtoPreamble(ProtoOutputStream proto) {
@@ -2403,10 +2422,11 @@ public final class ProcessStats implements Parcelable {
final SourceKey key = assocVals.keyAt(i);
final long[] vals = assocVals.valueAt(i);
final long token = proto.start(fieldId);
+ final int idx = uidToPkgMap.indexOfKey(key.mUid);
ProcessState.writeCompressedProcessName(proto,
ProcessStatsAssociationProto.ASSOC_PROCESS_NAME,
key.mProcess, key.mPackage,
- uidToPkgMap.get(key.mUid).size() > 1);
+ idx >= 0 && uidToPkgMap.valueAt(idx).size() > 1);
proto.write(ProcessStatsAssociationProto.ASSOC_UID, key.mUid);
proto.write(ProcessStatsAssociationProto.TOTAL_COUNT, (int) vals[1]);
proto.write(ProcessStatsAssociationProto.TOTAL_DURATION_SECS,
diff --git a/core/java/com/android/internal/infra/ServiceConnector.java b/core/java/com/android/internal/infra/ServiceConnector.java
index e9d7d05fe68d..167d128a76f8 100644
--- a/core/java/com/android/internal/infra/ServiceConnector.java
+++ b/core/java/com/android/internal/infra/ServiceConnector.java
@@ -709,7 +709,7 @@ public interface ServiceConnector<I extends IInterface> {
if (DEBUG) {
return mDebugName;
}
- return mDelegate.toString() + " wrapped into " + super.toString();
+ return mDelegate + " wrapped into " + super.toString();
}
@Override
diff --git a/core/java/com/android/internal/inputmethod/InputMethodDebug.java b/core/java/com/android/internal/inputmethod/InputMethodDebug.java
index a660493f4613..085cdfcf9462 100644
--- a/core/java/com/android/internal/inputmethod/InputMethodDebug.java
+++ b/core/java/com/android/internal/inputmethod/InputMethodDebug.java
@@ -46,8 +46,10 @@ public final class InputMethodDebug {
return "UNSPECIFIED";
case StartInputReason.WINDOW_FOCUS_GAIN:
return "WINDOW_FOCUS_GAIN";
- case StartInputReason.WINDOW_FOCUS_GAIN_REPORT_ONLY:
- return "WINDOW_FOCUS_GAIN_REPORT_ONLY";
+ case StartInputReason.WINDOW_FOCUS_GAIN_REPORT_WITH_SAME_EDITOR:
+ return "WINDOW_FOCUS_GAIN_REPORT_WITH_SAME_EDITOR";
+ case StartInputReason.WINDOW_FOCUS_GAIN_REPORT_WITHOUT_EDITOR:
+ return "WINDOW_FOCUS_GAIN_REPORT_WITHOUT_EDITOR";
case StartInputReason.APP_CALLED_RESTART_INPUT_API:
return "APP_CALLED_RESTART_INPUT_API";
case StartInputReason.CHECK_FOCUS:
diff --git a/core/java/com/android/internal/inputmethod/SoftInputShowHideReason.java b/core/java/com/android/internal/inputmethod/SoftInputShowHideReason.java
index 79397b81ace7..4b968b45f122 100644
--- a/core/java/com/android/internal/inputmethod/SoftInputShowHideReason.java
+++ b/core/java/com/android/internal/inputmethod/SoftInputShowHideReason.java
@@ -46,7 +46,8 @@ import java.lang.annotation.Retention;
SoftInputShowHideReason.HIDE_SETTINGS_ON_CHANGE,
SoftInputShowHideReason.HIDE_POWER_BUTTON_GO_HOME,
SoftInputShowHideReason.HIDE_DOCKED_STACK_ATTACHED,
- SoftInputShowHideReason.HIDE_RECENTS_ANIMATION})
+ SoftInputShowHideReason.HIDE_RECENTS_ANIMATION,
+ SoftInputShowHideReason.HIDE_BUBBLES})
public @interface SoftInputShowHideReason {
/** Show soft input by {@link android.view.inputmethod.InputMethodManager#showSoftInput}. */
int SHOW_SOFT_INPUT = 0;
@@ -140,4 +141,10 @@ public @interface SoftInputShowHideReason {
* intercept touch from app window.
*/
int HIDE_RECENTS_ANIMATION = 18;
+
+ /**
+ * Hide soft input when {@link com.android.systemui.bubbles.BubbleController} is expanding,
+ * switching, or collapsing Bubbles.
+ */
+ int HIDE_BUBBLES = 19;
}
diff --git a/core/java/com/android/internal/inputmethod/StartInputReason.java b/core/java/com/android/internal/inputmethod/StartInputReason.java
index a4eaa21538f7..946ce858c12d 100644
--- a/core/java/com/android/internal/inputmethod/StartInputReason.java
+++ b/core/java/com/android/internal/inputmethod/StartInputReason.java
@@ -30,7 +30,8 @@ import java.lang.annotation.Retention;
@IntDef(value = {
StartInputReason.UNSPECIFIED,
StartInputReason.WINDOW_FOCUS_GAIN,
- StartInputReason.WINDOW_FOCUS_GAIN_REPORT_ONLY,
+ StartInputReason.WINDOW_FOCUS_GAIN_REPORT_WITH_SAME_EDITOR,
+ StartInputReason.WINDOW_FOCUS_GAIN_REPORT_WITHOUT_EDITOR,
StartInputReason.APP_CALLED_RESTART_INPUT_API,
StartInputReason.CHECK_FOCUS,
StartInputReason.BOUND_TO_IMMS,
@@ -49,45 +50,50 @@ public @interface StartInputReason {
*/
int WINDOW_FOCUS_GAIN = 1;
/**
+ * {@link android.view.Window} gained focus and the focused view is same as current served
+ * view and its input connection remains. {@link android.view.inputmethod.InputMethodManager}
+ * just reports this window focus change event to sync IME input target for system.
+ */
+ int WINDOW_FOCUS_GAIN_REPORT_WITH_SAME_EDITOR = 2;
+ /**
* {@link android.view.Window} gained focus but there is no {@link android.view.View} that is
- * eligible to have IME focus, or the focused view is same as current served view and its
- * input connection remains. {@link android.view.inputmethod.InputMethodManager} just reports
- * this window focus change event to sync IME input target for system.
+ * eligible to have IME focus. {@link android.view.inputmethod.InputMethodManager} just reports
+ * this window focus change event for logging.
*/
- int WINDOW_FOCUS_GAIN_REPORT_ONLY = 2;
+ int WINDOW_FOCUS_GAIN_REPORT_WITHOUT_EDITOR = 3;
/**
* {@link android.view.inputmethod.InputMethodManager#restartInput(android.view.View)} is
* either explicitly called by the application or indirectly called by some Framework class
* (e.g. {@link android.widget.EditText}).
*/
- int APP_CALLED_RESTART_INPUT_API = 3;
+ int APP_CALLED_RESTART_INPUT_API = 4;
/**
* {@link android.view.View} requested a new connection because of view focus change.
*/
- int CHECK_FOCUS = 4;
+ int CHECK_FOCUS = 5;
/**
* {@link android.view.inputmethod.InputMethodManager} is responding to
* {@link com.android.internal.view.IInputMethodClient#onBindMethod}.
*/
- int BOUND_TO_IMMS = 5;
+ int BOUND_TO_IMMS = 6;
/**
* {@link android.view.inputmethod.InputMethodManager} is responding to
* {@link com.android.internal.view.IInputMethodClient#onUnbindMethod}.
*/
- int UNBOUND_FROM_IMMS = 6;
+ int UNBOUND_FROM_IMMS = 7;
/**
* {@link android.view.inputmethod.InputMethodManager} is responding to
* {@link com.android.internal.view.IInputMethodClient#setActive}.
*/
- int ACTIVATED_BY_IMMS = 7;
+ int ACTIVATED_BY_IMMS = 8;
/**
* {@link android.view.inputmethod.InputMethodManager} is responding to
* {@link com.android.internal.view.IInputMethodClient#setActive}.
*/
- int DEACTIVATED_BY_IMMS = 8;
+ int DEACTIVATED_BY_IMMS = 9;
/**
* {@link com.android.server.inputmethod.InputMethodManagerService} is responding to
* {@link com.android.internal.view.IInputSessionCallback#sessionCreated}.
*/
- int SESSION_CREATED_BY_IME = 9;
+ int SESSION_CREATED_BY_IME = 10;
}
diff --git a/core/java/com/android/internal/os/FuseAppLoop.java b/core/java/com/android/internal/os/FuseAppLoop.java
index ab0cc3093b6d..2393036b5a38 100644
--- a/core/java/com/android/internal/os/FuseAppLoop.java
+++ b/core/java/com/android/internal/os/FuseAppLoop.java
@@ -210,7 +210,7 @@ public class FuseAppLoop implements Handler.Callback {
if (mInstance != 0) {
native_replySimple(mInstance, unique, FUSE_OK);
}
- mBytesMap.stopUsing(entry.getThreadId());
+ mBytesMap.stopUsing(inode);
recycleLocked(args);
}
break;
@@ -270,7 +270,7 @@ public class FuseAppLoop implements Handler.Callback {
if (mInstance != 0) {
native_replyOpen(mInstance, unique, /* fh */ inode);
entry.opened = true;
- return mBytesMap.startUsing(entry.getThreadId());
+ return mBytesMap.startUsing(inode);
}
} catch (ErrnoException error) {
replySimpleLocked(unique, getError(error));
@@ -354,27 +354,27 @@ public class FuseAppLoop implements Handler.Callback {
}
/**
- * Map between Thread ID and byte buffer.
+ * Map between inode and byte buffer.
*/
private static class BytesMap {
final Map<Long, BytesMapEntry> mEntries = new HashMap<>();
- byte[] startUsing(long threadId) {
- BytesMapEntry entry = mEntries.get(threadId);
+ byte[] startUsing(long inode) {
+ BytesMapEntry entry = mEntries.get(inode);
if (entry == null) {
entry = new BytesMapEntry();
- mEntries.put(threadId, entry);
+ mEntries.put(inode, entry);
}
entry.counter++;
return entry.bytes;
}
- void stopUsing(long threadId) {
- final BytesMapEntry entry = mEntries.get(threadId);
+ void stopUsing(long inode) {
+ final BytesMapEntry entry = mEntries.get(inode);
Objects.requireNonNull(entry);
entry.counter--;
if (entry.counter <= 0) {
- mEntries.remove(threadId);
+ mEntries.remove(inode);
}
}
diff --git a/core/java/com/android/internal/os/KernelCpuThreadReaderDiff.java b/core/java/com/android/internal/os/KernelCpuThreadReaderDiff.java
index c11b939098c4..69ca9922e81f 100644
--- a/core/java/com/android/internal/os/KernelCpuThreadReaderDiff.java
+++ b/core/java/com/android/internal/os/KernelCpuThreadReaderDiff.java
@@ -59,7 +59,7 @@ import java.util.Objects;
* #getProcessCpuUsageDiffed()} result.
*
* <p>Thresholding is done in this class, instead of {@link KernelCpuThreadReader}, and instead of
- * WestWorld, because the thresholding should be done after diffing, not before. This is because of
+ * statsd, because the thresholding should be done after diffing, not before. This is because of
* two issues with thresholding before diffing:
*
* <ul>
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java
index 505a05eb9c23..a7d9827855a2 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -24,6 +24,7 @@ import android.content.pm.ApplicationInfo;
import android.net.Credentials;
import android.net.LocalServerSocket;
import android.net.LocalSocket;
+import android.net.NetworkUtils;
import android.os.FactoryTest;
import android.os.IVold;
import android.os.Process;
@@ -286,6 +287,13 @@ public final class Zygote {
private Zygote() {}
+ private static boolean containsInetGid(int[] gids) {
+ for (int i = 0; i < gids.length; i++) {
+ if (gids[i] == android.os.Process.INET_GID) return true;
+ }
+ return false;
+ }
+
/**
* Forks a new VM instance. The current VM must have been started
* with the -Xzygote flag. <b>NOTE: new instance keeps all
@@ -341,6 +349,11 @@ public final class Zygote {
if (pid == 0) {
// Note that this event ends at the end of handleChildProc,
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "PostFork");
+
+ // If no GIDs were specified, don't make any permissions changes based on groups.
+ if (gids != null && gids.length > 0) {
+ NetworkUtils.setAllowNetworkingForProcess(containsInetGid(gids));
+ }
}
// Set the Java Language thread priority to the default value for new apps.
diff --git a/core/java/com/android/internal/policy/BackdropFrameRenderer.java b/core/java/com/android/internal/policy/BackdropFrameRenderer.java
index 7bfed91c42b9..6fe1d8140371 100644
--- a/core/java/com/android/internal/policy/BackdropFrameRenderer.java
+++ b/core/java/com/android/internal/policy/BackdropFrameRenderer.java
@@ -16,6 +16,7 @@
package com.android.internal.policy;
+import android.graphics.Insets;
import android.graphics.RecordingCanvas;
import android.graphics.Rect;
import android.graphics.RenderNode;
@@ -69,16 +70,14 @@ public class BackdropFrameRenderer extends Thread implements Choreographer.Frame
private ColorDrawable mNavigationBarColor;
private boolean mOldFullscreen;
private boolean mFullscreen;
- private final Rect mOldSystemInsets = new Rect();
- private final Rect mOldStableInsets = new Rect();
- private final Rect mSystemInsets = new Rect();
- private final Rect mStableInsets = new Rect();
+ private final Rect mOldSystemBarInsets = new Rect();
+ private final Rect mSystemBarInsets = new Rect();
private final Rect mTmpRect = new Rect();
public BackdropFrameRenderer(DecorView decorView, ThreadedRenderer renderer, Rect initialBounds,
Drawable resizingBackgroundDrawable, Drawable captionBackgroundDrawable,
Drawable userCaptionBackgroundDrawable, int statusBarColor, int navigationBarColor,
- boolean fullscreen, Rect systemInsets, Rect stableInsets) {
+ boolean fullscreen, Insets systemBarInsets) {
setName("ResizeFrame");
mRenderer = renderer;
@@ -95,10 +94,8 @@ public class BackdropFrameRenderer extends Thread implements Choreographer.Frame
mTargetRect.set(initialBounds);
mFullscreen = fullscreen;
mOldFullscreen = fullscreen;
- mSystemInsets.set(systemInsets);
- mStableInsets.set(stableInsets);
- mOldSystemInsets.set(systemInsets);
- mOldStableInsets.set(stableInsets);
+ mSystemBarInsets.set(systemBarInsets.toRect());
+ mOldSystemBarInsets.set(systemBarInsets.toRect());
// Kick off our draw thread.
start();
@@ -154,16 +151,13 @@ public class BackdropFrameRenderer extends Thread implements Choreographer.Frame
*
* @param newTargetBounds The new target bounds.
* @param fullscreen Whether the window is currently drawing in fullscreen.
- * @param systemInsets The current visible system insets for the window.
- * @param stableInsets The stable insets for the window.
+ * @param systemBarInsets The current visible system insets for the window.
*/
- public void setTargetRect(Rect newTargetBounds, boolean fullscreen, Rect systemInsets,
- Rect stableInsets) {
+ public void setTargetRect(Rect newTargetBounds, boolean fullscreen, Rect systemBarInsets) {
synchronized (this) {
mFullscreen = fullscreen;
mTargetRect.set(newTargetBounds);
- mSystemInsets.set(systemInsets);
- mStableInsets.set(stableInsets);
+ mSystemBarInsets.set(systemBarInsets);
// Notify of a bounds change.
pingRenderLocked(false /* drawImmediate */);
}
@@ -247,14 +241,12 @@ public class BackdropFrameRenderer extends Thread implements Choreographer.Frame
mNewTargetRect.set(mTargetRect);
if (!mNewTargetRect.equals(mOldTargetRect)
|| mOldFullscreen != mFullscreen
- || !mStableInsets.equals(mOldStableInsets)
- || !mSystemInsets.equals(mOldSystemInsets)
+ || !mSystemBarInsets.equals(mOldSystemBarInsets)
|| mReportNextDraw) {
mOldFullscreen = mFullscreen;
mOldTargetRect.set(mNewTargetRect);
- mOldSystemInsets.set(mSystemInsets);
- mOldStableInsets.set(mStableInsets);
- redrawLocked(mNewTargetRect, mFullscreen, mSystemInsets, mStableInsets);
+ mOldSystemBarInsets.set(mSystemBarInsets);
+ redrawLocked(mNewTargetRect, mFullscreen);
}
}
@@ -304,11 +296,8 @@ public class BackdropFrameRenderer extends Thread implements Choreographer.Frame
*
* @param newBounds The window bounds which needs to be drawn.
* @param fullscreen Whether the window is currently drawing in fullscreen.
- * @param systemInsets The current visible system insets for the window.
- * @param stableInsets The stable insets for the window.
*/
- private void redrawLocked(Rect newBounds, boolean fullscreen, Rect systemInsets,
- Rect stableInsets) {
+ private void redrawLocked(Rect newBounds, boolean fullscreen) {
// While a configuration change is taking place the view hierarchy might become
// inaccessible. For that case we remember the previous metrics to avoid flashes.
@@ -355,7 +344,7 @@ public class BackdropFrameRenderer extends Thread implements Choreographer.Frame
}
mFrameAndBackdropNode.endRecording();
- drawColorViews(left, top, width, height, fullscreen, systemInsets, stableInsets);
+ drawColorViews(left, top, width, height, fullscreen);
// We need to render the node explicitly
mRenderer.drawRenderNode(mFrameAndBackdropNode);
@@ -363,14 +352,13 @@ public class BackdropFrameRenderer extends Thread implements Choreographer.Frame
reportDrawIfNeeded();
}
- private void drawColorViews(int left, int top, int width, int height,
- boolean fullscreen, Rect systemInsets, Rect stableInsets) {
+ private void drawColorViews(int left, int top, int width, int height, boolean fullscreen) {
if (mSystemBarBackgroundNode == null) {
return;
}
RecordingCanvas canvas = mSystemBarBackgroundNode.beginRecording(width, height);
mSystemBarBackgroundNode.setLeftTopRightBottom(left, top, left + width, top + height);
- final int topInset = DecorView.getColorViewTopInset(mStableInsets.top, mSystemInsets.top);
+ final int topInset = mSystemBarInsets.top;
if (mStatusBarColor != null) {
mStatusBarColor.setBounds(0, 0, left + width, topInset);
mStatusBarColor.draw(canvas);
@@ -380,7 +368,7 @@ public class BackdropFrameRenderer extends Thread implements Choreographer.Frame
// don't want the navigation bar background be moving around when resizing in docked mode.
// However, we need it for the transitions into/out of docked mode.
if (mNavigationBarColor != null && fullscreen) {
- DecorView.getNavigationBarRect(width, height, stableInsets, systemInsets, mTmpRect, 1f);
+ DecorView.getNavigationBarRect(width, height, mSystemBarInsets, mTmpRect, 1f);
mNavigationBarColor.setBounds(mTmpRect);
mNavigationBarColor.draw(canvas);
}
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index c6135f2c81d3..b12c5e9ba5b0 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -1050,22 +1050,6 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
return false;
}
- public static int getColorViewTopInset(int stableTop, int systemTop) {
- return Math.min(stableTop, systemTop);
- }
-
- public static int getColorViewBottomInset(int stableBottom, int systemBottom) {
- return Math.min(stableBottom, systemBottom);
- }
-
- public static int getColorViewRightInset(int stableRight, int systemRight) {
- return Math.min(stableRight, systemRight);
- }
-
- public static int getColorViewLeftInset(int stableLeft, int systemLeft) {
- return Math.min(stableLeft, systemLeft);
- }
-
public static boolean isNavBarToRightEdge(int bottomInset, int rightInset) {
return bottomInset == 0 && rightInset > 0;
}
@@ -1079,14 +1063,11 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
: isNavBarToLeftEdge(bottomInset, leftInset) ? leftInset : bottomInset;
}
- public static void getNavigationBarRect(int canvasWidth, int canvasHeight, Rect stableInsets,
- Rect contentInsets, Rect outRect, float scale) {
- final int bottomInset =
- (int) (getColorViewBottomInset(stableInsets.bottom, contentInsets.bottom) * scale);
- final int leftInset =
- (int) (getColorViewLeftInset(stableInsets.left, contentInsets.left) * scale);
- final int rightInset =
- (int) (getColorViewLeftInset(stableInsets.right, contentInsets.right) * scale);
+ public static void getNavigationBarRect(int canvasWidth, int canvasHeight, Rect systemBarInsets,
+ Rect outRect, float scale) {
+ final int bottomInset = (int) (systemBarInsets.bottom * scale);
+ final int leftInset = (int) (systemBarInsets.left * scale);
+ final int rightInset = (int) (systemBarInsets.right * scale);
final int size = getNavBarSize(bottomInset, rightInset, leftInset);
if (isNavBarToRightEdge(bottomInset, rightInset)) {
outRect.set(canvasWidth - size, 0, canvasWidth, canvasHeight);
@@ -1113,31 +1094,30 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
mLastWindowFlags = attrs.flags;
if (insets != null) {
- mLastTopInset = getColorViewTopInset(insets.getStableInsetTop(),
- insets.getSystemWindowInsetTop());
- mLastBottomInset = getColorViewBottomInset(insets.getStableInsetBottom(),
- insets.getSystemWindowInsetBottom());
- mLastRightInset = getColorViewRightInset(insets.getStableInsetRight(),
- insets.getSystemWindowInsetRight());
- mLastLeftInset = getColorViewRightInset(insets.getStableInsetLeft(),
- insets.getSystemWindowInsetLeft());
+ final Insets systemBarInsets = insets.getInsets(WindowInsets.Type.systemBars());
+ final Insets stableBarInsets = insets.getInsetsIgnoringVisibility(
+ WindowInsets.Type.systemBars());
+ mLastTopInset = systemBarInsets.top;
+ mLastBottomInset = systemBarInsets.bottom;
+ mLastRightInset = systemBarInsets.right;
+ mLastLeftInset = systemBarInsets.left;
// Don't animate if the presence of stable insets has changed, because that
// indicates that the window was either just added and received them for the
// first time, or the window size or position has changed.
- boolean hasTopStableInset = insets.getStableInsetTop() != 0;
+ boolean hasTopStableInset = stableBarInsets.top != 0;
disallowAnimate |= (hasTopStableInset != mLastHasTopStableInset);
mLastHasTopStableInset = hasTopStableInset;
- boolean hasBottomStableInset = insets.getStableInsetBottom() != 0;
+ boolean hasBottomStableInset = stableBarInsets.bottom != 0;
disallowAnimate |= (hasBottomStableInset != mLastHasBottomStableInset);
mLastHasBottomStableInset = hasBottomStableInset;
- boolean hasRightStableInset = insets.getStableInsetRight() != 0;
+ boolean hasRightStableInset = stableBarInsets.right != 0;
disallowAnimate |= (hasRightStableInset != mLastHasRightStableInset);
mLastHasRightStableInset = hasRightStableInset;
- boolean hasLeftStableInset = insets.getStableInsetLeft() != 0;
+ boolean hasLeftStableInset = stableBarInsets.left != 0;
disallowAnimate |= (hasLeftStableInset != mLastHasLeftStableInset);
mLastHasLeftStableInset = hasLeftStableInset;
@@ -2296,7 +2276,7 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
public void onWindowSizeIsChanging(Rect newBounds, boolean fullscreen, Rect systemInsets,
Rect stableInsets) {
if (mBackdropFrameRenderer != null) {
- mBackdropFrameRenderer.setTargetRect(newBounds, fullscreen, systemInsets, stableInsets);
+ mBackdropFrameRenderer.setTargetRect(newBounds, fullscreen, systemInsets);
}
}
@@ -2314,11 +2294,12 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
final ThreadedRenderer renderer = getThreadedRenderer();
if (renderer != null) {
loadBackgroundDrawablesIfNeeded();
+ WindowInsets rootInsets = getRootWindowInsets();
mBackdropFrameRenderer = new BackdropFrameRenderer(this, renderer,
initialBounds, mResizingBackgroundDrawable, mCaptionBackgroundDrawable,
mUserCaptionBackgroundDrawable, getCurrentColor(mStatusColorViewState),
- getCurrentColor(mNavigationColorViewState), fullscreen, systemInsets,
- stableInsets);
+ getCurrentColor(mNavigationColorViewState), fullscreen,
+ rootInsets.getInsets(WindowInsets.Type.systemBars()));
// Get rid of the shadow while we are resizing. Shadow drawing takes considerable time.
// If we want to get the shadow shown while resizing, we would need to elevate a new
diff --git a/core/java/com/android/internal/policy/DividerSnapAlgorithm.java b/core/java/com/android/internal/policy/DividerSnapAlgorithm.java
index 575a5320bbd3..527286cf000e 100644
--- a/core/java/com/android/internal/policy/DividerSnapAlgorithm.java
+++ b/core/java/com/android/internal/policy/DividerSnapAlgorithm.java
@@ -104,17 +104,18 @@ public class DividerSnapAlgorithm {
public DividerSnapAlgorithm(Resources res, int displayWidth, int displayHeight, int dividerSize,
boolean isHorizontalDivision, Rect insets) {
this(res, displayWidth, displayHeight, dividerSize, isHorizontalDivision, insets,
- DOCKED_INVALID, false);
+ DOCKED_INVALID, false /* minimized */, true /* resizable */);
}
public DividerSnapAlgorithm(Resources res, int displayWidth, int displayHeight, int dividerSize,
boolean isHorizontalDivision, Rect insets, int dockSide) {
this(res, displayWidth, displayHeight, dividerSize, isHorizontalDivision, insets,
- dockSide, false);
+ dockSide, false /* minimized */, true /* resizable */);
}
public DividerSnapAlgorithm(Resources res, int displayWidth, int displayHeight, int dividerSize,
- boolean isHorizontalDivision, Rect insets, int dockSide, boolean isMinimizedMode) {
+ boolean isHorizontalDivision, Rect insets, int dockSide, boolean isMinimizedMode,
+ boolean isHomeResizable) {
mMinFlingVelocityPxPerSecond =
MIN_FLING_VELOCITY_DP_PER_SECOND * res.getDisplayMetrics().density;
mMinDismissVelocityPxPerSecond =
@@ -132,8 +133,8 @@ public class DividerSnapAlgorithm {
com.android.internal.R.fraction.docked_stack_divider_fixed_ratio, 1, 1);
mMinimalSizeResizableTask = res.getDimensionPixelSize(
com.android.internal.R.dimen.default_minimal_size_resizable_task);
- mTaskHeightInMinimizedMode = res.getDimensionPixelSize(
- com.android.internal.R.dimen.task_height_of_minimized_mode);
+ mTaskHeightInMinimizedMode = isHomeResizable ? res.getDimensionPixelSize(
+ com.android.internal.R.dimen.task_height_of_minimized_mode) : 0;
calculateTargets(isHorizontalDivision, dockSide);
mFirstSplitTarget = mTargets.get(1);
mLastSplitTarget = mTargets.get(mTargets.size() - 2);
diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
index c32082418bc5..4999ec055608 100644
--- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
@@ -79,6 +79,7 @@ interface IStatusBarService
void onNotificationSettingsViewed(String key);
void onNotificationBubbleChanged(String key, boolean isBubble, int flags);
void onBubbleNotificationSuppressionChanged(String key, boolean isSuppressed);
+ void hideCurrentInputMethodForBubbles();
void grantInlineReplyUriPermission(String key, in Uri uri, in UserHandle user, String packageName);
void clearInlineReplyUriPermissions(String key);
diff --git a/core/java/com/android/internal/view/IInputMethodManager.aidl b/core/java/com/android/internal/view/IInputMethodManager.aidl
index 3f03f2a3e754..8ec51b89d240 100644
--- a/core/java/com/android/internal/view/IInputMethodManager.aidl
+++ b/core/java/com/android/internal/view/IInputMethodManager.aidl
@@ -71,4 +71,7 @@ interface IInputMethodManager {
void reportActivityView(in IInputMethodClient parentClient, int childDisplayId,
in float[] matrixValues);
+
+ oneway void reportPerceptible(in IBinder windowToken, boolean perceptible);
+ void removeImeSurface();
}
diff --git a/core/java/com/android/internal/widget/ConversationLayout.java b/core/java/com/android/internal/widget/ConversationLayout.java
index b64923fb5bf8..0791ed3c42ec 100644
--- a/core/java/com/android/internal/widget/ConversationLayout.java
+++ b/core/java/com/android/internal/widget/ConversationLayout.java
@@ -197,7 +197,6 @@ public class ConversationLayout extends FrameLayout
super.onFinishInflate();
mMessagingLinearLayout = findViewById(R.id.notification_messaging);
mActions = findViewById(R.id.actions);
- mMessagingLinearLayout.setMessagingLayout(this);
mImageMessageContainer = findViewById(R.id.conversation_image_message_container);
// We still want to clip, but only on the top, since views can temporarily out of bounds
// during transitions.
@@ -233,13 +232,20 @@ public class ConversationLayout extends FrameLayout
oldVisibility = mImportanceRingView.getVisibility();
wasGone = oldVisibility == GONE;
visibility = !mImportantConversation ? GONE : visibility;
- isGone = visibility == GONE;
- if (wasGone != isGone) {
+ boolean isRingGone = visibility == GONE;
+ if (wasGone != isRingGone) {
// Keep the badge visibility in sync with the icon. This is necessary in cases
// Where the icon is being hidden externally like in group children.
mImportanceRingView.animate().cancel();
mImportanceRingView.setVisibility(visibility);
}
+
+ oldVisibility = mConversationIconBadge.getVisibility();
+ wasGone = oldVisibility == GONE;
+ if (wasGone != isGone) {
+ mConversationIconBadge.animate().cancel();
+ mConversationIconBadge.setVisibility(visibility);
+ }
});
// When the small icon is gone, hide the rest of the badge
mIcon.setOnForceHiddenChangedListener((forceHidden) -> {
@@ -1298,8 +1304,10 @@ public class ConversationLayout extends FrameLayout
if (expandable) {
mExpandButtonContainer.setVisibility(VISIBLE);
mExpandButtonInnerContainer.setOnClickListener(onClickListener);
+ mConversationIconContainer.setOnClickListener(onClickListener);
} else {
mExpandButtonContainer.setVisibility(GONE);
+ mConversationIconContainer.setOnClickListener(null);
}
updateContentEndPaddings();
}
diff --git a/core/java/com/android/internal/widget/MessagingGroup.java b/core/java/com/android/internal/widget/MessagingGroup.java
index 53272f7eebf9..f312d1d4f25d 100644
--- a/core/java/com/android/internal/widget/MessagingGroup.java
+++ b/core/java/com/android/internal/widget/MessagingGroup.java
@@ -42,6 +42,7 @@ import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.RemoteViews;
+import android.widget.TextView;
import com.android.internal.R;
@@ -109,6 +110,7 @@ public class MessagingGroup extends LinearLayout implements MessagingLinearLayou
private ViewGroup mMessagingIconContainer;
private int mConversationContentStart;
private int mNonConversationMarginEnd;
+ private int mNotificationTextMarginTop;
public MessagingGroup(@NonNull Context context) {
super(context);
@@ -148,6 +150,8 @@ public class MessagingGroup extends LinearLayout implements MessagingLinearLayou
R.dimen.conversation_content_start);
mNonConversationMarginEnd = getResources().getDimensionPixelSize(
R.dimen.messaging_layout_margin_end);
+ mNotificationTextMarginTop = getResources().getDimensionPixelSize(
+ R.dimen.notification_text_margin_top);
}
public void updateClipRect() {
@@ -612,7 +616,7 @@ public class MessagingGroup extends LinearLayout implements MessagingLinearLayou
return 0;
}
- public View getSenderView() {
+ public TextView getSenderView() {
return mSenderView;
}
@@ -664,10 +668,14 @@ public class MessagingGroup extends LinearLayout implements MessagingLinearLayou
public void setSingleLine(boolean singleLine) {
if (singleLine != mSingleLine) {
mSingleLine = singleLine;
+ MarginLayoutParams p = (MarginLayoutParams) mMessageContainer.getLayoutParams();
+ p.topMargin = singleLine ? 0 : mNotificationTextMarginTop;
+ mMessageContainer.setLayoutParams(p);
mContentContainer.setOrientation(
singleLine ? LinearLayout.HORIZONTAL : LinearLayout.VERTICAL);
MarginLayoutParams layoutParams = (MarginLayoutParams) mSenderView.getLayoutParams();
layoutParams.setMarginEnd(singleLine ? mSenderTextPaddingSingleLine : 0);
+ mSenderView.setSingleLine(singleLine);
updateMaxDisplayedLines();
updateClipRect();
updateSenderVisibility();
diff --git a/core/java/com/android/internal/widget/MessagingLayout.java b/core/java/com/android/internal/widget/MessagingLayout.java
index a162e4e10c71..27cd6e13d86c 100644
--- a/core/java/com/android/internal/widget/MessagingLayout.java
+++ b/core/java/com/android/internal/widget/MessagingLayout.java
@@ -124,7 +124,6 @@ public class MessagingLayout extends FrameLayout
protected void onFinishInflate() {
super.onFinishInflate();
mMessagingLinearLayout = findViewById(R.id.notification_messaging);
- mMessagingLinearLayout.setMessagingLayout(this);
// We still want to clip, but only on the top, since views can temporarily out of bounds
// during transitions.
DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
diff --git a/core/java/com/android/internal/widget/MessagingLinearLayout.java b/core/java/com/android/internal/widget/MessagingLinearLayout.java
index ac04862d9a7d..7cfd46c880fc 100644
--- a/core/java/com/android/internal/widget/MessagingLinearLayout.java
+++ b/core/java/com/android/internal/widget/MessagingLinearLayout.java
@@ -24,6 +24,7 @@ import android.util.AttributeSet;
import android.view.RemotableViewMethod;
import android.view.View;
import android.view.ViewGroup;
+import android.view.ViewParent;
import android.widget.RemoteViews;
import com.android.internal.R;
@@ -43,8 +44,6 @@ public class MessagingLinearLayout extends ViewGroup {
private int mMaxDisplayedLines = Integer.MAX_VALUE;
- private IMessagingLayout mMessagingLayout;
-
public MessagingLinearLayout(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
@@ -292,12 +291,40 @@ public class MessagingLinearLayout extends ViewGroup {
mMaxDisplayedLines = numberLines;
}
- public void setMessagingLayout(IMessagingLayout layout) {
- mMessagingLayout = layout;
+ public IMessagingLayout getMessagingLayout() {
+ View view = this;
+ while (true) {
+ ViewParent p = view.getParent();
+ if (p instanceof View) {
+ view = (View) p;
+ if (view instanceof IMessagingLayout) {
+ return (IMessagingLayout) view;
+ }
+ } else {
+ return null;
+ }
+ }
}
- public IMessagingLayout getMessagingLayout() {
- return mMessagingLayout;
+ @Override
+ public int getBaseline() {
+ // When placed in a horizontal linear layout (as is the case in a single-line MessageGroup),
+ // align with the last visible child (which is the one that will be displayed in the single-
+ // line group.
+ int childCount = getChildCount();
+ for (int i = childCount - 1; i >= 0; i--) {
+ final View child = getChildAt(i);
+ if (isGone(child)) {
+ continue;
+ }
+ final int childBaseline = child.getBaseline();
+ if (childBaseline == -1) {
+ return -1;
+ }
+ MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
+ return lp.topMargin + childBaseline;
+ }
+ return super.getBaseline();
}
public interface MessagingChild {
diff --git a/core/java/com/android/server/SystemConfig.java b/core/java/com/android/server/SystemConfig.java
index 21ca948fa89c..ea390cd71e31 100644
--- a/core/java/com/android/server/SystemConfig.java
+++ b/core/java/com/android/server/SystemConfig.java
@@ -24,6 +24,7 @@ import android.content.ComponentName;
import android.content.pm.FeatureInfo;
import android.content.pm.PackageManager;
import android.os.Build;
+import android.os.CarrierAssociatedAppEntry;
import android.os.Environment;
import android.os.FileUtils;
import android.os.Process;
@@ -198,8 +199,8 @@ public class SystemConfig {
// These are the packages of carrier-associated apps which should be disabled until used until
// a SIM is inserted which grants carrier privileges to that carrier app.
- final ArrayMap<String, List<String>> mDisabledUntilUsedPreinstalledCarrierAssociatedApps =
- new ArrayMap<>();
+ final ArrayMap<String, List<CarrierAssociatedAppEntry>>
+ mDisabledUntilUsedPreinstalledCarrierAssociatedApps = new ArrayMap<>();
final ArrayMap<String, ArraySet<String>> mPrivAppPermissions = new ArrayMap<>();
final ArrayMap<String, ArraySet<String>> mPrivAppDenyPermissions = new ArrayMap<>();
@@ -331,7 +332,8 @@ public class SystemConfig {
return mDisabledUntilUsedPreinstalledCarrierApps;
}
- public ArrayMap<String, List<String>> getDisabledUntilUsedPreinstalledCarrierAssociatedApps() {
+ public ArrayMap<String, List<CarrierAssociatedAppEntry>>
+ getDisabledUntilUsedPreinstalledCarrierAssociatedApps() {
return mDisabledUntilUsedPreinstalledCarrierAssociatedApps;
}
@@ -954,7 +956,23 @@ public class SystemConfig {
+ "> without package or carrierAppPackage in " + permFile
+ " at " + parser.getPositionDescription());
} else {
- List<String> associatedPkgs =
+ // APKs added to system images via OTA should specify the addedInSdk
+ // attribute, otherwise they may be enabled-by-default in too many
+ // cases. See CarrierAppUtils for more info.
+ int addedInSdk = CarrierAssociatedAppEntry.SDK_UNSPECIFIED;
+ String addedInSdkStr = parser.getAttributeValue(null, "addedInSdk");
+ if (!TextUtils.isEmpty(addedInSdkStr)) {
+ try {
+ addedInSdk = Integer.parseInt(addedInSdkStr);
+ } catch (NumberFormatException e) {
+ Slog.w(TAG, "<" + name + "> addedInSdk not an integer in "
+ + permFile + " at "
+ + parser.getPositionDescription());
+ XmlUtils.skipCurrentTag(parser);
+ break;
+ }
+ }
+ List<CarrierAssociatedAppEntry> associatedPkgs =
mDisabledUntilUsedPreinstalledCarrierAssociatedApps.get(
carrierPkgname);
if (associatedPkgs == null) {
@@ -962,7 +980,8 @@ public class SystemConfig {
mDisabledUntilUsedPreinstalledCarrierAssociatedApps.put(
carrierPkgname, associatedPkgs);
}
- associatedPkgs.add(pkgname);
+ associatedPkgs.add(
+ new CarrierAssociatedAppEntry(pkgname, addedInSdk));
}
} else {
logNotAllowedInPartition(name, permFile, parser);
@@ -1197,6 +1216,10 @@ public class SystemConfig {
addFeature(PackageManager.FEATURE_APP_ENUMERATION, 0);
}
+ if (Build.VERSION.FIRST_SDK_INT >= Build.VERSION_CODES.Q) {
+ addFeature(PackageManager.FEATURE_IPSEC_TUNNELS, 0);
+ }
+
for (String featureName : mUnavailableFeatures) {
removeFeature(featureName);
}
diff --git a/core/jni/android_media_AudioFormat.h b/core/jni/android_media_AudioFormat.h
index a3c455bfc111..b1b39f3e36ff 100644
--- a/core/jni/android_media_AudioFormat.h
+++ b/core/jni/android_media_AudioFormat.h
@@ -47,6 +47,7 @@
#define CHANNEL_INVALID 0
#define CHANNEL_OUT_DEFAULT 1
+#define CHANNEL_IN_DEFAULT 1
static inline audio_format_t audioFormatToNative(int audioFormat)
{
@@ -196,12 +197,22 @@ static inline int outChannelMaskFromNative(audio_channel_mask_t nativeMask)
static inline audio_channel_mask_t inChannelMaskToNative(int channelMask)
{
- return (audio_channel_mask_t)channelMask;
+ switch (channelMask) {
+ case CHANNEL_IN_DEFAULT:
+ return AUDIO_CHANNEL_NONE;
+ default:
+ return (audio_channel_mask_t)channelMask;
+ }
}
static inline int inChannelMaskFromNative(audio_channel_mask_t nativeMask)
{
- return (int)nativeMask;
+ switch (nativeMask) {
+ case AUDIO_CHANNEL_NONE:
+ return CHANNEL_IN_DEFAULT;
+ default:
+ return (int)nativeMask;
+ }
}
#endif // ANDROID_MEDIA_AUDIOFORMAT_H
diff --git a/core/jni/android_net_NetUtils.cpp b/core/jni/android_net_NetUtils.cpp
index 03b9793ccba8..d4805acb06d0 100644
--- a/core/jni/android_net_NetUtils.cpp
+++ b/core/jni/android_net_NetUtils.cpp
@@ -226,6 +226,11 @@ static jobject android_net_utils_getDnsNetwork(JNIEnv *env, jobject thiz) {
class_Network, ctor, dnsNetId & ~NETID_USE_LOCAL_NAMESERVERS, privateDnsBypass);
}
+static void android_net_utils_setAllowNetworkingForProcess(JNIEnv *env, jobject thiz,
+ jboolean hasConnectivity) {
+ setAllowNetworkingForProcess(hasConnectivity == JNI_TRUE);
+}
+
static jobject android_net_utils_getTcpRepairWindow(JNIEnv *env, jobject thiz, jobject javaFd) {
if (javaFd == NULL) {
jniThrowNullPointerException(env, NULL);
@@ -266,6 +271,7 @@ static jobject android_net_utils_getTcpRepairWindow(JNIEnv *env, jobject thiz, j
/*
* JNI registration.
*/
+// clang-format off
static const JNINativeMethod gNetworkUtilMethods[] = {
/* name, signature, funcPtr */
{ "bindProcessToNetwork", "(I)Z", (void*) android_net_utils_bindProcessToNetwork },
@@ -282,7 +288,9 @@ static const JNINativeMethod gNetworkUtilMethods[] = {
{ "resNetworkResult", "(Ljava/io/FileDescriptor;)Landroid/net/DnsResolver$DnsResponse;", (void*) android_net_utils_resNetworkResult },
{ "resNetworkCancel", "(Ljava/io/FileDescriptor;)V", (void*) android_net_utils_resNetworkCancel },
{ "getDnsNetwork", "()Landroid/net/Network;", (void*) android_net_utils_getDnsNetwork },
+ { "setAllowNetworkingForProcess", "(Z)V", (void *)android_net_utils_setAllowNetworkingForProcess },
};
+// clang-format on
int register_android_net_NetworkUtils(JNIEnv* env)
{
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index e553a786da96..ae36f8a7b30b 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -395,6 +395,16 @@ static void nativeSetEarlyWakeup(JNIEnv* env, jclass clazz, jlong transactionObj
transaction->setEarlyWakeup();
}
+static void nativeSetEarlyWakeupStart(JNIEnv* env, jclass clazz, jlong transactionObj) {
+ auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+ transaction->setExplicitEarlyWakeupStart();
+}
+
+static void nativeSetEarlyWakeupEnd(JNIEnv* env, jclass clazz, jlong transactionObj) {
+ auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+ transaction->setExplicitEarlyWakeupEnd();
+}
+
static void nativeSetLayer(JNIEnv* env, jclass clazz, jlong transactionObj,
jlong nativeObject, jint zorder) {
auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
@@ -1501,6 +1511,10 @@ static const JNINativeMethod sSurfaceControlMethods[] = {
(void*)nativeSetAnimationTransaction },
{"nativeSetEarlyWakeup", "(J)V",
(void*)nativeSetEarlyWakeup },
+ {"nativeSetEarlyWakeupStart", "(J)V",
+ (void*)nativeSetEarlyWakeupStart },
+ {"nativeSetEarlyWakeupEnd", "(J)V",
+ (void*)nativeSetEarlyWakeupEnd },
{"nativeSetLayer", "(JJI)V",
(void*)nativeSetLayer },
{"nativeSetRelativeLayer", "(JJJI)V",
diff --git a/core/proto/android/app/enums.proto b/core/proto/android/app/enums.proto
index 563ef145b79c..bd5cb62f7fde 100644
--- a/core/proto/android/app/enums.proto
+++ b/core/proto/android/app/enums.proto
@@ -206,4 +206,5 @@ enum AppOpEnum {
APP_OP_DEPRECATED_1 = 96 [deprecated = true];
APP_OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED = 97;
APP_OP_AUTO_REVOKE_MANAGED_BY_INSTALLER = 98;
+ APP_OP_NO_ISOLATED_STORAGE = 99;
}
diff --git a/core/proto/android/app/settings_enums.proto b/core/proto/android/app/settings_enums.proto
index 997829eacf96..69b32c264d3d 100644
--- a/core/proto/android/app/settings_enums.proto
+++ b/core/proto/android/app/settings_enums.proto
@@ -2678,4 +2678,9 @@ enum PageId {
// CATEGORY: SETTINGS
// OS: R
DEVICE_CONTROLS_SETTINGS = 1844;
+
+ // OPEN: Settings > Sound > Media
+ // CATEGORY: SETTINGS
+ // OS: R
+ MEDIA_CONTROLS_SETTINGS = 1845;
}
diff --git a/core/proto/android/stats/connectivity/Android.bp b/core/proto/android/stats/connectivity/Android.bp
index 9cd233e1ba85..5e6ac3cd3ca1 100644
--- a/core/proto/android/stats/connectivity/Android.bp
+++ b/core/proto/android/stats/connectivity/Android.bp
@@ -22,3 +22,17 @@ java_library_static {
],
sdk_version: "system_29",
}
+
+java_library_static {
+ name: "tetheringprotos",
+ proto: {
+ type: "lite",
+ },
+ srcs: [
+ "tethering.proto",
+ ],
+ apex_available: [
+ "com.android.tethering",
+ ],
+ sdk_version: "system_current",
+}
diff --git a/core/proto/android/stats/connectivity/tethering.proto b/core/proto/android/stats/connectivity/tethering.proto
new file mode 100644
index 000000000000..13f0b8c44fb5
--- /dev/null
+++ b/core/proto/android/stats/connectivity/tethering.proto
@@ -0,0 +1,97 @@
+/*
+ * 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.
+ */
+syntax = "proto2";
+package android.stats.connectivity;
+option java_multiple_files = true;
+option java_outer_classname = "TetheringProto";
+
+enum ErrorCode {
+ EC_NO_ERROR = 0;
+ EC_UNKNOWN_IFACE = 1;
+ EC_SERVICE_UNAVAIL = 2;
+ EC_UNSUPPORTED = 3;
+ EC_UNAVAIL_IFACE = 4;
+ EC_INTERNAL_ERROR = 5;
+ EC_TETHER_IFACE_ERROR = 6;
+ EC_UNTETHER_IFACE_ERROR = 7;
+ EC_ENABLE_FORWARDING_ERROR = 8;
+ EC_DISABLE_FORWARDING_ERROR = 9;
+ EC_IFACE_CFG_ERROR = 10;
+ EC_PROVISIONING_FAILED = 11;
+ EC_DHCPSERVER_ERROR = 12;
+ EC_ENTITLEMENT_UNKNOWN = 13;
+ EC_NO_CHANGE_TETHERING_PERMISSION = 14;
+ EC_NO_ACCESS_TETHERING_PERMISSION = 15;
+ EC_UNKNOWN_TYPE = 16;
+}
+
+enum DownstreamType {
+ // Unspecific tethering type.
+ DS_UNSPECIFIED = 0;
+ // Wifi tethering type.
+ DS_TETHERING_WIFI = 1;
+ // USB tethering type.
+ DS_TETHERING_USB = 2;
+ // Bluetooth tethering type.
+ DS_TETHERING_BLUETOOTH = 3;
+ // Wifi P2p tethering type.
+ DS_TETHERING_WIFI_P2P = 4;
+ // NCM (Network Control Model) local tethering type.
+ DS_TETHERING_NCM = 5;
+ // Ethernet tethering type.
+ DS_TETHERING_ETHERNET = 6;
+}
+
+enum UpstreamType {
+ UT_UNKNOWN = 0;
+ // Indicates upstream using a Cellular transport.
+ UT_CELLULAR = 1;
+ // Indicates upstream using a Wi-Fi transport.
+ UT_WIFI = 2;
+ // Indicates upstream using a Bluetooth transport.
+ UT_BLUETOOTH = 3;
+ // Indicates upstream using an Ethernet transport.
+ UT_ETHERNET = 4;
+ // Indicates upstream using a Wi-Fi Aware transport.
+ UT_WIFI_AWARE = 5;
+ // Indicates upstream using a LoWPAN transport.
+ UT_LOWPAN = 6;
+ // Indicates upstream using a Cellular+VPN transport.
+ UT_CELLULAR_VPN = 7;
+ // Indicates upstream using a Wi-Fi+VPN transport.
+ UT_WIFI_VPN = 8;
+ // Indicates upstream using a Bluetooth+VPN transport.
+ UT_BLUETOOTH_VPN = 9;
+ // Indicates upstream using an Ethernet+VPN transport.
+ UT_ETHERNET_VPN = 10;
+ // Indicates upstream using a Wi-Fi+Cellular+VPN transport.
+ UT_WIFI_CELLULAR_VPN = 11;
+ // Indicates upstream using for test only.
+ UT_TEST = 12;
+ // Indicates upstream using DUN capability + Cellular transport.
+ UT_DUN_CELLULAR = 13;
+}
+
+enum UserType {
+ // Unknown.
+ USER_UNKNOWN = 0;
+ // Settings.
+ USER_SETTINGS = 1;
+ // System UI.
+ USER_SYSTEMUI = 2;
+ // Google mobile service.
+ USER_GMS = 3;
+}
diff --git a/core/proto/android/stats/launcher/launcher.proto b/core/proto/android/stats/launcher/launcher.proto
index dbd0e038c40c..fc177d57b193 100644
--- a/core/proto/android/stats/launcher/launcher.proto
+++ b/core/proto/android/stats/launcher/launcher.proto
@@ -32,10 +32,12 @@ enum LauncherAction {
}
enum LauncherState {
- BACKGROUND = 0;
- HOME = 1;
- OVERVIEW = 2;
- ALLAPPS = 3;
+ LAUNCHER_STATE_UNSPECIFIED = 0;
+ BACKGROUND = 1;
+ HOME = 2;
+ OVERVIEW = 3;
+ ALLAPPS = 4;
+ UNCHANGED = 5;
}
message LauncherTarget {
diff --git a/core/proto/android/stats/sysui/notification_enums.proto b/core/proto/android/stats/sysui/notification_enums.proto
index 09837022e50d..30bdecae07d1 100644
--- a/core/proto/android/stats/sysui/notification_enums.proto
+++ b/core/proto/android/stats/sysui/notification_enums.proto
@@ -26,4 +26,5 @@ enum NotificationImportance { // Constants from NotificationManager.java
IMPORTANCE_LOW = 2; // Shows in shade, maybe status bar, no buzz/beep.
IMPORTANCE_DEFAULT = 3; // Shows everywhere, makes noise, no heads-up.
IMPORTANCE_HIGH = 4; // Shows everywhere, makes noise, heads-up, may full-screen.
+ IMPORTANCE_IMPORTANT_CONVERSATION = 5; // High + isImportantConversation().
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index f71d4063b847..9c1ecf2e48e0 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -3534,6 +3534,8 @@
@hide -->
<permission android:name="android.permission.MEDIA_RESOURCE_OVERRIDE_PID"
android:protectionLevel="signature" />
+ <uses-permission android:name="android.permission.MEDIA_RESOURCE_OVERRIDE_PID" />
+
<!-- Must be required by a {@link android.media.routing.MediaRouteService}
to ensure that only the system can interact with it.
@@ -5026,6 +5028,10 @@
<permission android:name="android.permission.ACCESS_TV_DESCRAMBLER"
android:protectionLevel="signature|privileged|vendorPrivileged" />
+ <!-- Allows an application to create trusted displays. @hide -->
+ <permission android:name="android.permission.ADD_TRUSTED_DISPLAY"
+ android:protectionLevel="signature" />
+
<!-- @hide @SystemApi Allows an application to access locusId events in the usage stats. -->
<permission android:name="android.permission.ACCESS_LOCUS_ID_USAGE_STATS"
android:protectionLevel="signature|appPredictor" />
diff --git a/core/res/res/drawable-car-night/car_dialog_button_background.xml b/core/res/res/drawable-car-night/car_dialog_button_background.xml
new file mode 100644
index 000000000000..138cb38b0d87
--- /dev/null
+++ b/core/res/res/drawable-car-night/car_dialog_button_background.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2020 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_focused="true">
+ <ripple android:color="#2371cd">
+ <item android:id="@android:id/mask">
+ <color android:color="@*android:color/car_white_1000"/>
+ </item>
+ </ripple>
+ </item>
+ <item>
+ <ripple android:color="?android:attr/colorControlHighlight">
+ <item android:id="@android:id/mask">
+ <color android:color="@*android:color/car_white_1000"/>
+ </item>
+ </ripple>
+ </item>
+</selector>
diff --git a/core/res/res/drawable-car/car_dialog_button_background.xml b/core/res/res/drawable-car/car_dialog_button_background.xml
index 67506cbc12bc..a7d40bcd759a 100644
--- a/core/res/res/drawable-car/car_dialog_button_background.xml
+++ b/core/res/res/drawable-car/car_dialog_button_background.xml
@@ -14,9 +14,19 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
-<ripple xmlns:android="http://schemas.android.com/apk/res/android"
- android:color="?android:attr/colorControlHighlight">
- <item android:id="@android:id/mask">
- <color android:color="@*android:color/car_white_1000" />
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_focused="true">
+ <ripple android:color="#4b9eff">
+ <item android:id="@android:id/mask">
+ <color android:color="@*android:color/car_white_1000"/>
+ </item>
+ </ripple>
</item>
-</ripple>
+ <item>
+ <ripple android:color="?android:attr/colorControlHighlight">
+ <item android:id="@android:id/mask">
+ <color android:color="@*android:color/car_white_1000"/>
+ </item>
+ </ripple>
+ </item>
+</selector>
diff --git a/core/res/res/drawable/chooser_action_button_bg.xml b/core/res/res/drawable/chooser_action_button_bg.xml
index a434c0b9b6a9..0dd9e9c7cd98 100644
--- a/core/res/res/drawable/chooser_action_button_bg.xml
+++ b/core/res/res/drawable/chooser_action_button_bg.xml
@@ -25,8 +25,8 @@
<shape android:shape="rectangle">
<corners android:radius="16dp"></corners>
<stroke android:width="1dp"
- android:color="?attr/textColorSecondary" />
- <solid android:color="?attr/colorBackground" />
+ android:color="?attr/opacityListDivider" />
+ <solid android:color="?attr/colorBackgroundFloating" />
</shape>
</inset>
</item>
diff --git a/core/res/res/layout/chooser_action_button.xml b/core/res/res/layout/chooser_action_button.xml
index 119b2e90292d..6af7937960f0 100644
--- a/core/res/res/layout/chooser_action_button.xml
+++ b/core/res/res/layout/chooser_action_button.xml
@@ -19,12 +19,12 @@
android:paddingStart="12dp"
android:paddingEnd="12dp"
android:drawablePadding="8dp"
- android:textColor="?android:textColorSecondary"
+ android:textColor="?android:textColorPrimary"
android:textSize="12sp"
android:maxWidth="192dp"
android:singleLine="true"
android:clickable="true"
android:background="@drawable/chooser_action_button_bg"
- android:drawableTint="?android:attr/colorControlNormal"
+ android:drawableTint="@color/chooser_chip_icon"
android:drawableTintMode="src_in"
/>
diff --git a/core/res/res/layout/notification_template_material_conversation.xml b/core/res/res/layout/notification_template_material_conversation.xml
index 139185f98b69..82e99e6419b6 100644
--- a/core/res/res/layout/notification_template_material_conversation.xml
+++ b/core/res/res/layout/notification_template_material_conversation.xml
@@ -139,7 +139,7 @@
>
<TextView
android:id="@+id/conversation_text"
- android:layout_width="wrap_content"
+ android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/notification_conversation_header_separating_margin"
android:textAppearance="@style/TextAppearance.DeviceDefault.Notification.Title"
diff --git a/core/res/res/layout/notification_template_messaging_group.xml b/core/res/res/layout/notification_template_messaging_group.xml
index 3188861a52a5..5e3b657353b6 100644
--- a/core/res/res/layout/notification_template_messaging_group.xml
+++ b/core/res/res/layout/notification_template_messaging_group.xml
@@ -37,6 +37,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
+ android:baselineAligned="true"
android:orientation="vertical">
<com.android.internal.widget.ImageFloatingTextView
android:id="@+id/message_name"
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 8a68217d966a..89ce3b0eefb9 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -1619,7 +1619,6 @@
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"Jy het jou ontsluitpatroon <xliff:g id="NUMBER_0">%1$d</xliff:g> keer verkeerdelik geteken. Na nog <xliff:g id="NUMBER_1">%2$d</xliff:g> onsuksesvolle pogings, sal jy gevra word om jou foon te ontsluit deur middel van \'n e-posrekening.\n\n Probeer weer oor <xliff:g id="NUMBER_2">%3$d</xliff:g> sekondes."</string>
<string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Verwyder"</string>
- <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Die voorgronddiens wat in die agtergrond begin het vanaf <xliff:g id="PACKAGENAME">%1$s</xliff:g> sal nie ingebruik-toestemming hê in toekomstige R-bouweergawes nie. Raadpleeg asseblief go/r-bg-fgs-restriction en dien \'n foutverslag in."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Verhoog volume bo aanbevole vlak?\n\nOm lang tydperke teen hoë volume te luister, kan jou gehoor beskadig."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Gebruik toeganklikheidkortpad?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Wanneer die kortpad aan is, sal \'n toeganklikheidkenmerk begin word as albei volumeknoppies 3 sekondes lank gedruk word."</string>
@@ -1651,8 +1650,8 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Gebruik kortpad"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Kleuromkering"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Kleurkorreksie"</string>
- <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Het volumesleutels gehou. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> aangeskakel."</string>
- <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Het volumesleutels gehou. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> het afgeskakel"</string>
+ <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Het volumesleutels ingehou. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> aangeskakel."</string>
+ <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Het volumesleutels ingehou. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> is afgeskakel"</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Druk en hou albei volumesleutels drie sekondes lank om <xliff:g id="SERVICE_NAME">%1$s</xliff:g> te gebruik"</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Kies \'n kenmerk om te gebruik wanneer jy op die toeganklikheidknoppie tik:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Kies \'n kenmerk om te gebruik saam met die toeganklikheidgebaar (swiep met twee vingers op van die onderkant van die skerm af):"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index a05cfbfc99fd..5eb271e754a6 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -1619,7 +1619,6 @@
<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="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"ዳራው ከ<xliff:g id="PACKAGENAME">%1$s</xliff:g> የጀመረው የፊት አገልግሎት ወደፊት በሚኖሩት R ግንቦች ላይ ጥቅም ላይ እየዋለ ፈቃድ አይኖረውም። እባክዎ go/r-bg-fgs-restriction እና ፋይል ሳንካ ሪፖርትን ይመልከቱ።"</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"ድምጹ ከሚመከረው መጠን በላይ ከፍ ይበል?\n\nበከፍተኛ ድምጽ ለረጅም ጊዜ ማዳመጥ ጆሮዎን ሊጎዳው ይችላል።"</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"የተደራሽነት አቋራጭ ጥቅም ላይ ይዋል?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"አቋራጩ ሲበራ ሁለቱንም የድምጽ አዝራሮች ለ3 ሰከንዶች ተጭኖ መቆየት የተደራሽነት ባህሪን ያስጀምረዋል።"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 02a0eb476505..5c101888aff8 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -973,7 +973,7 @@
<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="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>
@@ -1391,7 +1391,7 @@
<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>
+ <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"انقر لإيقاف ميزة \"تصحيح الأخطاء اللاسلكي\""</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"تم تفعيل وضع \"مفعّل الاختبار\""</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"يمكنك إجراء إعادة ضبط على الإعدادات الأصلية لإيقاف وضع \"مفعِّل اختبار\"."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"وحدة التحكّم التسلسلية مفعّلة"</string>
@@ -1707,12 +1707,11 @@
<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="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"‏لن يتم منح إذن الوصول إلى الموقع الجغرافي أثناء الاستخدام للخدمات التي تعمل في المقدّمة من <xliff:g id="PACKAGENAME">%1$s</xliff:g> والتي تبدأ من الخلفية في إصدارات R القادمة. يُرجى مراجعة go/r-bg-fgs-restriction وتقديم تقرير خطأ."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"هل تريد رفع مستوى الصوت فوق المستوى الموصى به؟\n\nقد يضر سماع صوت عالٍ لفترات طويلة بسمعك."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"هل تريد استخدام اختصار \"سهولة الاستخدام\"؟"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"عند تفعيل الاختصار، يؤدي الضغط على زرّي التحكّم في مستوى الصوت معًا لمدة 3 ثوانٍ إلى تفعيل إحدى ميزات إمكانية الوصول."</string>
<string name="accessibility_shortcut_multiple_service_warning_title" msgid="8417489297036013065">"هل تريد تفعيل ميزات إمكانية الوصول؟"</string>
- <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"‏يؤدي الضغط مع الاستمرار على كلا مفتاحَي التحكّم في مستوى الصوت لبضع ثوانٍ إلى تفعيل ميزات إمكانية الوصول. قد يؤدي هذا إلى تغيير كيفية عمل جهازك.\n\nالميزات الحالية:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nيمكنك تغيير الميزات المحددة في الإعدادات &gt; أدوات تمكين الوصول."</string>
+ <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"يؤدي الضغط مع الاستمرار على كلا مفتاحَي التحكّم في مستوى الصوت لبضع ثوانٍ إلى تفعيل ميزات إمكانية الوصول. قد يؤدي هذا الإجراء إلى تغيير طريقة عمل جهازك.\n\nالميزات الحالية:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nيمكنك تغيير الميزات المحددة في الإعدادات &gt; إمكانية الوصول."</string>
<string name="accessibility_shortcut_multiple_service_list" msgid="6935581470716541531">" • <xliff:g id="SERVICE">%1$s</xliff:g>\n"</string>
<string name="accessibility_shortcut_single_service_warning_title" msgid="2819109500943271385">"هل تريد تفعيل <xliff:g id="SERVICE">%1$s</xliff:g>؟"</string>
<string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"‏يؤدي الضغط مع الاستمرار لبضع ثوانٍ على كلا مفتاحَي التحكّم في مستوى الصوت إلى تفعيل <xliff:g id="SERVICE">%1$s</xliff:g> وهي إحدى ميزات إمكانية الوصول. يمكن أن يؤدي هذا الإجراء إلى تغيير كيفية عمل جهازك.\n\nيمكنك تغيير هذا الاختصار لاستخدامه مع ميزة أخرى في الإعدادات &gt; أدوات تمكين الوصول."</string>
@@ -1982,9 +1981,9 @@
<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_name" msgid="490523464968655741">"‏منفذ الأجهزة الملحقة المزودة بكابل USB ونظام التشغيل Android"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7557148557088787741">"Android"</string>
- <string name="usb_midi_peripheral_product_name" msgid="2836276258480904434">"‏منفذ الأجهزة الطرفية المزودة بكابل USB"</string>
+ <string name="usb_midi_peripheral_product_name" msgid="2836276258480904434">"‏منفذ الأجهزة الملحقة المزودة بكابل USB"</string>
<string name="floating_toolbar_open_overflow_description" msgid="2260297653578167367">"خيارات أخرى"</string>
<string name="floating_toolbar_close_overflow_description" msgid="3949818077708138098">"إغلاق التجاوز"</string>
<string name="maximize_button_text" msgid="4258922519914732645">"تكبير"</string>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index 5ac3aaeb9c6c..f2c7c4551de8 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -1619,12 +1619,11 @@
<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="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"নেপথ্যই <xliff:g id="PACKAGENAME">%1$s</xliff:g>ৰ পৰা আৰম্ভ কৰা অগ্ৰভূমিৰ সেৱাটোৰ ভৱিষ্যতৰ R বিল্ডসমূহত ব্যৱহাৰ হৈ থকা সম্পৰ্কীয় অনুমতি নাথাকিব। অনুগ্ৰহ কৰি go/r-bg-fgs-restriction চাওক আৰু এটা বাগৰিপ\'ৰ্ট ফাইল কৰক।"</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"অনুমোদিত স্তৰতকৈ ওপৰলৈ ভলিউম বঢ়াব নেকি?\n\nদীৰ্ঘ সময়ৰ বাবে উচ্চ ভলিউমত শুনাৰ ফলত শ্ৰৱণ ক্ষমতাৰ ক্ষতি হ\'ব পাৰে।"</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"দিব্যাংগসকলৰ সুবিধাৰ শ্বৰ্টকাট ব্যৱহাৰ কৰেনে?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"শ্বৰ্টকাটটো অন হৈ থকাৰ সময়ত দুয়োটা ভলিউম বুটাম ৩ ছেকেণ্ডৰ বাবে হেঁচি ধৰি ৰাখিলে এটা সাধ্য সুবিধা আৰম্ভ হ’ব।"</string>
<string name="accessibility_shortcut_multiple_service_warning_title" msgid="8417489297036013065">"সাধ্য-সুবিধাসমূহ অন কৰিবনে?"</string>
- <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"দুয়োটা ভলিউম কী কিছুসময়ৰ বাবে ধৰি থাকিলে সাধ্য-সুবিধাসমূহ অন কৰে। এইটোৱে আপোনাৰ ডিভাইচটোৱে কাম কৰাৰ ধৰণ সলনি কৰিব পাৰে।\n\nবর্তমানৰ সুবিধাসমূহ:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nআপুনি ছেটিংসমূহ &gt; সাধ্য-সুবিধাত বাছনি কৰা সুবিধাসমূহ সলনি কৰিব পাৰে।"</string>
+ <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"দুয়োটা ভলিউম কী কিছুসময়ৰ বাবে ধৰি থাকিলে সাধ্য-সুবিধাসমূহ অন কৰে। এইটোৱে আপোনাৰ ডিভাইচটোৱে কাম কৰাৰ ধৰণ সলনি কৰিব পাৰে।\n\nবর্তমানৰ সুবিধাসমূহ:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nআপুনি ছেটিংসমূহ &gt; সাধ্য-সুবিধাত কিছুমান নিৰ্দিষ্ট সুবিধা সলনি কৰিব পাৰে।"</string>
<string name="accessibility_shortcut_multiple_service_list" msgid="6935581470716541531">" • <xliff:g id="SERVICE">%1$s</xliff:g>\n"</string>
<string name="accessibility_shortcut_single_service_warning_title" msgid="2819109500943271385">"<xliff:g id="SERVICE">%1$s</xliff:g> অন কৰিবনে?"</string>
<string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"দুয়োটা ভলিউম কী কিছুসময়ৰ বাবে ধৰি থাকিলে এটা সাধ্য- সুবিধা <xliff:g id="SERVICE">%1$s</xliff:g> অন কৰে। এইটোৱে আপোনাৰ ডিভাইচটোৱে কাম কৰাৰ ধৰণ সলনি কৰিব পাৰে।\n\nআপুনি ছেটিংসমূহ &gt; সাধ্য-সুবিধাসমূহত এই শ্বৰ্টকাটটো অন্য এটা সুবিধালৈ সলনি কৰিব পাৰে।"</string>
@@ -1652,7 +1651,7 @@
<string name="color_inversion_feature_name" msgid="326050048927789012">"ৰং বিপৰীতকৰণ"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"ৰং শুধৰণী"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ভলিউম কীসমূহ ধৰি ৰাখক। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> অন কৰা হ\'ল।"</string>
- <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ভলিউম কীসমূহ ধৰি ৰাখক। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> অফ কৰা হ\'ল।"</string>
+ <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ভলিউম কী ধৰি ৰাখিছিল। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> অফ কৰা হ\'ল।"</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> ব্যৱহাৰ কৰিবলৈ দুয়োটা ভলিউম বুটাম তিনি ছেকেণ্ডৰ বাবে হেঁচি ৰাখক"</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"আপুনি সাধ্য-সুবিধাৰ বুটামটো টিপিলে ব্যৱহাৰ কৰিবলৈ এটা সুবিধা বাছনি কৰক:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"সাধ্য-সুবিধাৰ নির্দেশৰ জৰিয়তে ব্যৱহাৰ কৰিবলৈ এটা সুবিধা বাছনি কৰক (দুটা আঙুলিৰে স্ক্রীনখনৰ একেবাৰে তলিৰ পৰা ওপৰলৈ ছোৱাইপ কৰক):"</string>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index 106f7040c1a4..2c75c866f1c0 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -1619,7 +1619,6 @@
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"Siz artıq modeli <xliff:g id="NUMBER_0">%1$d</xliff:g> dəfə yanlış daxil etmisiniz.<xliff:g id="NUMBER_1">%2$d</xliff:g> dəfə də yanlış daxil etsəniz, telefonun kilidinin açılması üçün elektron poçt ünvanınız tələb olunacaq.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> saniyə ərzində yenidən cəhd edin."</string>
<string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" - "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Yığışdır"</string>
- <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Arxa fonda başladılan <xliff:g id="PACKAGENAME">%1$s</xliff:g> üzrə ön plan xidmətinin gələcək R versiyalarında \"istifadə zamanı\" icazəsi olmayacaq. go/r-bg-fgs-restriction bölməsinə keçin və baq hesabatı göndərin."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Səsin həcmi tövsiyə olunan səviyyədən artıq olsun?\n\nYüksək səsi uzun zaman dinləmək eşitmə qabiliyyətinizə zərər vura bilər."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Əlçatımlılıq Qısayolu istifadə edilsin?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Qısayol aktiv olduqda, hər iki səs düyməsinə 3 saniyə basıb saxlamaqla əlçatımlılıq funksiyası başladılacaq."</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index c2d501355d5f..7fb53f6e269b 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -1641,7 +1641,6 @@
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"Nacrtali ste šablon za otključavanje netačno <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Posle još <xliff:g id="NUMBER_1">%2$d</xliff:g> neuspešna(ih) pokušaja, od vas će biti zatraženo da otključate telefon pomoću naloga e-pošte.\n\nProbajte ponovo za <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunde/i."</string>
<string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" – "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Ukloni"</string>
- <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Usluga u prvom planu sa <xliff:g id="PACKAGENAME">%1$s</xliff:g> koja je pokrenuta u pozadini neće imati dozvolu tokom korišćenja u budućim R verzijama. Posetite go/r-bg-fgs-restriction i pošaljite izveštaj o grešci."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Želite da pojačate zvuk iznad preporučenog nivoa?\n\nSlušanje glasne muzike duže vreme može da vam ošteti sluh."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Želite li da koristite prečicu za pristupačnost?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Kada je prečica uključena, pritisnite oba dugmeta za jačinu zvuka da biste pokrenuli funkciju pristupačnosti."</string>
@@ -1665,7 +1664,7 @@
<string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Odbij"</string>
<string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Dodirnite neku funkciju da biste počeli da je koristite:"</string>
<string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Odaberite funkcije koje ćete koristiti sa dugmetom Pristupačnost"</string>
- <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Odaberite funkcije koje ćete koristiti sa tasterom jačine zvuka kao prečicom"</string>
+ <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Odaberite funkcije za prečicu tasterom jačine zvuka"</string>
<string name="accessibility_uncheck_legacy_item_warning" msgid="8047830891064817447">"Usluga <xliff:g id="SERVICE_NAME">%s</xliff:g> je isključena"</string>
<string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Izmenite prečice"</string>
<string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Gotovo"</string>
@@ -1673,8 +1672,8 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Koristi prečicu"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Inverzija boja"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Korekcija boja"</string>
- <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Zadržali ste tastere za jačinu zvuka. Usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je uključena."</string>
- <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Zadržali ste tastere za jačinu zvuka. Usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je isključena."</string>
+ <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Držali ste tastere za jačinu zvuka. Usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je uključena."</string>
+ <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Držali ste tastere za jačinu zvuka. Usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je isključena."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Pritisnite i zadržite oba tastera za jačinu zvuka tri sekunde da biste koristili <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Izaberite funkciju koja će se koristiti kada dodirnete dugme Pristupačnost:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Odaberite funkciju koja će se koristiti pomoću pokreta za pristupačnost (pomoću dva prsta prevucite nagore od dna ekrana):"</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 2bdd4f7ad230..57e6409c93c0 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -1663,7 +1663,6 @@
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"Вы няправільна ўвялі графічны ключ разблакiроўкi пэўную колькасць разоў: <xliff:g id="NUMBER_0">%1$d</xliff:g>. Пасля яшчэ некалькiх няўдалых спроб (<xliff:g id="NUMBER_1">%2$d</xliff:g>) вам будзе прапанавана разблакiраваць тэлефон, увайшоўшы ў Google.\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">"Выдалiць"</string>
- <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Запушчаны ў фонавым рэжыме асноўны сэрвіс з пакета \"<xliff:g id="PACKAGENAME">%1$s</xliff:g>\" не будзе мець дазволу while-in-use у будучых зборках на мове R. Наведайце сайт go/r-bg-fgs-restriction і адпраўце справаздачу пра памылку."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Павялiчыць гук вышэй рэкамендаванага ўзроўню?\n\nДоўгае праслухоўванне музыкi на вялiкай гучнасцi можа пашкодзiць ваш слых."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Выкарыстоўваць камбінацыю хуткага доступу для спецыяльных магчымасцей?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Калі хуткі доступ уключаны, вы можаце націснуць абедзве кнопкі гучнасці і ўтрымліваць іх 3 секунды, каб запусціць функцыю спецыяльных магчымасцей."</string>
@@ -1687,7 +1686,7 @@
<string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Адмовіць"</string>
<string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Каб пачаць выкарыстоўваць функцыю, націсніце на яе:"</string>
<string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Выберыце функцыі, якія будзеце выкарыстоўваць з кнопкай спецыяльных магчымасцей"</string>
- <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Выберыце функцыі, якія будзеце выкарыстоўваць са спалучэннем клавішы гучнасці"</string>
+ <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="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Змяніць ярлыкі"</string>
<string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Гатова"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index a574fec312b6..99d7d8651d1e 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -308,7 +308,7 @@
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Физическа активност"</string>
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"достъп до физическата ви активност"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Камера"</string>
- <string name="permgroupdesc_camera" msgid="7585150538459320326">"да прави снимки и записва видеоклипове"</string>
+ <string name="permgroupdesc_camera" msgid="7585150538459320326">"да прави снимки и записва видео"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Списъци с обажданията"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"четене и запис на списъка с телефонните обаждания"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Телефон"</string>
@@ -436,9 +436,9 @@
<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="1354600178048761499">"Това приложение може по всяко време да прави снимки и да записва видеоклипове посредством камерата."</string>
+ <string name="permdesc_camera" msgid="1354600178048761499">"Това приложение може по всяко време да прави снимки и да записва видео посредством камерата."</string>
<string name="permlab_systemCamera" msgid="3642917457796210580">"Разрешаване на достъп на приложение или услуга до системните камери с цел правене на снимки и видеоклипове"</string>
- <string name="permdesc_systemCamera" msgid="5938360914419175986">"Това привилегировано или системно приложение може по всяко време да прави снимки и да записва видеоклипове посредством системна камера. Необходимо е също на приложението да бъде дадено разрешението android.permission.CAMERA"</string>
+ <string name="permdesc_systemCamera" msgid="5938360914419175986">"Това привилегировано или системно приложение може по всяко време да прави снимки и да записва видео посредством системна камера. Необходимо е също на приложението да бъде дадено разрешението android.permission.CAMERA"</string>
<string name="permlab_cameraOpenCloseListener" msgid="5548732769068109315">"Разрешаване на приложение или услуга да получават обратни повиквания за отварянето или затварянето на снимачни устройства."</string>
<string name="permdesc_cameraOpenCloseListener" msgid="2002636131008772908">"Това приложение може да получава обратни повиквания, когато снимачно устройство бъде отворено (от кое приложение) или затворено."</string>
<string name="permlab_vibrate" msgid="8596800035791962017">"контролиране на вибрирането"</string>
@@ -1619,11 +1619,10 @@
<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="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Задният план, който е стартирал услуга на преден план от <xliff:g id="PACKAGENAME">%1$s</xliff:g>, няма да има разрешение при използване в бъдещите компилации R. Моля, вижте go/r-bg-fgs-restriction и подайте сигнал за програмна грешка."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Да се увеличи ли силата на звука над препоръчителното ниво?\n\nПродължителното слушане при висока сила на звука може да увреди слуха ви."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Искате ли да използвате пряк път към функцията за достъпност?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Когато прекият път е включен, можете да стартирате дадена функция за достъпност, като натиснете двата бутона за силата на звука и ги задържите за 3 секунди."</string>
- <string name="accessibility_shortcut_multiple_service_warning_title" msgid="8417489297036013065">"Да се включат ли функциите за достъпност?"</string>
+ <string name="accessibility_shortcut_multiple_service_warning_title" msgid="8417489297036013065">"Включване на функциите за достъпност?"</string>
<string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"Натиснете двата бутона за силата на звука и ги задръжте за няколко секунди, за да включите функциите за достъпност. Това може да промени начина, по който работи устройството ви.\n\nТекущи функции:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nМожете да промените избраните функции от „Настройки“ &gt; „Достъпност“."</string>
<string name="accessibility_shortcut_multiple_service_list" msgid="6935581470716541531">" • <xliff:g id="SERVICE">%1$s</xliff:g>\n"</string>
<string name="accessibility_shortcut_single_service_warning_title" msgid="2819109500943271385">"Да се включи ли <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index 98c778cbd759..d560ce934440 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -238,7 +238,7 @@
<string name="global_action_lock" msgid="6949357274257655383">"স্ক্রীণ লক"</string>
<string name="global_action_power_off" msgid="4404936470711393203">"পাওয়ার বন্ধ করুন"</string>
<string name="global_action_power_options" msgid="1185286119330160073">"ফোন বন্ধ করুন"</string>
- <string name="global_action_restart" msgid="4678451019561687074">"ফোন আবার চালু করুন"</string>
+ <string name="global_action_restart" msgid="4678451019561687074">"ফোন রিস্টার্ট করুন"</string>
<string name="global_action_emergency" msgid="1387617624177105088">"জরুরী"</string>
<string name="global_action_bug_report" msgid="5127867163044170003">"ত্রুটির প্রতিবেদন"</string>
<string name="global_action_logout" msgid="6093581310002476511">"সেশন শেষ করুন"</string>
@@ -1619,12 +1619,11 @@
<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="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> থেকে শুরু হওয়া ফোরগ্রাউন্ড পরিষেবাটির ভবিষ্যতে আর বিল্ডগুলিতে ব্যবহারের অনুমতি নেই। go/r-bg-fgs-restriction দেখুন এবং বাগরিপোর্ট জমা দিন।"</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"প্রস্তাবিত স্তরের চেয়ে বেশি উঁচুতে ভলিউম বাড়াবেন?\n\nউঁচু ভলিউমে বেশি সময় ধরে কিছু শুনলে আপনার শ্রবনশক্তির ক্ষতি হতে পারে।"</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"অ্যাক্সেসযোগ্যতা শর্টকাট ব্যবহার করবেন?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"শর্টকাট চালু করা থাকাকালীন দুটি ভলিউম বোতাম একসাথে ৩ সেকেন্ড টিপে ধরে রাখলে একটি অ্যাকসেসিবিলিটি ফিচার চালু হবে।"</string>
<string name="accessibility_shortcut_multiple_service_warning_title" msgid="8417489297036013065">"অ্যাক্সেসিবিলিটি ফিচার চালু করতে চান?"</string>
- <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"উভয় ভলিউম কী কয়েক সেকেন্ড ধরে থাকলে অ্যাক্সেসিবিলিটি ফিচার চালু হয়ে যাবে। এর ফলে, আপনার ডিভাইস কীভাবে কাজ করবে সেটিতে পরিবর্তন হতে পারে।\n\nবর্তমান ফিচার:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nসেটিংস &gt; অ্যাক্সেসিবিলিটি থেকে আপনি বাছাই করা ফিচার পরিবর্তন করতে পারবেন।"</string>
+ <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"উভয় ভলিউম কী কয়েক সেকেন্ড ধরে থাকলে অ্যাক্সেসিবিলিটি ফিচার চালু হয়ে যাবে। এর ফলে, আপনার ডিভাইস কীভাবে কাজ করবে সেটিতে পরিবর্তন হতে পারে।\n\nবর্তমান ফিচার:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nসেটিংস &gt; অ্যাক্সেসিবিলিটি বিকল্প থেকে আপনি বাছাই করা ফিচার পরিবর্তন করতে পারবেন।"</string>
<string name="accessibility_shortcut_multiple_service_list" msgid="6935581470716541531">" • <xliff:g id="SERVICE">%1$s</xliff:g>\n"</string>
<string name="accessibility_shortcut_single_service_warning_title" msgid="2819109500943271385">"<xliff:g id="SERVICE">%1$s</xliff:g> চালু করতে চান?"</string>
<string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"উভয় ভলিউম কী কয়েক সেকেন্ড ধরে থাকলে <xliff:g id="SERVICE">%1$s</xliff:g> চালু হয়ে যাবে। এটি একটি অ্যাক্সেসিবিলিটি ফিচার। এর ফলে, আপনার ডিভাইস কীভাবে কাজ করবে সেটিতে পরিবর্তন হতে পারে।\n\nসেটিংস &gt; অ্যাক্সেসিবিলিটি থেকে আপনি এই শর্টকাট পরিবর্তন করতে পারবেন।"</string>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index 8c0459103696..a4c1ba42377c 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -1328,7 +1328,7 @@
<string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"Priključeni uređaj nije kompatibilan s ovim telefonom. Dodirnite da saznate više."</string>
<string name="adb_active_notification_title" msgid="408390247354560331">"Otklanjanje grešaka putem USB-a je uspostavljeno"</string>
<string name="adb_active_notification_message" msgid="5617264033476778211">"Dodirnite da isključite otklanjanje grešaka putem USB-a"</string>
- <string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"Odaberite da onemogućite ispravljanje grešaka koristeći USB"</string>
+ <string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"Odaberite da onemogućite otklanjanje grešaka putem USB-a"</string>
<string name="adbwifi_active_notification_title" msgid="6147343659168302473">"Bežično otklanjanje grešaka je povezano"</string>
<string name="adbwifi_active_notification_message" msgid="930987922852867972">"Dodirnite da isključite bežično otklanjanje grešaka"</string>
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Odaberite da onemogućite bežično otklanjanje grešaka."</string>
@@ -1641,17 +1641,16 @@
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"Pogrešno ste nacrtali uzorak za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Ako napravite još <xliff:g id="NUMBER_1">%2$d</xliff:g> pokušaja bez uspjeha, od vas će se tražiti da otključate telefon pomoću e-pošte. \n\n Pokušajte ponovo za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
<string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Ukloni"</string>
- <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Usluge iz prvog plana započete u pozadini s web lokacije <xliff:g id="PACKAGENAME">%1$s</xliff:g> neće imati odobrenje za funkciju \"za vrijeme korištenja\" u budućim R verzijama. Pogledajte go/r-bg-fgs-restriction i podnesite izvještaj o greškama."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Želite li pojačati zvuk iznad preporučenog nivoa?\n\nDužim slušanjem glasnog zvuka možete oštetiti sluh."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Želite li koristiti Prečicu za pristupačnost?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Kada je prečica uključena, pritiskom i držanjem oba dugmeta za jačinu zvuka u trajanju od 3 sekunde pokrenut će se funkcija pristupačnosti."</string>
<string name="accessibility_shortcut_multiple_service_warning_title" msgid="8417489297036013065">"Uključiti funkcije pristupačnosti?"</string>
- <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"Ako nekoliko sekundi držite pritisnute obje tipke za jačinu zvuka, uključit ćete funkcije pristupačnosti. Ovo može uticati na način rada uređaja.\n\nTrenutne funkcije:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nOdabrane funkcije možete izmijeniti u odjeljku Postavke &gt; Pristupačnost."</string>
+ <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"Ako nekoliko sekundi držite pritisnute obje tipke za jačinu zvuka, uključit ćete funkcije pristupačnosti. Ovo može uticati na način rada uređaja.\n\nTrenutne funkcije:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nOdabrane funkcije možete promijeniti u odjeljku Postavke &gt; Pristupačnost."</string>
<string name="accessibility_shortcut_multiple_service_list" msgid="6935581470716541531">" • <xliff:g id="SERVICE">%1$s</xliff:g>\n"</string>
<string name="accessibility_shortcut_single_service_warning_title" msgid="2819109500943271385">"Uključiti <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
<string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Ako nekoliko sekundi držite pritisnute obje tipke za jačinu zvuka, uključit ćete funkciju pristupačnosti <xliff:g id="SERVICE">%1$s</xliff:g>. Ovo može promijeniti način rada uređaja.\n\nOvu prečicu možete zamijeniti drugom funkcijom u odjeljku Postavke &gt; Pristupačnost."</string>
<string name="accessibility_shortcut_on" msgid="5463618449556111344">"Uključi"</string>
- <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Nemoj uključivati"</string>
+ <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Nemoj uključiti"</string>
<string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"UKLJUČENO"</string>
<string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"ISKLJUČENO"</string>
<string name="accessibility_enable_service_title" msgid="3931558336268541484">"Dozvoliti da usluga <xliff:g id="SERVICE">%1$s</xliff:g> ima punu kontrolu nad vašim uređajem?"</string>
@@ -1665,7 +1664,7 @@
<string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Odbij"</string>
<string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Dodirnite funkciju da je počnete koristiti:"</string>
<string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Odaberite funkcije koje ćete koristiti s dugmetom Pristupačnost"</string>
- <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Odaberite funkcije koje ćete koristiti s tipkom prečice za jačinu zvuka"</string>
+ <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Odaberite funkcije koje ćete koristiti pomoću prečice tipke za jačinu zvuka"</string>
<string name="accessibility_uncheck_legacy_item_warning" msgid="8047830891064817447">"Usluga <xliff:g id="SERVICE_NAME">%s</xliff:g> je isključena"</string>
<string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Uredi prečice"</string>
<string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Gotovo"</string>
@@ -1953,7 +1952,7 @@
<string name="app_category_maps" msgid="6395725487922533156">"Mape i navigacija"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Produktivnost"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Memorija uređaja"</string>
- <string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Otklanjanje grešaka putem uređaja spojenog na USB"</string>
+ <string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Otklanjanje grešaka putem USB-a"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"sat"</string>
<string name="time_picker_minute_label" msgid="8307452311269824553">"minuta"</string>
<string name="time_picker_header_text" msgid="9073802285051516688">"Postavljanje vremena"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index fc9471f5d449..0a5907ef4274 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -237,7 +237,7 @@
<string name="global_actions" product="default" msgid="6410072189971495460">"Opcions del telèfon"</string>
<string name="global_action_lock" msgid="6949357274257655383">"Bloqueig de pantalla"</string>
<string name="global_action_power_off" msgid="4404936470711393203">"Apaga"</string>
- <string name="global_action_power_options" msgid="1185286119330160073">"Engegada"</string>
+ <string name="global_action_power_options" msgid="1185286119330160073">"Engega"</string>
<string name="global_action_restart" msgid="4678451019561687074">"Reinicia"</string>
<string name="global_action_emergency" msgid="1387617624177105088">"Emergència"</string>
<string name="global_action_bug_report" msgid="5127867163044170003">"Informe d\'error"</string>
@@ -264,7 +264,7 @@
<string name="global_action_settings" msgid="4671878836947494217">"Configuració"</string>
<string name="global_action_assist" msgid="2517047220311505805">"Assistència"</string>
<string name="global_action_voice_assist" msgid="6655788068555086695">"Assist. per veu"</string>
- <string name="global_action_lockdown" msgid="2475471405907902963">"Bloq. de seguretat"</string>
+ <string name="global_action_lockdown" msgid="2475471405907902963">"Bloqueig de seguretat"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"+999"</string>
<string name="notification_hidden_text" msgid="2835519769868187223">"Notificació nova"</string>
<string name="notification_channel_virtual_keyboard" msgid="6465975799223304567">"Teclat virtual"</string>
@@ -1619,7 +1619,6 @@
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"Has dibuixat el patró de desbloqueig <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades de manera incorrecta. Si falles <xliff:g id="NUMBER_1">%2$d</xliff:g> vegades més, se\'t demanarà que desbloquegis el telèfon amb un compte de correu electrònic.\n\n Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_2">%3$d</xliff:g> segons."</string>
<string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Elimina"</string>
- <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"El servei en primer pla (<xliff:g id="PACKAGENAME">%1$s</xliff:g>) iniciat en segon pla no tindrà permís durant l\'ús en compilacions R posteriors. Consulta la pàgina go/r-bg-fgs-restriction i presenta un informe d\'errors."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Vols apujar el volum per sobre del nivell recomanat?\n\nSi escoltes música a un volum alt durant períodes llargs, pots danyar-te l\'oïda."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Vols fer servir la drecera d\'accessibilitat?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Si la drecera està activada, prem els dos botons de volum durant 3 segons per iniciar una funció d\'accessibilitat."</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 90ee8f25d2bf..3ce57233cc09 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -1663,7 +1663,6 @@
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"Již <xliff:g id="NUMBER_0">%1$d</xliff:g>krát jste nesprávně nakreslili své heslo odemknutí. Po <xliff:g id="NUMBER_1">%2$d</xliff:g> dalších neúspěšných pokusech budete požádáni o odemčení telefonu pomocí e-mailového účtu.\n\n Zkuste to znovu za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
<string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" – "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Odebrat"</string>
- <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Služba v popředí z balíčku <xliff:g id="PACKAGENAME">%1$s</xliff:g>, která byla spuštěna na pozadí, v budoucích sestavenách typu R nebude mít oprávnění ke spuštění při používání. Přejděte na adresu go/r-bg-fgs-restriction a vyplňte zprávu o chybě."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Zvýšit hlasitost nad doporučenou úroveň?\n\nDlouhodobý poslech hlasitého zvuku může poškodit sluch."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Použít zkratku přístupnosti?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Když je tato zkratka zapnutá, můžete funkci přístupnosti spustit tím, že na tři sekundy podržíte obě tlačítka hlasitosti."</string>
@@ -1696,7 +1695,7 @@
<string name="color_inversion_feature_name" msgid="326050048927789012">"Převrácení barev"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Oprava barev"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Byla podržena tlačítka hlasitosti. Služba <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je zapnutá."</string>
- <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Byla podržena tlačítka hlasitosti. Služba <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je vypnutá."</string>
+ <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Byla podržena tlačítka hlasitosti. Služba <xliff:g id="SERVICE_NAME">%1$s</xliff:g> byla vypnuta."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Chcete-li používat službu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, tři sekundy podržte stisknutá obě tlačítka hlasitosti"</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Určete, jakou funkci aktivujete klepnutím na tlačítko přístupnosti:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Určete, jakou funkci aktivujete pomocí gesta přístupnosti (přejetí dvěma prsty ze spodní části obrazovky nahoru):"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 16cae27eb2fa..bd5a0d37dd85 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -264,7 +264,7 @@
<string name="global_action_settings" msgid="4671878836947494217">"Indstillinger"</string>
<string name="global_action_assist" msgid="2517047220311505805">"Assistance"</string>
<string name="global_action_voice_assist" msgid="6655788068555086695">"Taleassistent"</string>
- <string name="global_action_lockdown" msgid="2475471405907902963">"Lukning"</string>
+ <string name="global_action_lockdown" msgid="2475471405907902963">"Lås enhed"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
<string name="notification_hidden_text" msgid="2835519769868187223">"Ny notifikation"</string>
<string name="notification_channel_virtual_keyboard" msgid="6465975799223304567">"Virtuelt tastatur"</string>
@@ -1619,7 +1619,6 @@
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"Du har tegnet dit oplåsningsmønster forkert <xliff:g id="NUMBER_0">%1$d</xliff:g> gange. Efter <xliff:g id="NUMBER_1">%2$d</xliff:g> yderligere mislykkede forsøg til vil du blive bedt om at låse din telefon op ved hjælp af en mailkonto.\n\n Prøv igen om <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunder."</string>
<string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" – "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Fjern"</string>
- <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Tjenesten i forgrunden fra <xliff:g id="PACKAGENAME">%1$s</xliff:g>, der starter i baggrunden, vil i fremtidige R-builds ikke have tilladelse, mens den er i brug. Se go/r-bg-fgs-restriction, og indsend en fejlrapport."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Vil du skrue højere op end det anbefalede lydstyrkeniveau?\n\nDu kan skade hørelsen ved at lytte til meget høj musik over længere tid."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Vil du bruge genvejen til Hjælpefunktioner?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Når genvejen er aktiveret, kan du starte en hjælpefunktion ved at trykke på begge lydstyrkeknapper i tre sekunder."</string>
@@ -1643,7 +1642,7 @@
<string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Afvis"</string>
<string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Tryk på en funktion for at bruge den:"</string>
<string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Vælg, hvilke funktioner du vil bruge med knappen Hjælpefunktioner"</string>
- <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Vælg, hvilke funktioner du vil bruge med genvejen via lydstyrkeknapperne"</string>
+ <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Vælg de funktioner, du vil bruge via lydstyrkeknapperne"</string>
<string name="accessibility_uncheck_legacy_item_warning" msgid="8047830891064817447">"<xliff:g id="SERVICE_NAME">%s</xliff:g> er blevet deaktiveret"</string>
<string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Rediger genveje"</string>
<string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Udfør"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 2763acad2672..a2a4adc782c2 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -1619,7 +1619,6 @@
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"Du hast dein Entsperrungsmuster <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal falsch gezeichnet. Nach <xliff:g id="NUMBER_1">%2$d</xliff:g> weiteren erfolglosen Versuchen wirst du aufgefordert, dein Telefon mithilfe eines E-Mail-Kontos zu entsperren.\n\n Versuche es in <xliff:g id="NUMBER_2">%3$d</xliff:g> Sekunden erneut."</string>
<string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" – "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Entfernen"</string>
- <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Der Dienst im Vordergrund von <xliff:g id="PACKAGENAME">%1$s</xliff:g>, der im Hintergrund gestartet wurde, hat in zukünftigen R-Builds keine Zugriffsberechtigung mehr während der Nutzung. Siehe dazu go/r-bg-fgs-restriction und reiche einen Fehlerbericht ein."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Lautstärke über den Schwellenwert anheben?\n\nWenn du über einen längeren Zeitraum Musik in hoher Lautstärke hörst, kann dies dein Gehör schädigen."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Verknüpfung für Bedienungshilfen verwenden?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Wenn die Verknüpfung aktiviert ist, kannst du die beiden Lautstärketasten drei Sekunden lang gedrückt halten, um eine Bedienungshilfe zu starten."</string>
@@ -1643,7 +1642,7 @@
<string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Ablehnen"</string>
<string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Zum Auswählen der gewünschten Funktion tippen:"</string>
<string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Funktionen auswählen, die du mit der Schaltfläche \"Bedienungshilfen\" verwenden möchtest"</string>
- <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Funktionen auswählen, die du mit der Verknüpfung für die Lautstärketaste verwenden möchtest"</string>
+ <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Funktionen für Verknüpfung mit Lautstärketaste auswählen"</string>
<string name="accessibility_uncheck_legacy_item_warning" msgid="8047830891064817447">"<xliff:g id="SERVICE_NAME">%s</xliff:g> wurde deaktiviert"</string>
<string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Verknüpfungen bearbeiten"</string>
<string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Fertig"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index dd19b2769f72..916ad5f1ac21 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -1619,7 +1619,6 @@
<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="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Η υπηρεσία στο προσκήνιο που ξεκίνησε από το παρασκήνιο από το πακέτο <xliff:g id="PACKAGENAME">%1$s</xliff:g> δεν θα έχει άδεια πρόσβασης μόνο κατά τη χρήση σε μελλοντικές εκδόσεις R. Ανατρέξτε στο go/r-bg-fgs-restriction και υποβάλετε αναφορά σφάλματος."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Αυξάνετε την ένταση ήχου πάνω από το επίπεδο ασφαλείας;\n\nΑν ακούτε μουσική σε υψηλή ένταση για μεγάλο χρονικό διάστημα ενδέχεται να προκληθεί βλάβη στην ακοή σας."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Να χρησιμοποιείται η συντόμευση προσβασιμότητας;"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Όταν η συντόμευση είναι ενεργοποιημένη, το πάτημα και των δύο κουμπιών έντασης ήχου για 3 δευτερόλεπτα θα ξεκινήσει μια λειτουργία προσβασιμότητας."</string>
@@ -1652,7 +1651,7 @@
<string name="color_inversion_feature_name" msgid="326050048927789012">"Αντιστροφή χρωμάτων"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Διόρθωση χρωμάτων"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Τα πλήκτρα έντασης είναι πατημένα. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ενεργοποιήθηκε."</string>
- <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Τα πλήκτρα έντασης είναι πατημένα. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> απενεργοποιήθηκε."</string>
+ <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Τα πλήκτρα έντασης είναι πατημένα. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>: απενεργοποιημένο"</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Πατήστε παρατεταμένα και τα δύο κουμπιά έντασης ήχου για τρία δευτερόλεπτα, ώστε να χρησιμοποιήσετε την υπηρεσία <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Επιλέξτε μια λειτουργία που θα χρησιμοποιείται κατά το πάτημα του κουμπιού προσβασιμότητας:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Επιλέξτε μια λειτουργία που θα χρησιμοποιείται με την κίνηση προσβασιμότητας (σύρετε με δύο δάχτυλα προς τα επάνω από το κάτω μέρος της οθόνης):"</string>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index 359052488f52..779fdff59351 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -1619,7 +1619,6 @@
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your phone using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
<string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Remove"</string>
- <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"The background started foreground service from <xliff:g id="PACKAGENAME">%1$s</xliff:g> will not have while-in-use permission in future R builds. Please see go/r-bg-fgs-restriction and file a bug report."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Raise volume above recommended level?\n\nListening at high volume for long periods may damage your hearing."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Use Accessibility Shortcut?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"When the shortcut is on, pressing both volume buttons for three seconds will start an accessibility feature."</string>
@@ -1650,7 +1649,7 @@
<string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Turn off Shortcut"</string>
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Use Shortcut"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Colour Inversion"</string>
- <string name="color_correction_feature_name" msgid="3655077237805422597">"Colour Correction"</string>
+ <string name="color_correction_feature_name" msgid="3655077237805422597">"Colour correction"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned on."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned off."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Press and hold both volume keys for three seconds to use <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -1766,7 +1765,7 @@
<string name="restr_pin_confirm_pin" msgid="7143161971614944989">"Confirm new PIN"</string>
<string name="restr_pin_create_pin" msgid="917067613896366033">"Create a PIN for modifying restrictions"</string>
<string name="restr_pin_error_doesnt_match" msgid="7063392698489280556">"PINs don\'t match. Try again."</string>
- <string name="restr_pin_error_too_short" msgid="1547007808237941065">"PIN is too short. Must be at least 4 digits."</string>
+ <string name="restr_pin_error_too_short" msgid="1547007808237941065">"PIN is too short. Must be at least four digits."</string>
<plurals name="restr_pin_countdown" formatted="false" msgid="4427486903285216153">
<item quantity="other">Try again in <xliff:g id="COUNT">%d</xliff:g> seconds</item>
<item quantity="one">Try again in 1 second</item>
@@ -1793,8 +1792,8 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Updated by your admin"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Deleted by your admin"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
- <string name="battery_saver_description_with_learn_more" msgid="5997766757551917769">"To extend battery life, Battery Saver:\n\n•Turns on Dark theme\n•Turns off or restricts background activity, some visual effects and other features like “Hey Google”\n\n"<annotation id="url">"Learn more"</annotation></string>
- <string name="battery_saver_description" msgid="8587408568232177204">"To extend battery life, Battery Saver:\n\n•Turns on Dark theme\n•Turns off or restricts background activity, some visual effects and other features like “Hey Google”"</string>
+ <string name="battery_saver_description_with_learn_more" msgid="5997766757551917769">"To extend battery life, Battery Saver:\n\n•Turns on Dark theme\n•Turns off or restricts background activity, some visual effects and other features like \'Hey Google\'\n\n"<annotation id="url">"Learn more"</annotation></string>
+ <string name="battery_saver_description" msgid="8587408568232177204">"To extend battery life, Battery Saver:\n\n•Turns on Dark theme\n•Turns off or restricts background activity, some visual effects and other features like \'Hey Google\'"</string>
<string name="data_saver_description" msgid="4995164271550590517">"To help reduce data usage, Data Saver prevents some apps from sending or receiving data in the background. An app that you’re currently using can access data, but may do so less frequently. This may mean, for example, that images don’t display until you tap them."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Turn on Data Saver?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Turn on"</string>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index baf246cad231..4d3ca94b9c91 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -316,10 +316,10 @@
<string name="permgrouplab_sensors" msgid="9134046949784064495">"Body sensors"</string>
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"access sensor data about your vital signs"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Retrieve window content"</string>
- <string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Inspect the content of a window that you\'re interacting with."</string>
+ <string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Inspect the content of a window you\'re interacting with."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Turn on Explore by Touch"</string>
<string name="capability_desc_canRequestTouchExploration" msgid="4394677060796752976">"Tapped items will be spoken aloud and the screen can be explored using gestures."</string>
- <string name="capability_title_canRequestFilterKeyEvents" msgid="2772371671541753254">"Observe text that you type"</string>
+ <string name="capability_title_canRequestFilterKeyEvents" msgid="2772371671541753254">"Observe text you type"</string>
<string name="capability_desc_canRequestFilterKeyEvents" msgid="2381315802405773092">"Includes personal data such as credit card numbers and passwords."</string>
<string name="capability_title_canControlMagnification" msgid="7701572187333415795">"Control display magnification"</string>
<string name="capability_desc_canControlMagnification" msgid="2206586716709254805">"Control the display\'s zoom level and positioning."</string>
@@ -682,7 +682,7 @@
<string name="policydesc_resetPassword" msgid="4626419138439341851">"Change the screen lock."</string>
<string name="policylab_forceLock" msgid="7360335502968476434">"Lock the screen"</string>
<string name="policydesc_forceLock" msgid="1008844760853899693">"Control how and when the screen locks."</string>
- <string name="policylab_wipeData" msgid="1359485247727537311">"Delete all data"</string>
+ <string name="policylab_wipeData" msgid="1359485247727537311">"Erase all data"</string>
<string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"Erase the tablet\'s data without warning by performing a factory data reset."</string>
<string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"Delete your Android TV device\'s data without warning by performing a factory data reset."</string>
<string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"Erase the phone\'s data without warning by performing a factory data reset."</string>
@@ -1619,7 +1619,6 @@
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your phone using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
<string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Remove"</string>
- <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"The background started foreground service from <xliff:g id="PACKAGENAME">%1$s</xliff:g> will not have while-in-use permission in future R builds. Please see go/r-bg-fgs-restriction and file a bug report."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Raise volume above recommended level?\n\nListening at high volume for long periods may damage your hearing."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Use Accessibility Shortcut?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"When the shortcut is on, pressing both volume buttons for three seconds will start an accessibility feature."</string>
@@ -1649,8 +1648,8 @@
<string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Done"</string>
<string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Turn off Shortcut"</string>
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Use Shortcut"</string>
- <string name="color_inversion_feature_name" msgid="326050048927789012">"Colour Inversion"</string>
- <string name="color_correction_feature_name" msgid="3655077237805422597">"Colour Correction"</string>
+ <string name="color_inversion_feature_name" msgid="326050048927789012">"Colour inversion"</string>
+ <string name="color_correction_feature_name" msgid="3655077237805422597">"Colour correction"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned on."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned off."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Press and hold both volume keys for three seconds to use <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -1766,7 +1765,7 @@
<string name="restr_pin_confirm_pin" msgid="7143161971614944989">"Confirm new PIN"</string>
<string name="restr_pin_create_pin" msgid="917067613896366033">"Create a PIN for modifying restrictions"</string>
<string name="restr_pin_error_doesnt_match" msgid="7063392698489280556">"PINs don\'t match. Try again."</string>
- <string name="restr_pin_error_too_short" msgid="1547007808237941065">"PIN is too short. Must be at least 4 digits."</string>
+ <string name="restr_pin_error_too_short" msgid="1547007808237941065">"PIN is too short. Must be at least four digits."</string>
<plurals name="restr_pin_countdown" formatted="false" msgid="4427486903285216153">
<item quantity="other">Try again in <xliff:g id="COUNT">%d</xliff:g> seconds</item>
<item quantity="one">Try again in 1 second</item>
@@ -1793,9 +1792,9 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Updated by your admin"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Deleted by your admin"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
- <string name="battery_saver_description_with_learn_more" msgid="5997766757551917769">"To extend battery life, Battery Saver:\n\n•Turns on Dark theme\n•Turns off or restricts background activity, some visual effects and other features like “Hey Google”\n\n"<annotation id="url">"Learn more"</annotation></string>
- <string name="battery_saver_description" msgid="8587408568232177204">"To extend battery life, Battery Saver:\n\n•Turns on Dark theme\n•Turns off or restricts background activity, some visual effects and other features like “Hey Google”"</string>
- <string name="data_saver_description" msgid="4995164271550590517">"To help reduce data usage, Data Saver prevents some apps from sending or receiving data in the background. An app that you’re currently using can access data, but may do so less frequently. This may mean, for example, that images don’t display until you tap them."</string>
+ <string name="battery_saver_description_with_learn_more" msgid="5997766757551917769">"To extend battery life, Battery Saver:\n\n• Turns on Dark theme\n• Turns off or restricts background activity, some visual effects and other features like \"Hey Google\"\n\n"<annotation id="url">"Learn more"</annotation></string>
+ <string name="battery_saver_description" msgid="8587408568232177204">"To extend battery life, Battery Saver:\n\n• Turns on Dark theme\n• Turns off or restricts background activity, some visual effects and other features like \"Hey Google\""</string>
+ <string name="data_saver_description" msgid="4995164271550590517">"To help reduce data usage, Data Saver prevents some apps from sending or receiving data in the background. An app you\'re currently using can access data, but may do so less frequently. This may mean, for example, that images don\'t display until you tap them."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Turn on Data Saver?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Turn on"</string>
<plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="2877101784123058273">
@@ -1913,7 +1912,7 @@
<string name="conference_call" msgid="5731633152336490471">"Conference Call"</string>
<string name="tooltip_popup_title" msgid="7863719020269945722">"Tooltip"</string>
<string name="app_category_game" msgid="4534216074910244790">"Games"</string>
- <string name="app_category_audio" msgid="8296029904794676222">"Music &amp; Audio"</string>
+ <string name="app_category_audio" msgid="8296029904794676222">"Music and audio"</string>
<string name="app_category_video" msgid="2590183854839565814">"Movies &amp; Video"</string>
<string name="app_category_image" msgid="7307840291864213007">"Photos &amp; Images"</string>
<string name="app_category_social" msgid="2278269325488344054">"Social &amp; Communication"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 359052488f52..779fdff59351 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -1619,7 +1619,6 @@
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your phone using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
<string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Remove"</string>
- <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"The background started foreground service from <xliff:g id="PACKAGENAME">%1$s</xliff:g> will not have while-in-use permission in future R builds. Please see go/r-bg-fgs-restriction and file a bug report."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Raise volume above recommended level?\n\nListening at high volume for long periods may damage your hearing."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Use Accessibility Shortcut?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"When the shortcut is on, pressing both volume buttons for three seconds will start an accessibility feature."</string>
@@ -1650,7 +1649,7 @@
<string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Turn off Shortcut"</string>
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Use Shortcut"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Colour Inversion"</string>
- <string name="color_correction_feature_name" msgid="3655077237805422597">"Colour Correction"</string>
+ <string name="color_correction_feature_name" msgid="3655077237805422597">"Colour correction"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned on."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned off."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Press and hold both volume keys for three seconds to use <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -1766,7 +1765,7 @@
<string name="restr_pin_confirm_pin" msgid="7143161971614944989">"Confirm new PIN"</string>
<string name="restr_pin_create_pin" msgid="917067613896366033">"Create a PIN for modifying restrictions"</string>
<string name="restr_pin_error_doesnt_match" msgid="7063392698489280556">"PINs don\'t match. Try again."</string>
- <string name="restr_pin_error_too_short" msgid="1547007808237941065">"PIN is too short. Must be at least 4 digits."</string>
+ <string name="restr_pin_error_too_short" msgid="1547007808237941065">"PIN is too short. Must be at least four digits."</string>
<plurals name="restr_pin_countdown" formatted="false" msgid="4427486903285216153">
<item quantity="other">Try again in <xliff:g id="COUNT">%d</xliff:g> seconds</item>
<item quantity="one">Try again in 1 second</item>
@@ -1793,8 +1792,8 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Updated by your admin"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Deleted by your admin"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
- <string name="battery_saver_description_with_learn_more" msgid="5997766757551917769">"To extend battery life, Battery Saver:\n\n•Turns on Dark theme\n•Turns off or restricts background activity, some visual effects and other features like “Hey Google”\n\n"<annotation id="url">"Learn more"</annotation></string>
- <string name="battery_saver_description" msgid="8587408568232177204">"To extend battery life, Battery Saver:\n\n•Turns on Dark theme\n•Turns off or restricts background activity, some visual effects and other features like “Hey Google”"</string>
+ <string name="battery_saver_description_with_learn_more" msgid="5997766757551917769">"To extend battery life, Battery Saver:\n\n•Turns on Dark theme\n•Turns off or restricts background activity, some visual effects and other features like \'Hey Google\'\n\n"<annotation id="url">"Learn more"</annotation></string>
+ <string name="battery_saver_description" msgid="8587408568232177204">"To extend battery life, Battery Saver:\n\n•Turns on Dark theme\n•Turns off or restricts background activity, some visual effects and other features like \'Hey Google\'"</string>
<string name="data_saver_description" msgid="4995164271550590517">"To help reduce data usage, Data Saver prevents some apps from sending or receiving data in the background. An app that you’re currently using can access data, but may do so less frequently. This may mean, for example, that images don’t display until you tap them."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Turn on Data Saver?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Turn on"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 359052488f52..96a4b1a4b863 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -316,7 +316,7 @@
<string name="permgrouplab_sensors" msgid="9134046949784064495">"Body sensors"</string>
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"access sensor data about your vital signs"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Retrieve window content"</string>
- <string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Inspect the content of a window that you\'re interacting with."</string>
+ <string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Inspect the content of a window you\'re interacting with."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Turn on Explore by Touch"</string>
<string name="capability_desc_canRequestTouchExploration" msgid="4394677060796752976">"Tapped items will be spoken aloud and the screen can be explored using gestures."</string>
<string name="capability_title_canRequestFilterKeyEvents" msgid="2772371671541753254">"Observe text that you type"</string>
@@ -1006,7 +1006,7 @@
<string name="hour" msgid="7796325297097314653">"hour"</string>
<string name="hours" msgid="8517014849629200683">"hours"</string>
<string name="minute" msgid="8369209540986467610">"min"</string>
- <string name="minutes" msgid="3456532942641808971">"mins"</string>
+ <string name="minutes" msgid="3456532942641808971">"Min."</string>
<string name="second" msgid="9210875257112211713">"sec"</string>
<string name="seconds" msgid="2175052687727971048">"secs"</string>
<string name="week" msgid="907127093960923779">"week"</string>
@@ -1619,7 +1619,6 @@
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your phone using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
<string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Remove"</string>
- <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"The background started foreground service from <xliff:g id="PACKAGENAME">%1$s</xliff:g> will not have while-in-use permission in future R builds. Please see go/r-bg-fgs-restriction and file a bug report."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Raise volume above recommended level?\n\nListening at high volume for long periods may damage your hearing."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Use Accessibility Shortcut?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"When the shortcut is on, pressing both volume buttons for three seconds will start an accessibility feature."</string>
@@ -1650,7 +1649,7 @@
<string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Turn off Shortcut"</string>
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Use Shortcut"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Colour Inversion"</string>
- <string name="color_correction_feature_name" msgid="3655077237805422597">"Colour Correction"</string>
+ <string name="color_correction_feature_name" msgid="3655077237805422597">"Color correction"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned on."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned off."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Press and hold both volume keys for three seconds to use <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -1766,7 +1765,7 @@
<string name="restr_pin_confirm_pin" msgid="7143161971614944989">"Confirm new PIN"</string>
<string name="restr_pin_create_pin" msgid="917067613896366033">"Create a PIN for modifying restrictions"</string>
<string name="restr_pin_error_doesnt_match" msgid="7063392698489280556">"PINs don\'t match. Try again."</string>
- <string name="restr_pin_error_too_short" msgid="1547007808237941065">"PIN is too short. Must be at least 4 digits."</string>
+ <string name="restr_pin_error_too_short" msgid="1547007808237941065">"PIN is too short. Must be at least four digits."</string>
<plurals name="restr_pin_countdown" formatted="false" msgid="4427486903285216153">
<item quantity="other">Try again in <xliff:g id="COUNT">%d</xliff:g> seconds</item>
<item quantity="one">Try again in 1 second</item>
@@ -1793,8 +1792,8 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Updated by your admin"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Deleted by your admin"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
- <string name="battery_saver_description_with_learn_more" msgid="5997766757551917769">"To extend battery life, Battery Saver:\n\n•Turns on Dark theme\n•Turns off or restricts background activity, some visual effects and other features like “Hey Google”\n\n"<annotation id="url">"Learn more"</annotation></string>
- <string name="battery_saver_description" msgid="8587408568232177204">"To extend battery life, Battery Saver:\n\n•Turns on Dark theme\n•Turns off or restricts background activity, some visual effects and other features like “Hey Google”"</string>
+ <string name="battery_saver_description_with_learn_more" msgid="5997766757551917769">"To extend battery life, Battery Saver:\n\n•Turns on Dark theme\n•Turns off or restricts background activity, some visual effects and other features like \'Hey Google\'\n\n"<annotation id="url">"Learn more"</annotation></string>
+ <string name="battery_saver_description" msgid="8587408568232177204">"To extend battery life, Battery Saver:\n\n•Turns on Dark theme\n•Turns off or restricts background activity, some visual effects and other features like \'Hey Google\'"</string>
<string name="data_saver_description" msgid="4995164271550590517">"To help reduce data usage, Data Saver prevents some apps from sending or receiving data in the background. An app that you’re currently using can access data, but may do so less frequently. This may mean, for example, that images don’t display until you tap them."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Turn on Data Saver?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Turn on"</string>
diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml
index 31abd8235bf4..fef02fbc3daa 100644
--- a/core/res/res/values-en-rXC/strings.xml
+++ b/core/res/res/values-en-rXC/strings.xml
@@ -1619,7 +1619,6 @@
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‏‎‎‏‎‎‏‎‏‏‏‎‏‏‏‎‎‏‏‏‏‎‎‏‎‏‏‏‏‎‏‏‏‏‏‏‎‎‏‏‏‏‎‎‏‎‎‎‎‎‏‏‎‏‏‎‎‎You have incorrectly drawn your unlock pattern ‎‏‎‎‏‏‎<xliff:g id="NUMBER_0">%1$d</xliff:g>‎‏‎‎‏‏‏‎ times. After ‎‏‎‎‏‏‎<xliff:g id="NUMBER_1">%2$d</xliff:g>‎‏‎‎‏‏‏‎ more unsuccessful attempts, you will be asked to unlock your phone using an email account.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎ Try again in ‎‏‎‎‏‏‎<xliff:g id="NUMBER_2">%3$d</xliff:g>‎‏‎‎‏‏‏‎ seconds.‎‏‎‎‏‎"</string>
<string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" ‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‎‏‎‎‎‎‎‎‎‎‏‏‎‎‎‏‏‎‏‎‏‏‏‏‏‏‎‏‎‏‏‎‎‎‏‎‏‎‏‏‏‏‏‎‏‎‏‏‏‎‏‏‎‎‎‏‎‎ — ‎‏‎‎‏‎ "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‎‎‎‏‏‏‎‏‏‎‏‏‏‏‏‎‏‏‏‏‏‎‏‎‎‎‎‎‎‎‏‏‏‎‎‎‎‏‏‎‏‏‏‎‏‏‎‎‎‎‎‎‎‎‎‏‎‎Remove‎‏‎‎‏‎"</string>
- <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‎‏‏‏‎‏‎‏‎‏‏‏‎‎‎‏‎‏‎‏‏‎‏‎‎‏‏‎‎‏‎‎‏‏‏‏‏‏‏‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‎The background started foreground service from ‎‏‎‎‏‏‎<xliff:g id="PACKAGENAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ will not have while-in-use permission in future R builds. Please see go/r-bg-fgs-restriction and file a bugreport.‎‏‎‎‏‎"</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‎‎‎‎‏‎‎‎‎‏‎‏‎‎‎‏‎‎‎‏‏‎‎‎‏‏‏‎‎‏‏‏‏‏‏‎‎‏‏‎‏‎‎‏‎‏‎‏‏‎‎‎‎‏‎‏‎‎Raise volume above recommended level?‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Listening at high volume for long periods may damage your hearing.‎‏‎‎‏‎"</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‏‏‏‎‎‎‎‏‎‏‏‎‎‏‎‎‏‏‏‏‎‏‏‎‏‎‎‎‏‎‏‏‎‏‎‏‎‏‎‏‎‏‎‏‏‏‎‎‎‎‏‎‏‎‏‎‏‎Use Accessibility Shortcut?‎‏‎‎‏‎"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‏‏‎‎‎‎‎‏‎‏‏‎‎‎‏‏‎‎‏‎‎‎‎‎‎‏‎‏‏‏‎‎‏‎‎‏‏‏‎‎‏‏‎‎‎‎‏‎‏‎‎‎‏‎‎‎‎When the shortcut is on, pressing both volume buttons for 3 seconds will start an accessibility feature.‎‏‎‎‏‎"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 005dd5d5f6de..35f3766e0c19 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -1619,7 +1619,6 @@
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"Dibujaste incorrectamente tu patrón de desbloqueo <xliff:g id="NUMBER_0">%1$d</xliff:g> veces. Luego de <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos incorrectos más, se te solicitará que desbloquees tu dispositivo mediante el uso de una cuenta de correo.\n\n Vuelve a intentarlo en <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
<string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Eliminar"</string>
- <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"El servicio que pasó del segundo al primer plano de <xliff:g id="PACKAGENAME">%1$s</xliff:g> no tendrá permiso durante el uso en las próximas compilaciones de R. Ve a go/r-bg-fgs-restriction y envía un informe de errores."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"¿Quieres subir el volumen por encima del nivel recomendado?\n\nEscuchar a un alto volumen durante largos períodos puede dañar tu audición."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"¿Usar acceso directo de accesibilidad?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Cuando la combinación de teclas está activada, puedes presionar los botones de volumen durante 3 segundos para iniciar una función de accesibilidad."</string>
@@ -1643,7 +1642,7 @@
<string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Rechazar"</string>
<string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Presiona una función para comenzar a usarla:"</string>
<string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Selecciona las funciones a utilizar con el botón de accesibilidad"</string>
- <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Selecciona las funciones a utilizar con la combinación de teclas de volumen"</string>
+ <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Selecciona las funciones a usar con las teclas de volumen"</string>
<string name="accessibility_uncheck_legacy_item_warning" msgid="8047830891064817447">"Se desactivó <xliff:g id="SERVICE_NAME">%s</xliff:g>"</string>
<string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Editar accesos directos"</string>
<string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Listo"</string>
@@ -1651,7 +1650,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Usar acceso directo"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Inversión de color"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Corrección de color"</string>
- <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Al mantener presionadas las teclas de volumen, se activó <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
+ <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Como mantuviste presionadas las teclas de volumen, se activó <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Al mantener presionadas las teclas de volumen, se desactivó <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Mantén presionadas ambas teclas de volumen durante tres segundos para usar <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Elige una función para usar cuando pulses el botón accesibilidad:"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index e18fc11bc7c3..4640e4b699d6 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -1311,7 +1311,7 @@
<string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"Seleccionar para inhabilitar la depuración USB"</string>
<string name="adbwifi_active_notification_title" msgid="6147343659168302473">"Depuración inalámbrica conectada"</string>
<string name="adbwifi_active_notification_message" msgid="930987922852867972">"Toca para desactivar la depuración inalámbrica"</string>
- <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Selecciona para inhabilitar la depuración inalámbrica."</string>
+ <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Toca para desactivar la depuración inalámbrica."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Modo de agente de prueba habilitado"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Restablece los ajustes de fábrica para inhabilitar el modo de agente de prueba."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"Se ha habilitado la consola en serie"</string>
@@ -1619,12 +1619,11 @@
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"Has fallado <xliff:g id="NUMBER_0">%1$d</xliff:g> veces al dibujar el patrón de desbloqueo. Si fallas otras <xliff:g id="NUMBER_1">%2$d</xliff:g> veces, deberás usar una cuenta de correo electrónico para desbloquear el teléfono.\n\n Inténtalo de nuevo en <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
<string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Quitar"</string>
- <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"El servicio en primer plano que se inició en segundo plano en <xliff:g id="PACKAGENAME">%1$s</xliff:g> no tendrá permisos en compilaciones R futuras mientras se estén usando. Ve a go/r-bg-fgs-restriction y envía un informe de errores."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"¿Quieres subir el volumen por encima del nivel recomendado?\n\nEscuchar sonidos fuertes durante mucho tiempo puede dañar los oídos."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"¿Utilizar acceso directo de accesibilidad?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Si el acceso directo está activado, pulsa los dos botones de volumen durante 3 segundos para iniciar una función de accesibilidad."</string>
- <string name="accessibility_shortcut_multiple_service_warning_title" msgid="8417489297036013065">"¿Quieres activar las funciones de accesibilidad?"</string>
- <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"Al mantener pulsadas ambas teclas de volumen durante unos segundos, se activan las funciones de accesibilidad, que pueden cambiar el funcionamiento del dispositivo.\n\nFunciones actuales:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nPuedes cambiar las funciones seleccionadas en Ajustes &gt; Accesibilidad."</string>
+ <string name="accessibility_shortcut_multiple_service_warning_title" msgid="8417489297036013065">"¿Activar funciones de accesibilidad?"</string>
+ <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"Al mantener pulsadas las dos teclas de volumen durante unos segundos, se activan las funciones de accesibilidad, que pueden cambiar el funcionamiento del dispositivo.\n\nFunciones actuales:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nPuedes cambiar las funciones seleccionadas en Ajustes &gt; Accesibilidad."</string>
<string name="accessibility_shortcut_multiple_service_list" msgid="6935581470716541531">" • <xliff:g id="SERVICE">%1$s</xliff:g>\n"</string>
<string name="accessibility_shortcut_single_service_warning_title" msgid="2819109500943271385">"¿Quieres activar <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
<string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Al mantener pulsadas ambas teclas de volumen durante unos segundos se activa <xliff:g id="SERVICE">%1$s</xliff:g>, una función de accesibilidad. Esta función puede modificar el funcionamiento del dispositivo.\n\nPuedes asignar este acceso directo a otra función en Ajustes &gt; Accesibilidad."</string>
@@ -1642,8 +1641,8 @@
<string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Permitir"</string>
<string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Denegar"</string>
<string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Toca una función para empezar a usarla:"</string>
- <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Seleccionar qué funciones usar con el botón Accesibilidad"</string>
- <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Seleccionar qué funciones usar con la tecla de volumen"</string>
+ <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Selecciona qué funciones usar con el botón Accesibilidad"</string>
+ <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Selecciona qué funciones usar con la tecla de volumen"</string>
<string name="accessibility_uncheck_legacy_item_warning" msgid="8047830891064817447">"Se ha desactivado <xliff:g id="SERVICE_NAME">%s</xliff:g>"</string>
<string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Editar accesos directos"</string>
<string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Listo"</string>
@@ -1651,8 +1650,8 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Utilizar acceso directo"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Inversión de color"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Corrección de color"</string>
- <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Al mantener pulsadas las teclas de volumen, <xliff:g id="SERVICE_NAME">%1$s</xliff:g> se ha activado."</string>
- <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Al mantener pulsadas las teclas de volumen, <xliff:g id="SERVICE_NAME">%1$s</xliff:g> se ha desactivado."</string>
+ <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Al mantener pulsadas las teclas de volumen, se ha activado <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
+ <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Se han mantenido pulsadas las teclas de volumen. Se ha desactivado <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Para utilizar <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, mantén pulsadas ambas teclas de volumen durante 3 segundos"</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Selecciona la función que se utilizará cuando toques el botón Accesibilidad:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Elige la función que se utilizará con el gesto de accesibilidad (deslizar dos dedos hacia arriba desde la parte inferior de la pantalla):"</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 56887d822483..6b5741cb6913 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -1619,15 +1619,14 @@
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"Joonistasite oma avamismustri <xliff:g id="NUMBER_0">%1$d</xliff:g> korda valesti. Pärast veel <xliff:g id="NUMBER_1">%2$d</xliff:g> ebaõnnestunud katset palutakse teil telefon avada meilikontoga.\n\n Proovige uuesti <xliff:g id="NUMBER_2">%3$d</xliff:g> sekundi pärast."</string>
<string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Eemalda"</string>
- <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Taustal käitatud esiplaanil oleval teenusel paketist <xliff:g id="PACKAGENAME">%1$s</xliff:g> ei ole tulevastes R-järkudes luba „kui kasutuses”. Vaadake saiti go/r-bg-fgs-restriction ja esitage veaaruanne."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Kas suurendada helitugevuse taset üle soovitatud taseme?\n\nPikaajaline valju helitugevusega kuulamine võib kuulmist kahjustada."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Kas kasutada juurdepääsetavuse otseteed?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Kui otsetee on sisse lülitatud, käivitab mõlema helitugevuse nupu kolm sekundit all hoidmine juurdepääsetavuse funktsiooni."</string>
<string name="accessibility_shortcut_multiple_service_warning_title" msgid="8417489297036013065">"Kas lülitada juurdepääsufunktsioonid sisse?"</string>
- <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"Hoidke mõlemat helitugevuse nuppu mõni sekund all, et juurdepääsufunktsioonid sisse lülitada. See võib teie seadme tööviisi muuta.\n\nPraegused funktsioonid:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nValitud funktsioone saab muuta jaotises Seaded &gt; Juurdepääsetavus."</string>
+ <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"Hoidke juurdepääsufunktsioonide sisselülitamiseks mõlemat helitugevuse klahvi mõni sekund all. See võib teie seadme tööviisi muuta.\n\nPraegused funktsioonid:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nValitud funktsioone saab muuta jaotises Seaded &gt; Juurdepääsetavus."</string>
<string name="accessibility_shortcut_multiple_service_list" msgid="6935581470716541531">" • <xliff:g id="SERVICE">%1$s</xliff:g>\n"</string>
<string name="accessibility_shortcut_single_service_warning_title" msgid="2819109500943271385">"Kas lülitada <xliff:g id="SERVICE">%1$s</xliff:g> sisse?"</string>
- <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Kui hoiate mõlemat helitugevuse nuppu mõni sekund all, lülitatakse sisse juurdepääsufunktsioon <xliff:g id="SERVICE">%1$s</xliff:g>. See võib teie seadme tööviisi muuta.\n\nSelle otsetee saab asendada muu otseteega jaotises Seaded &gt; Juurdepääsetavus."</string>
+ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Kui hoiate mõlemat helitugevuse klahvi mõni sekund all, lülitatakse juurdepääsufunktsioon <xliff:g id="SERVICE">%1$s</xliff:g> sisse. See võib teie seadme tööviisi muuta.\n\nSelle otsetee saab asendada muu otseteega jaotises Seaded &gt; Juurdepääsetavus."</string>
<string name="accessibility_shortcut_on" msgid="5463618449556111344">"Lülita sisse"</string>
<string name="accessibility_shortcut_off" msgid="3651336255403648739">"Ära lülita sisse"</string>
<string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"SEES"</string>
@@ -1643,7 +1642,7 @@
<string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Keela"</string>
<string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Puudutage funktsiooni, et selle kasutamist alustada."</string>
<string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Valige funktsioonid, mida juurdepääsetavuse nupuga kasutada"</string>
- <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Valige funktsioonid, mida helitugevuse nupu otseteega kasutada"</string>
+ <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Valige helitugevuse nupu otsetee funktsioonid"</string>
<string name="accessibility_uncheck_legacy_item_warning" msgid="8047830891064817447">"<xliff:g id="SERVICE_NAME">%s</xliff:g> on välja lülitatud"</string>
<string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Muuda otseteid"</string>
<string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Valmis"</string>
@@ -1651,13 +1650,13 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Kasuta otseteed"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Värvide ümberpööramine"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Värvide korrigeerimine"</string>
- <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Helitugevuse nuppe hoiti all. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> lülitati sisse."</string>
- <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Helitugevuse nuppe hoiti all. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> lülitati välja."</string>
+ <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Helitugevuse klahve hoiti all. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> lülitati sisse."</string>
+ <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Helitugevuse klahve hoiti all. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> lülitati välja."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Teenuse <xliff:g id="SERVICE_NAME">%1$s</xliff:g> kasutamiseks hoidke kolm sekundit all mõlemat helitugevuse klahvi"</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Valige, millist funktsiooni kasutada, kui vajutate juurdepääsetavuse nuppu:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Valige, millist funktsiooni juurdepääsetavuse liigutusega (kahe sõrmega ekraanikuval alt üles pühkimine) kasutada:"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Valige, millist funktsiooni juurdepääsetavuse liigutusega (kolme sõrmega ekraanikuval alt üles pühkimine) kasutada:"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Funktsioonide vahel vahetamiseks vajutage pikalt juurdepääsetavuse nuppu."</string>
+ <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Funktsioonide vahel vahetamiseks vajutage juurdepääsetavuse nuppu pikalt."</string>
<string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Funktsioonide vahel vahetamiseks pühkige kahe sõrmega üles ja hoidke."</string>
<string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Funktsioonide vahel vahetamiseks pühkige kolme sõrmega üles ja hoidke."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Suurendus"</string>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index 9f927c3015d5..e4fe179e89a7 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -512,7 +512,7 @@
<string name="permdesc_changeWimaxState" product="default" msgid="1551666203780202101">"Telefonoa WiMAX sareetara konektatzeko edo haietatik deskonektatzeko baimena ematen die aplikazioei."</string>
<string name="permlab_bluetooth" msgid="586333280736937209">"partekatu Bluetooth bidezko gailuekin"</string>
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Tabletaren Bluetooth konfigurazioa ikusteko eta parekatutako gailuekin konexioak egiteko eta onartzeko baimena ematen die aplikazioei."</string>
- <string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Android TV gailuaren Bluetooth konexioaren konfigurazioa ikusteko eta parekatutako gailuekin konexioak sortzeko eta onartzeko baimena ematen die aplikazioei."</string>
+ <string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Android TV gailuaren Bluetooth bidezko konexioaren konfigurazioa ikusteko eta parekatutako gailuekin konexioak sortzeko eta onartzeko baimena ematen die aplikazioei."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Telefonoaren Bluetooth konfigurazioa ikusteko eta parekatutako gailuekin konexioak egiteko eta onartzeko baimena ematen die aplikazioei."</string>
<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>
@@ -1309,9 +1309,9 @@
<string name="adb_active_notification_title" msgid="408390247354560331">"USB bidezko arazketa konektatuta"</string>
<string name="adb_active_notification_message" msgid="5617264033476778211">"Sakatu USB bidezko arazketa desaktibatzeko"</string>
<string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"Hautatu USB bidezko arazketa desgaitzeko."</string>
- <string name="adbwifi_active_notification_title" msgid="6147343659168302473">"Konektatu da hari gabeko arazketa"</string>
+ <string name="adbwifi_active_notification_title" msgid="6147343659168302473">"Hari gabeko arazketa konektatuta dago"</string>
<string name="adbwifi_active_notification_message" msgid="930987922852867972">"Sakatu hau hari gabeko arazketa desaktibatzeko"</string>
- <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Hautatu hau hari gabeko arazketa desgaitzeko"</string>
+ <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Hautatu hau hari gabeko arazketa desgaitzeko."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Proba-materialeko modua gaitu da"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Proba-materialaren modua desgaitzeko, berrezarri jatorrizko datuak."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"Serie-kontsola gaituta"</string>
@@ -1619,15 +1619,14 @@
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"Desblokeatzeko eredua oker marraztu duzu <xliff:g id="NUMBER_0">%1$d</xliff:g> aldiz. Beste <xliff:g id="NUMBER_1">%2$d</xliff:g> aldiz oker marrazten baduzu, telefonoa posta-kontu baten bidez desblokeatzeko eskatuko dizugu.\n\n Saiatu berriro <xliff:g id="NUMBER_2">%3$d</xliff:g> segundo barru."</string>
<string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Kendu"</string>
- <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> webgunearen atzeko planoak hasitako aurreko planoko zerbitzuak ez du izango erabili bitarteko baimenik etorkizuneko R konpilazioetan. Joan go/r-bg-fgs-restriction atalera eta egin akatsaren txostena."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Bolumena gomendatutako mailatik gora igo nahi duzu?\n\nMusika bolumen handian eta denbora luzez entzuteak entzumena kalte diezazuke."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Erabilerraztasun-lasterbidea erabili nahi duzu?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Lasterbidea aktibatuta dagoenean, bi bolumen-botoiak hiru segundoz sakatuta abiaraziko da erabilerraztasun-eginbidea."</string>
<string name="accessibility_shortcut_multiple_service_warning_title" msgid="8417489297036013065">"Erabilerraztasun-eginbideak aktibatu nahi dituzu?"</string>
- <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"Eduki sakatuta bolumen-teklak segundo batzuez erabilerraztasun-eginbideak aktibatzeko. Honen bidez, baliteke zure mugikorraren funtzionamendua aldatzea.\n\nUneko eginbideak:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nAukeratutako eginbideak aldatzeko, joan Ezarpenak &gt; Erabilerraztasuna atalera."</string>
+ <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"Eduki sakatuta bolumen-botoiak segundo batzuez erabilerraztasun-eginbideak aktibatzeko. Hori eginez gero, baliteke zure mugikorraren funtzionamendua aldatzea.\n\nUneko eginbideak:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nHautatutako eginbideak aldatzeko, joan Ezarpenak &gt; Erabilerraztasuna atalera."</string>
<string name="accessibility_shortcut_multiple_service_list" msgid="6935581470716541531">" • <xliff:g id="SERVICE">%1$s</xliff:g>\n"</string>
<string name="accessibility_shortcut_single_service_warning_title" msgid="2819109500943271385">"<xliff:g id="SERVICE">%1$s</xliff:g> aktibatu nahi duzu?"</string>
- <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Eduki sakatuta bolumen-teklak segundo batzuez <xliff:g id="SERVICE">%1$s</xliff:g> izeneko erabilerraztasun-eginbidea aktibatzeko. Honen bidez, baliteke zure mugikorraren funtzionamendua aldatzea.\n\nLasterbide hau beste eginbide batengatik aldatzeko, joan Ezarpenak &gt; Erabilerraztasuna atalera."</string>
+ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Eduki sakatuta bolumen-botoiak segundo batzuez <xliff:g id="SERVICE">%1$s</xliff:g> izeneko erabilerraztasun-eginbidea aktibatzeko. Honen bidez, baliteke zure mugikorraren funtzionamendua aldatzea.\n\nLasterbide hau beste eginbide batengatik aldatzeko, joan Ezarpenak &gt; Erabilerraztasuna atalera."</string>
<string name="accessibility_shortcut_on" msgid="5463618449556111344">"Aktibatu"</string>
<string name="accessibility_shortcut_off" msgid="3651336255403648739">"Ez aktibatu"</string>
<string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"AKTIBATUTA"</string>
@@ -1643,7 +1642,7 @@
<string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Ukatu"</string>
<string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Eginbide bat erabiltzen hasteko, saka ezazu:"</string>
<string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Aukeratu zein eginbide erabili nahi duzun Erabilerraztasuna botoiarekin"</string>
- <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Aukeratu zein eginbide erabili nahi duzun bolumen-teklen lasterbidearekin"</string>
+ <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Aukeratu zein eginbide erabili nahi duzun bolumen-botoien lasterbidearekin"</string>
<string name="accessibility_uncheck_legacy_item_warning" msgid="8047830891064817447">"Desaktibatu da <xliff:g id="SERVICE_NAME">%s</xliff:g>"</string>
<string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Editatu lasterbideak"</string>
<string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Eginda"</string>
@@ -1651,9 +1650,9 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Erabili lasterbidea"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Koloreen alderantzikatzea"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Koloreen zuzenketa"</string>
- <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Eduki sakatuta bolumen-teklak. Aktibatu da <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
- <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Eduki sakatuta bolumen-teklak. Desaktibatu da <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
- <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> erabiltzeko, eduki sakatuta bolumen-tekla biak hiru segundoz"</string>
+ <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Bolumen-botoiak sakatuta eduki direnez, <xliff:g id="SERVICE_NAME">%1$s</xliff:g> aktibatu egin da."</string>
+ <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Bolumen-botoiak sakatuta eduki direnez, <xliff:g id="SERVICE_NAME">%1$s</xliff:g> desaktibatu egin da."</string>
+ <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> erabiltzeko, eduki sakatuta bi bolumen-botoiak hiru segundoz"</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Aukeratu zein eginbide erabili nahi duzun Erabilerraztasuna botoia sakatzean:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Aukeratu zein eginbide erabili nahi duzun erabilerraztasun-keinuarekin (hau da, bi hatz pantailaren behealdetik gora pasatzean):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Aukeratu zein eginbide erabili nahi duzun erabilerraztasun-keinuarekin (hau da, hiru hatz pantailaren behealdetik gora pasatzean):"</string>
@@ -2024,7 +2023,7 @@
<string name="mime_type_spreadsheet_ext" msgid="8720173181137254414">"<xliff:g id="EXTENSION">%1$s</xliff:g> kalkulu-orria"</string>
<string name="mime_type_presentation" msgid="1145384236788242075">"Aurkezpena"</string>
<string name="mime_type_presentation_ext" msgid="8761049335564371468">"<xliff:g id="EXTENSION">%1$s</xliff:g> aurkezpena"</string>
- <string name="bluetooth_airplane_mode_toast" msgid="2066399056595768554">"Bluetooth konexioak aktibatuta jarraituko du hegaldi moduan"</string>
+ <string name="bluetooth_airplane_mode_toast" msgid="2066399056595768554">"Bluetooth-ak aktibatuta jarraituko du hegaldi moduan"</string>
<string name="car_loading_profile" msgid="8219978381196748070">"Kargatzen"</string>
<plurals name="file_count" formatted="false" msgid="7063513834724389247">
<item quantity="other"><xliff:g id="FILE_NAME_2">%s</xliff:g> + <xliff:g id="COUNT_3">%d</xliff:g> fitxategi</item>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 2287160a70d2..2cd3dbda1d5f 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -1619,7 +1619,6 @@
<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="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"‏سرویس پیش‌نمای <xliff:g id="PACKAGENAME">%1$s</xliff:g>، که در پس‌زمینه شروع شده، در ساخت‌های آتی R اجازهٔ حین استفاده نخواهد داشت. لطفاً به go/r-bg-fgs-restriction بروید و گزارش اشکال ارسال کنید."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"میزان صدا را به بالاتر از حد توصیه شده افزایش می‌دهید؟\n\nگوش دادن به صداهای بلند برای مدت طولانی می‌تواند به شنوایی‌تان آسیب وارد کند."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"از میان‌بر دسترس‌پذیری استفاده شود؟"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"وقتی میان‌بر روشن باشد، با فشار دادن هردو دکمه صدا به‌مدت ۳ ثانیه ویژگی دسترس‌پذیری فعال می‌شود."</string>
@@ -1628,7 +1627,7 @@
<string name="accessibility_shortcut_multiple_service_list" msgid="6935581470716541531">" • <xliff:g id="SERVICE">%1$s</xliff:g>\n"</string>
<string name="accessibility_shortcut_single_service_warning_title" msgid="2819109500943271385">"<xliff:g id="SERVICE">%1$s</xliff:g> روشن شود؟"</string>
<string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"با پایین نگه داشتن هردو کلید میزان صدا به‌مدت چند ثانیه، <xliff:g id="SERVICE">%1$s</xliff:g> (یکی از ویژگی‌های دسترس‌پذیری) روشن می‌شود. با این کار نحوه عملکرد دستگاهتان تغییر می‌کند.\n\nمی‌توانید در «تنظیمات &gt; دسترس‌پذیری»،‌این میان‌بر را به ویژگی دیگری تغییر دهید."</string>
- <string name="accessibility_shortcut_on" msgid="5463618449556111344">"روشن کردن"</string>
+ <string name="accessibility_shortcut_on" msgid="5463618449556111344">"روشن شود"</string>
<string name="accessibility_shortcut_off" msgid="3651336255403648739">"روشن نشود"</string>
<string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"روشن"</string>
<string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"خاموش"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index f0ce863c5bb8..6aab2c3cc0b6 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -238,7 +238,7 @@
<string name="global_action_lock" msgid="6949357274257655383">"Näytön lukitus"</string>
<string name="global_action_power_off" msgid="4404936470711393203">"Katkaise virta"</string>
<string name="global_action_power_options" msgid="1185286119330160073">"Virta"</string>
- <string name="global_action_restart" msgid="4678451019561687074">"Uudelleenkäynnistys"</string>
+ <string name="global_action_restart" msgid="4678451019561687074">"Käynnistä uudelleen"</string>
<string name="global_action_emergency" msgid="1387617624177105088">"Hätäpuhelu"</string>
<string name="global_action_bug_report" msgid="5127867163044170003">"Virheraportti"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Lopeta käyttökerta"</string>
@@ -1619,7 +1619,6 @@
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"Piirsit lukituksenpoistokuvion väärin <xliff:g id="NUMBER_0">%1$d</xliff:g> kertaa. Jos piirrät kuvion väärin vielä <xliff:g id="NUMBER_1">%2$d</xliff:g> kertaa, sinua pyydetään poistamaan puhelimesi lukitus sähköpostitilin avulla.\n\n Yritä uudelleen <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunnin kuluttua."</string>
<string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" – "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Poista"</string>
- <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Taustalla aloitettu etualan palvelu (<xliff:g id="PACKAGENAME">%1$s</xliff:g>) ei ole käytön aikana sallittu R:n tulevissa versioissa. Lue go/r-bg-fgs-restriction ja lähetä virheraportti."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Nostetaanko äänenvoimakkuus suositellun tason yläpuolelle?\n\nPitkäkestoinen kova äänenvoimakkuus saattaa heikentää kuuloa."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Käytetäänkö esteettömyyden pikanäppäintä?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Kun pikanäppäin on käytössä, voit käynnistää esteettömyystoiminnon pitämällä molempia äänenvoimakkuuspainikkeita painettuna kolmen sekunnin ajan."</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 2eba43f5ae7a..70f403c56ed3 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -1619,7 +1619,6 @@
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, vous devrez déverrouiller votre téléphone à l\'aide d\'un compte de messagerie électronique.\n\n Veuillez réessayer dans <xliff:g id="NUMBER_2">%3$d</xliff:g> secondes."</string>
<string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Supprimer"</string>
- <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Le service de premier plan qui a démarré en arrière-plan provenant de <xliff:g id="PACKAGENAME">%1$s</xliff:g> ne disposera pas de l\'autorisation pendant l\'utilisation dans les futures versions R. Veuillez accéder à go/r-bg-fgs-restriction et envoyer un rapport de bogue."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Augmenter le volume au-dessus du niveau recommandé?\n\nL\'écoute prolongée à un volume élevé peut endommager vos facultés auditives."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Utiliser le raccourci d\'accessibilité?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Quand le raccourci est activé, appuyez sur les deux boutons de volume pendant trois secondes pour lancer une fonctionnalité d\'accessibilité."</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 151f13d5176b..0b3a6af36f8d 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -1619,7 +1619,6 @@
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, vous devrez déverrouiller votre téléphone à l\'aide d\'un compte de messagerie électronique.\n\n Veuillez réessayer dans <xliff:g id="NUMBER_2">%3$d</xliff:g> secondes."</string>
<string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Supprimer"</string>
- <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Le service de premier plan qui a démarré en arrière-plan et provenant de <xliff:g id="PACKAGENAME">%1$s</xliff:g> ne disposera pas de l\'autorisation \"pendant l\'utilisation\" dans les futurs builds R. Veuillez accéder à go/r-bg-fgs-restriction et envoyer un rapport de bug."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Augmenter le volume au dessus du niveau recommandé ?\n\nL\'écoute prolongée à un volume élevé peut endommager vos facultés auditives."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Utiliser le raccourci d\'accessibilité ?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Quand le raccourci est activé, appuyez sur les deux boutons de volume pendant trois secondes pour démarrer une fonctionnalité d\'accessibilité."</string>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 8272fed8cc97..77a1fec768d7 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -1619,7 +1619,6 @@
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"Debuxaches o padrón de desbloqueo incorrectamente <xliff:g id="NUMBER_0">%1$d</xliff:g> veces. Se realizas <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos incorrectos máis, terás que desbloquear o teléfono a través dunha conta de correo electrónico.\n\n Téntao de novo dentro de <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
<string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Eliminar"</string>
- <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Nas futuras compilacións R, o servizo en primeiro plano iniciado en segundo plano desde <xliff:g id="PACKAGENAME">%1$s</xliff:g> non terá permiso mentres estea en uso. Consulta go/r-bg-fgs-restriction e presenta un informe de erros."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Queres subir o volume máis do nivel recomendado?\n\nA reprodución de son a un volume elevado durante moito tempo pode provocar danos nos oídos."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Queres utilizar o atallo de accesibilidade?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Cando o atallo está activado, podes premer os dous botóns de volume durante 3 segundos para iniciar unha función de accesibilidade."</string>
@@ -1643,7 +1642,7 @@
<string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Denegar"</string>
<string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Tocar unha función para comezar a utilizala:"</string>
<string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Escoller as funcións que queres utilizar co botón Accesibilidade"</string>
- <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Escoller as funcións que queres utilizar co atallo da tecla de volume"</string>
+ <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Escolle as funcións que queres utilizar co atallo da tecla de volume"</string>
<string name="accessibility_uncheck_legacy_item_warning" msgid="8047830891064817447">"<xliff:g id="SERVICE_NAME">%s</xliff:g>: desactivouse"</string>
<string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Editar atallos"</string>
<string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Feito"</string>
@@ -1651,8 +1650,8 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Utilizar atallo"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Inversión de cor"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Corrección de cor"</string>
- <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Teclas de volume premidas. Servizo <xliff:g id="SERVICE_NAME">%1$s</xliff:g> activado."</string>
- <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Teclas de volume premidas. Servizo <xliff:g id="SERVICE_NAME">%1$s</xliff:g> desactivado."</string>
+ <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Teclas de volume premidas. Activouse o servizo <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
+ <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Teclas de volume premidas. Desactivouse <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Mantén premidas as teclas do volume durante tres segudos para usar <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Escolle a función que queres utilizar cando toques o botón Accesibilidade:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Escolle a función que queres usar co xesto de accesibilidade (pasa dous dedos cara arriba desde a parte inferior da pantalla):"</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index a2317e9e1cad..f445883a801b 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -1619,7 +1619,6 @@
<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="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"બૅકગ્રાઉન્ડમાં શરૂ થયેલી <xliff:g id="PACKAGENAME">%1$s</xliff:g>ની ફોરગ્રાઉન્ડ સેવા પાસે ભવિષ્યની R બિલ્ડમાં ઉપયોગમાં હોય તે સમયની પરવાનગી હશે નહીં. કૃપા કરીને go/r-bg-fgs-restriction જુઓ અને ભૂલનો અહેવાલ દાખલ કરો."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"ભલામણ કરેલ સ્તરની ઉપર વૉલ્યૂમ વધાર્યો?\n\nલાંબા સમય સુધી ઊંચા અવાજે સાંભળવું તમારી શ્રવણક્ષમતાને નુકસાન પહોંચાડી શકે છે."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"ઍક્સેસિબિલિટી શૉર્ટકટનો ઉપયોગ કરીએ?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"જ્યારે શૉર્ટકટ ચાલુ હોય, ત્યારે બન્ને વૉલ્યૂમ બટનને 3 સેકન્ડ સુધી દબાવી રાખવાથી ઍક્સેસિબિલિટી સુવિધા શરૂ થઈ જશે."</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 0890ae13e421..9b47f8090e89 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -184,7 +184,7 @@
<string name="ssl_ca_cert_noti_by_unknown" msgid="4961102218216815242">"किसी अज्ञात तृतीय पक्ष के द्वारा"</string>
<string name="ssl_ca_cert_noti_by_administrator" msgid="4564941950768783879">"आपकी वर्क प्रोफ़ाइल का व्यवस्थापक करता है"</string>
<string name="ssl_ca_cert_noti_managed" msgid="217337232273211674">"<xliff:g id="MANAGING_DOMAIN">%s</xliff:g> के द्वारा"</string>
- <string name="work_profile_deleted" msgid="5891181538182009328">"वर्क प्रोफ़ाइल हटाई गई"</string>
+ <string name="work_profile_deleted" msgid="5891181538182009328">"वर्क प्रोफ़ाइल मिटाई गई"</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>
@@ -1619,7 +1619,6 @@
<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="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"<xliff:g id="PACKAGENAME">%1$s</xliff:g>से बैकग्राउंड में शुरू की गई फ़ॉरग्राउंड सेवा के लिए, भविष्य के R बिल्ड में \'इस्तेमाल के समय अनुमति दें\' की सुविधा नहीं होगी. कृपया go/r-bg-fgs-restriction देखें और गड़बड़ी की शिकायत करें."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"वॉल्यूम को सुझाए गए स्तर से ऊपर बढ़ाएं?\n\nअत्यधिक वॉल्यूम पर ज़्यादा समय तक सुनने से आपकी सुनने की क्षमता को नुकसान हो सकता है."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"सुलभता शॉर्टकट का इस्तेमाल करना चाहते हैं?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"शॉर्टकट के चालू होने पर, दाेनाें वॉल्यूम बटन (आवाज़ कम या ज़्यादा करने वाले बटन) को तीन सेकंड तक दबाने से, सुलभता सुविधा शुरू हाे जाएगी."</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 17f40f15bbe3..5076aa94b1ea 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -239,7 +239,7 @@
<string name="global_actions" product="default" msgid="6410072189971495460">"Opcije telefona"</string>
<string name="global_action_lock" msgid="6949357274257655383">"Zaključavanje zaslona"</string>
<string name="global_action_power_off" msgid="4404936470711393203">"Isključi"</string>
- <string name="global_action_power_options" msgid="1185286119330160073">"Napajanje"</string>
+ <string name="global_action_power_options" msgid="1185286119330160073">"Uključi"</string>
<string name="global_action_restart" msgid="4678451019561687074">"Ponovo pokreni"</string>
<string name="global_action_emergency" msgid="1387617624177105088">"Hitne službe"</string>
<string name="global_action_bug_report" msgid="5127867163044170003">"Izvješće o bugovima"</string>
@@ -1641,7 +1641,6 @@
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"Netočno ste iscrtali obrazac za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Nakon još ovoliko neuspješnih pokušaja: <xliff:g id="NUMBER_1">%2$d</xliff:g> morat ćete otključati telefon pomoću računa e-pošte.\n\n Pokušajte ponovo za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
<string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" – "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Ukloni"</string>
- <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Usluga u prednjem planu s <xliff:g id="PACKAGENAME">%1$s</xliff:g> pokrenuta u pozadini neće imati dopuštenje tijekom upotrebe u budućim R kompilacijama. Pogledajte go/r-bg-fgs-restriction i pošaljite izvješće o programskoj pogrešci."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Želite li pojačati zvuk iznad preporučene razine?\n\nDugotrajno slušanje glasne glazbe može vam oštetiti sluh."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Želite li upotrebljavati prečac za pristupačnost?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Kad je taj prečac uključen, pritiskom na obje tipke za glasnoću na tri sekunde pokrenut će se značajka pristupačnosti."</string>
@@ -1667,7 +1666,7 @@
<string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Odabir značajki za upotrebu pomoću gumba za Pristupačnost"</string>
<string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Odabir značajki za upotrebu pomoću prečaca tipki za glasnoću"</string>
<string name="accessibility_uncheck_legacy_item_warning" msgid="8047830891064817447">"Usluga <xliff:g id="SERVICE_NAME">%s</xliff:g> je isključena"</string>
- <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Uredi prečace"</string>
+ <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Uredite prečace"</string>
<string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Gotovo"</string>
<string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Isključi prečac"</string>
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Upotrijebi prečac"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 302dc6925085..6b442137da18 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -1619,7 +1619,6 @@
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"<xliff:g id="NUMBER_0">%1$d</xliff:g> alkalommal helytelenül rajzolta le a feloldási mintát. További <xliff:g id="NUMBER_1">%2$d</xliff:g> sikertelen kísérlet után egy e-mail fiók használatával kell feloldania a telefonját.\n\n Kérjük, próbálja újra <xliff:g id="NUMBER_2">%3$d</xliff:g> másodperc múlva."</string>
<string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" – "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Eltávolítás"</string>
- <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"A háttér által indított előtérben futó szolgáltatás (innen: <xliff:g id="PACKAGENAME">%1$s</xliff:g>) nem tartalmaz majd használat közbeni engedélyt a jövőbeli R buildekben. Kérjük, keresse fel a go/r-bg-fgs-restriction webhelyet, és jelentse a hibát."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Az ajánlott szint fölé szeretné emelni a hangerőt?\n\nHa hosszú időn át teszi ki magát nagy hangerőnek, azzal károsíthatja a hallását."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Szeretné használni a Kisegítő lehetőségek billentyűparancsot?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Ha a gyorsparancs aktív, akkor a két hangerőgomb három másodpercig tartó együttes lenyomásával kisegítő funkciót indíthat el."</string>
@@ -1628,7 +1627,7 @@
<string name="accessibility_shortcut_multiple_service_list" msgid="6935581470716541531">" • <xliff:g id="SERVICE">%1$s</xliff:g>\n"</string>
<string name="accessibility_shortcut_single_service_warning_title" msgid="2819109500943271385">"Bekapcsolja a következőt: <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
<string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"A(z) <xliff:g id="SERVICE">%1$s</xliff:g> kisegítő lehetőség bekapcsolásához tartsa nyomva néhány másodpercig mindkét hangerőgombot. Ez hatással lehet az eszköz működésére.\n\nEzt a gyorsparancsot a Beállítások &gt; Kisegítő lehetőségek pontban módosíthatja másik funkció használatára."</string>
- <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Bekapcsolás"</string>
+ <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Bekapcsolom"</string>
<string name="accessibility_shortcut_off" msgid="3651336255403648739">"Nem kapcsolom be"</string>
<string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"BE"</string>
<string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"KI"</string>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index 1fb9a62025bb..6f676fd7af80 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -1619,7 +1619,6 @@
<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="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Ֆոնային ռեժիմում <xliff:g id="PACKAGENAME">%1$s</xliff:g>-ից գործարկված առաջին պլանի ծառայությունը հետագա R կառուցումներում թույլտվություն չի ունենա օգտագործման ընթացքում։ Անցեք go/r-bg-fgs-restriction էջ և հաղորդեք վրիպակի մասին։"</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Ձայնը բարձրացնե՞լ խորհուրդ տրվող մակարդակից ավել:\n\nԵրկարատև բարձրաձայն լսելը կարող է վնասել ձեր լսողությունը:"</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Օգտագործե՞լ Մատչելիության դյուրանցումը։"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Հատուկ գործառույթն օգտագործելու համար սեղմեք և 3 վայրկյան սեղմած պահեք ձայնի ուժգնության երկու կոճակները, երբ գործառույթը միացված է:"</string>
@@ -1841,7 +1840,7 @@
<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="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="system_error_wipe_data" msgid="5910572292172208493">"Սարքում ներքին խնդիր է առաջացել և այն կարող է կրկնվել, մինչև չվերականգնեք գործարանային կարգավորումները:"</string>
<string name="system_error_manufacturer" msgid="703545241070116315">"Սարքում ներքին խնդիր է առաջացել: Մանրամասների համար կապվեք արտադրողի հետ:"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 9fbd73ea1269..3aaf2f5f6404 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -339,7 +339,7 @@
<string name="permdesc_install_shortcut" msgid="4476328467240212503">"Mengizinkan aplikasi menambahkan pintasan Layar Utama tanpa tindakan dari pengguna."</string>
<string name="permlab_uninstall_shortcut" msgid="295263654781900390">"meng-uninstal pintasan"</string>
<string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Mengizinkan aplikasi menghapus pintasan Layar Utama tanpa tindakan dari pengguna."</string>
- <string name="permlab_processOutgoingCalls" msgid="4075056020714266558">"ubah rute panggilan keluar"</string>
+ <string name="permlab_processOutgoingCalls" msgid="4075056020714266558">"alihkan panggilan keluar"</string>
<string name="permdesc_processOutgoingCalls" msgid="7833149750590606334">"Memungkinkan aplikasi melihat nomor yang dihubungi saat melakukan panggilan keluar dengan opsi untuk mengalihkan panggilan ke nomor lain atau membatalkan panggilan sepenuhnya."</string>
<string name="permlab_answerPhoneCalls" msgid="4131324833663725855">"jawab panggilan telepon"</string>
<string name="permdesc_answerPhoneCalls" msgid="894386681983116838">"Mengizinkan aplikasi menjawab panggilan telepon masuk."</string>
@@ -1619,7 +1619,6 @@
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali salah menggambar pola pembuka kunci. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi upaya gagal, Anda akan diminta membuka kunci ponsel menggunakan akun email.\n\nCoba lagi dalam <xliff:g id="NUMBER_2">%3$d</xliff:g> detik."</string>
<string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Hapus"</string>
- <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Layanan latar depan yang dimulai oleh latar belakang dari <xliff:g id="PACKAGENAME">%1$s</xliff:g> tidak akan memiliki izin saat-sedang-digunakan pada build R masa mendatang Lihat go/r-bg-fgs-restriction dan kirim laporan bug."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Mengeraskan volume di atas tingkat yang disarankan?\n\nMendengarkan dengan volume keras dalam waktu yang lama dapat merusak pendengaran Anda."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Gunakan Pintasan Aksesibilitas?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Saat pintasan aktif, menekan kedua tombol volume selama 3 detik akan memulai fitur aksesibilitas."</string>
@@ -1651,8 +1650,8 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Gunakan Pintasan"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Inversi Warna"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Koreksi Warna"</string>
- <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Tombol volume yang ditahan. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> diaktifkan."</string>
- <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Tombol volume yang ditahan. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> dinonaktifkan."</string>
+ <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Tombol volume ditahan. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> diaktifkan."</string>
+ <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Tombol volume ditahan. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> dinonaktifkan."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Tekan dan tahan kedua tombol volume selama tiga detik untuk menggunakan <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Pilih fitur yang akan digunakan saat mengetuk tombol aksesibilitas:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Pilih fitur yang akan digunakan dengan gestur aksesibilitas (geser ke atas dari bawah layar dengan dua jari):"</string>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index 82d6206ab625..e5e23f6e0ac3 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -237,7 +237,7 @@
<string name="global_actions" product="default" msgid="6410072189971495460">"Valkostir síma"</string>
<string name="global_action_lock" msgid="6949357274257655383">"Skjálás"</string>
<string name="global_action_power_off" msgid="4404936470711393203">"Slökkva"</string>
- <string name="global_action_power_options" msgid="1185286119330160073">"Orka"</string>
+ <string name="global_action_power_options" msgid="1185286119330160073">"Slökkva/endurræsa"</string>
<string name="global_action_restart" msgid="4678451019561687074">"Endurræsa"</string>
<string name="global_action_emergency" msgid="1387617624177105088">"Neyðarsímtal"</string>
<string name="global_action_bug_report" msgid="5127867163044170003">"Villutilkynning"</string>
@@ -1619,7 +1619,6 @@
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"Þú hefur teiknað rangt opnunarmynstur <xliff:g id="NUMBER_0">%1$d</xliff:g> sinnum. Eftir <xliff:g id="NUMBER_1">%2$d</xliff:g> árangurslausar tilraunir í viðbót verður þú beðin(n) um að opna símann með tölvupóstreikningi.\n\n Reyndu aftur eftir <xliff:g id="NUMBER_2">%3$d</xliff:g> sekúndur."</string>
<string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Fjarlægja"</string>
- <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Forgrunnsþjónusta frá <xliff:g id="PACKAGENAME">%1$s</xliff:g> sem er ræst úr bakgrunni mun ekki hafa heimild við notkun í framtíðarútgáfum R. Farðu á go/r-bg-fgs-restriction og gefðu villuskýrslu."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Hækka hljóðstyrk umfram ráðlagðan styrk?\n\nEf hlustað er á háum hljóðstyrk í langan tíma kann það að skaða heyrnina."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Viltu nota aðgengisflýtileið?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Þegar flýtileiðin er virk er kveikt á aðgengiseiginleikanum með því að halda báðum hljóðstyrkshnöppunum inni í þrjár sekúndur."</string>
@@ -1643,7 +1642,7 @@
<string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Hafna"</string>
<string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Ýttu á eiginleika til að byrja að nota hann:"</string>
<string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Veldu eiginleika sem á að nota með aðgengishnappinum"</string>
- <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Veldu eiginleika á að nota með flýtileið hljóðstyrkstakka"</string>
+ <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Veldu eiginleika sem á að nota með flýtileið hljóðstyrkstakka"</string>
<string name="accessibility_uncheck_legacy_item_warning" msgid="8047830891064817447">"Slökkt hefur verið á <xliff:g id="SERVICE_NAME">%s</xliff:g>"</string>
<string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Breyta flýtileiðum"</string>
<string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Lokið"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index b6a850d10fef..5b6b5feeb09b 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -222,7 +222,7 @@
<string name="reboot_to_update_reboot" msgid="4474726009984452312">"Riavvio in corso…"</string>
<string name="reboot_to_reset_title" msgid="2226229680017882787">"Ripristino dati di fabbrica"</string>
<string name="reboot_to_reset_message" msgid="3347690497972074356">"Riavvio in corso…"</string>
- <string name="shutdown_progress" msgid="5017145516412657345">"Spegnimento..."</string>
+ <string name="shutdown_progress" msgid="5017145516412657345">"Spegnimento…"</string>
<string name="shutdown_confirm" product="tablet" msgid="2872769463279602432">"Il tablet verrà spento."</string>
<string name="shutdown_confirm" product="tv" msgid="7975942887313518330">"Il dispositivo Android TV verrà spento."</string>
<string name="shutdown_confirm" product="watch" msgid="2977299851200240146">"L\'orologio verrà spento."</string>
@@ -856,7 +856,7 @@
<string name="lockscreen_sim_puk_locked_message" msgid="6618356415831082174">"La SIM è bloccata tramite PUK."</string>
<string name="lockscreen_sim_puk_locked_instructions" msgid="5307979043730860995">"Consulta la Guida dell\'utente o contatta il servizio clienti."</string>
<string name="lockscreen_sim_locked_message" msgid="3160196135801185938">"La SIM è bloccata."</string>
- <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="2286497117428409709">"Sblocco SIM..."</string>
+ <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="2286497117428409709">"Sblocco SIM…"</string>
<string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6458790975898594240">"<xliff:g id="NUMBER_0">%1$d</xliff:g> tentativi errati di inserimento della sequenza di sblocco. \n\nRiprova tra <xliff:g id="NUMBER_1">%2$d</xliff:g> secondi."</string>
<string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="3118353451602377380">"Hai digitato la tua password <xliff:g id="NUMBER_0">%1$d</xliff:g> volte in modo errato. \n\nRiprova tra <xliff:g id="NUMBER_1">%2$d</xliff:g> secondi."</string>
<string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="2874278239714821984">"Hai digitato il tuo PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> volte in modo errato. \n\nRiprova tra <xliff:g id="NUMBER_1">%2$d</xliff:g> secondi."</string>
@@ -879,7 +879,7 @@
<string name="lockscreen_glogin_submit_button" msgid="3590556636347843733">"Accedi"</string>
<string name="lockscreen_glogin_invalid_input" msgid="4369219936865697679">"Password o nome utente non valido."</string>
<string name="lockscreen_glogin_account_recovery_hint" msgid="1683405808525090649">"Hai dimenticato il nome utente o la password?\nVisita "<b>"google.com/accounts/recovery"</b>"."</string>
- <string name="lockscreen_glogin_checking_password" msgid="2607271802803381645">"Verifica..."</string>
+ <string name="lockscreen_glogin_checking_password" msgid="2607271802803381645">"Verifica…"</string>
<string name="lockscreen_unlock_label" msgid="4648257878373307582">"Sblocca"</string>
<string name="lockscreen_sound_on_label" msgid="1660281470535492430">"Audio attivato"</string>
<string name="lockscreen_sound_off_label" msgid="2331496559245450053">"Audio disattivato"</string>
@@ -1095,7 +1095,7 @@
<string name="failed_to_copy_to_clipboard" msgid="725919885138539875">"Impossibile copiare negli appunti"</string>
<string name="paste" msgid="461843306215520225">"Incolla"</string>
<string name="paste_as_plain_text" msgid="7664800665823182587">"Incolla come testo normale"</string>
- <string name="replace" msgid="7842675434546657444">"Sostituisci..."</string>
+ <string name="replace" msgid="7842675434546657444">"Sostituisci…"</string>
<string name="delete" msgid="1514113991712129054">"Elimina"</string>
<string name="copyUrl" msgid="6229645005987260230">"Copia URL"</string>
<string name="selectTextMode" msgid="3225108910999318778">"Seleziona testo"</string>
@@ -1117,7 +1117,7 @@
<string name="yes" msgid="9069828999585032361">"OK"</string>
<string name="no" msgid="5122037903299899715">"Annulla"</string>
<string name="dialog_alert_title" msgid="651856561974090712">"Attenzione"</string>
- <string name="loading" msgid="3138021523725055037">"Caricamento..."</string>
+ <string name="loading" msgid="3138021523725055037">"Caricamento…"</string>
<string name="capital_on" msgid="2770685323900821829">"ON"</string>
<string name="capital_off" msgid="7443704171014626777">"OFF"</string>
<string name="checked" msgid="9179896827054513119">"selezionato"</string>
@@ -1544,7 +1544,7 @@
<string name="activity_chooser_view_see_all" msgid="3917045206812726099">"Mostra tutto"</string>
<string name="activity_chooser_view_dialog_title_default" msgid="8880731437191978314">"Scegli attività"</string>
<string name="share_action_provider_share_with" msgid="1904096863622941880">"Condividi con"</string>
- <string name="sending" msgid="206925243621664438">"Invio..."</string>
+ <string name="sending" msgid="206925243621664438">"Invio…"</string>
<string name="launchBrowserDefault" msgid="6328349989932924119">"Avviare l\'applicazione Browser?"</string>
<string name="SetupCallDefault" msgid="5581740063237175247">"Accettare la chiamata?"</string>
<string name="activity_resolver_use_always" msgid="5575222334666843269">"Sempre"</string>
@@ -1591,7 +1591,7 @@
<string name="kg_puk_enter_puk_hint" msgid="6696187482616360994">"La scheda SIM è disattivata. Inserisci il codice PUK per continuare. Contatta l\'operatore per avere informazioni dettagliate."</string>
<string name="kg_puk_enter_pin_hint" msgid="8190982314659429770">"Inserisci il codice PIN desiderato"</string>
<string name="kg_enter_confirm_pin_hint" msgid="6372557107414074580">"Conferma il codice PIN desiderato"</string>
- <string name="kg_sim_unlock_progress_dialog_message" msgid="8871937892678885545">"Sblocco scheda SIM..."</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8871937892678885545">"Sblocco scheda SIM…"</string>
<string name="kg_password_wrong_pin_code" msgid="9013856346870572451">"Codice PIN errato."</string>
<string name="kg_invalid_sim_pin_hint" msgid="4821601451222564077">"Il PIN deve essere di 4-8 numeri."</string>
<string name="kg_invalid_sim_puk_hint" msgid="2539364558870734339">"Il codice PUK deve essere di 8 cifre."</string>
@@ -1619,12 +1619,11 @@
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"<xliff:g id="NUMBER_0">%1$d</xliff:g> tentativi errati di inserimento della sequenza di sblocco. Dopo altri <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativi falliti, ti verrà chiesto di sbloccare il telefono con un account email.\n\n Riprova tra <xliff:g id="NUMBER_2">%3$d</xliff:g> secondi."</string>
<string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" – "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Rimuovi"</string>
- <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Il servizio in primo piano avviato in background da <xliff:g id="PACKAGENAME">%1$s</xliff:g> non avrà l\'autorizzazione \"durante l\'uso\" nelle future build R. Visita la pagina go/r-bg-fgs-restriction e invia una segnalazione di bug."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Vuoi aumentare il volume oltre il livello consigliato?\n\nL\'ascolto ad alto volume per lunghi periodi di tempo potrebbe danneggiare l\'udito."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Usare la scorciatoia Accessibilità?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Quando la scorciatoia è attiva, puoi premere entrambi i pulsanti del volume per tre secondi per avviare una funzione di accessibilità."</string>
<string name="accessibility_shortcut_multiple_service_warning_title" msgid="8417489297036013065">"Attivare le funzioni di accessibilità?"</string>
- <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"Se tieni premuti entrambi i tasti del volume per qualche secondo, le funzioni di accessibilità vengono attivate. Questa operazione potrebbe modificare il funzionamento del dispositivo.\n\nFunzionalità correnti:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nPuoi modificare le funzionalità selezionate in Impostazioni &gt; Accessibilità."</string>
+ <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"Se tieni premuti entrambi i tasti del volume per qualche secondo, vengono attivate le funzioni di accessibilità. Questa operazione potrebbe modificare il funzionamento del dispositivo.\n\nFunzioni correnti:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nPuoi modificare le funzioni selezionate in Impostazioni &gt; Accessibilità."</string>
<string name="accessibility_shortcut_multiple_service_list" msgid="6935581470716541531">" • <xliff:g id="SERVICE">%1$s</xliff:g>\n"</string>
<string name="accessibility_shortcut_single_service_warning_title" msgid="2819109500943271385">"Attivare <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
<string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Se tieni premuti entrambi i tasti del volume per qualche secondo verrà attivata la funzione di accessibilità <xliff:g id="SERVICE">%1$s</xliff:g>. Questa operazione potrebbe modificare il funzionamento del dispositivo.\n\nPuoi associare questa scorciatoia a un\'altra funzionalità in Impostazioni &gt; Accessibilità."</string>
@@ -1643,7 +1642,7 @@
<string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Rifiuta"</string>
<string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Tocca una funzionalità per iniziare a usarla:"</string>
<string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Scegli le funzionalità da usare con il pulsante Accessibilità"</string>
- <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Scegli le funzionalità da usare con la scorciatoia per i tasti del volume"</string>
+ <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Scegli le funzionalità da usare con la scorciatoia dei tasti del volume"</string>
<string name="accessibility_uncheck_legacy_item_warning" msgid="8047830891064817447">"Il servizio <xliff:g id="SERVICE_NAME">%s</xliff:g> è stato disattivato"</string>
<string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Modifica scorciatoie"</string>
<string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Fine"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 10d3f4383069..1b3fb1ba087a 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -1663,7 +1663,6 @@
<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="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"‏לשירות שפועל בחזית מ-<xliff:g id="PACKAGENAME">%1$s</xliff:g> שהחל ברקע לא תהיה הרשאת while-in-use בגרסאות R build בעתיד. יש לעיין בכתובת go/r-bg-fgs-restriction ולהגיש דוח על באג."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"האם להעלות את עוצמת הקול מעל לרמה המומלצת?\n\nהאזנה בעוצמת קול גבוהה למשכי זמן ממושכים עלולה לפגוע בשמיעה."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"להשתמש בקיצור הדרך לתכונת הנגישות?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"כשקיצור הדרך מופעל, לחיצה על שני לחצני עוצמת הקול למשך שלוש שניות מפעילה את תכונת הנגישות."</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 7f27e648b4d7..f5686c2ec12d 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -1311,7 +1311,7 @@
<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">"ワイヤレス デバッグをUSB デバッグを無効にするにはここをタップしてください"</string>
- <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"ワイヤレス デバッグを無効にする場合に選択します。"</string>
+ <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"ワイヤレス デバッグを無効にするには選択します。"</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"テストハーネス モード有効"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"出荷時設定にリセットしてテストハーネス モードを無効にしてください。"</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"シリアル コンソールは有効です"</string>
@@ -1619,7 +1619,6 @@
<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="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"今後の R ビルドでは、<xliff:g id="PACKAGENAME">%1$s</xliff:g> からバックグラウンドで開始されるフォアグラウンド サービスに「使用中のみ許可」の権限がありません。go/r-bg-fgs-restriction を確認し、バグレポートを提出してください。"</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"推奨レベルを超えるまで音量を上げますか?\n\n大音量で長時間聞き続けると、聴力を損なう恐れがあります。"</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"ユーザー補助機能のショートカットの使用"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"ショートカットが ON の場合、両方の音量ボタンを 3 秒ほど長押しするとユーザー補助機能が起動します。"</string>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index ed31a1cd3bed..3d447fc00bf0 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -1619,7 +1619,6 @@
<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="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"<xliff:g id="PACKAGENAME">%1$s</xliff:g>-ის ფონურად დაწყებულ წინა პლანის სერვისს მომავალ R build-ებში გამოყენების პროცესში წვდომის ნებართვა არ ექნება. გთხოვთ, იხილოთ go/r-bg-fgs-restriction და გამოგზავნოთ ხარვეზის ანგარიში."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"გსურთ ხმის რეკომენდებულ დონეზე მაღლა აწევა?\n\nხანგრძლივად ხმამაღლა მოსმენით შესაძლოა სმენადობა დაიზიანოთ."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"გსურთ მარტივი წვდომის მალსახმობის გამოყენება?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"თუ მალსახმობი ჩართულია, ხმის ორივე ღილაკზე 3 წამის განმავლობაში დაჭერით მარტივი წვდომის ფუნქცია ჩაირთვება."</string>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 07579ad0ae0f..28409e019a59 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -1311,7 +1311,7 @@
<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>
+ <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Сымсыз түзетуді өшіру үшін басыңыз."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Сынақ бағдарламасы режимі қосылды"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Сынақ бағдарламасы режимін өшіру үшін зауыттық күйіне қайтарыңыз."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"Сериялық консоль қосылды"</string>
@@ -1619,12 +1619,11 @@
<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="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Фондық режимде іске қосылған <xliff:g id="PACKAGENAME">%1$s</xliff:g> белсенді пакетінің алдағы R құрамаларында \"Пайдаланғанда ғана рұқсат ету\" рұқсаты болмайды. go/r-bg-fgs-restriction бетіне өтіп, қате туралы есеп жіберіңіз."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Дыбыс деңгейін ұсынылған деңгейден көтеру керек пе?\n\nЖоғары дыбыс деңгейінде ұзақ кезеңдер бойы тыңдау есту қабілетіңізге зиян тигізуі мүмкін."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Арнайы мүмкіндік төте жолын пайдалану керек пе?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Түймелер тіркесімі қосулы кезде, екі дыбыс түймесін 3 секунд басып тұрсаңыз, \"Арнайы мүмкіндіктер\" функциясы іске қосылады."</string>
<string name="accessibility_shortcut_multiple_service_warning_title" msgid="8417489297036013065">"Арнайы мүмкіндіктер іске қосылсын ба?"</string>
- <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"Дыбыс деңгейі пернелерін бірнеше секунд басып тұрсаңыз, арнайы мүмкіндіктер іске қосылады. Бұл – құрылғының жұмысына әсер етуі мүмкін.\n\nФункциялар:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nТаңдалған функцияларды \"Параметрлер &gt; Арнайы мүмкіндіктер\" бөлімінен өзгерте аласыз."</string>
+ <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"Дыбыс деңгейі пернелерін бірнеше секунд басып тұрсаңыз, арнайы мүмкіндіктер іске қосылады. Бұл – құрылғының жұмысына әсер етуі мүмкін.\n\nҚазіргі функциялар:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nТаңдалған функцияларды \"Параметрлер &gt; Арнайы мүмкіндіктер\" бөлімінен өзгерте аласыз."</string>
<string name="accessibility_shortcut_multiple_service_list" msgid="6935581470716541531">" • <xliff:g id="SERVICE">%1$s</xliff:g>\n"</string>
<string name="accessibility_shortcut_single_service_warning_title" msgid="2819109500943271385">"<xliff:g id="SERVICE">%1$s</xliff:g> қосылсын ба?"</string>
<string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Дыбыс деңгейі пернелерін бірнеше секунд басып тұрсаңыз, <xliff:g id="SERVICE">%1$s</xliff:g> арнайы қызметі іске қосылады. Бұл – құрылғының жүмысына әсер етуі мүмкін.\n\nБұл таңбашаны басқа функцияға \"Параметрлер &gt; Арнайы мүмкіндіктер\" бөлімінен өзгерте аласыз."</string>
@@ -1643,16 +1642,16 @@
<string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Қабылдамау"</string>
<string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Функцияны пайдалана бастау үшін түртіңіз:"</string>
<string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"\"Арнайы мүмкіндіктер\" түймесімен қолданылатын функцияларды таңдаңыз"</string>
- <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Дыбыс деңгейі пернелері таңбашасымен қолданылатын функцияларды таңдаңыз"</string>
+ <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="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Таңбашаларды өзгерту"</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="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>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Пайдаланушы дыбыс деңгейі пернелерін басып ұстап тұрды. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> қосулы."</string>
- <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Пайдаланушы дыбыс деңгейі пернелерін басып ұстап тұрды. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> өшірулі."</string>
+ <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Дыбыс деңгейі пернелерін басып тұрған соң, <xliff:g id="SERVICE_NAME">%1$s</xliff:g> өшірілді."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> қызметін пайдалану үшін дыбыс деңгейін реттейтін екі түймені де 3 секунд басып тұрыңыз"</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"\"Арнайы мүмкіндіктер\" түймесін түрткенде пайдаланатын функцияны таңдаңыз:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Арнайы мүмкіндіктер қимылымен (екі саусақпен экранның төменгі жағынан жоғары қарай сырғытыңыз) пайдаланатын функцияны таңдаңыз:"</string>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index 4fd0338b1f63..e056455f4773 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -1621,7 +1621,6 @@
<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="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"សេវាកម្ម​ផ្ទៃខាងមុខ​ដែលចាប់ផ្ដើមដោយ​ផ្ទៃខាងក្រោយ​ពី <xliff:g id="PACKAGENAME">%1$s</xliff:g> នឹង​មិនមាន​ការអនុញ្ញាត​ខណៈពេល​កំពុង​ប្រើប្រាស់​ទេ នៅក្នុង​កំណែបង្កើត R នៅពេល​អនាគត​។ សូម​មើល go/r-bg-fgs-restriction និង​ផ្ញើ​របាយការណ៍​អំពី​បញ្ហា​។"</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"បង្កើន​កម្រិត​សំឡេង​លើស​ពី​កម្រិត​បាន​ផ្ដល់​យោបល់?\n\nការ​ស្ដាប់​នៅ​កម្រិត​សំឡេង​ខ្លាំង​យូរ​អាច​ធ្វើឲ្យ​ខូច​ត្រចៀក។"</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"ប្រើប្រាស់​ផ្លូវកាត់​ភាព​ងាយស្រួល?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"នៅពេលបើក​ផ្លូវកាត់ ការចុច​ប៊ូតុង​កម្រិតសំឡេង​ទាំងពីរ​រយៈពេល 3 វិនាទី​នឹង​ចាប់ផ្តើម​មុខងារ​ភាពងាយប្រើ។"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index a1060808172a..72cf78f8275e 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -1619,12 +1619,11 @@
<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="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> ನಿಂದ ಹಿನ್ನೆಲೆಯಲ್ಲಿ ಪ್ರಾರಂಭಿಸಲಾದ ಮುನ್ನೆಲೆ ಸೇವೆ ಭವಿಷ್ಯದ R ಬಿಲ್ಡ್‌ಗಳಿಂದ ಬಳಕೆಯಲ್ಲಿರುವಾಗ ಅನುಮತಿಯನ್ನು ಪಡೆಯುವುದಿಲ್ಲ. go/r-bg-fgs-restriction ಅನ್ನು ನೋಡಿ ಮತ್ತು ದೋಷವರದಿಯನ್ನು ಫೈಲ್‌ ಮಾಡಿ."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"ವಾಲ್ಯೂಮ್‌ ಅನ್ನು ಶಿಫಾರಸು ಮಾಡಲಾದ ಮಟ್ಟಕ್ಕಿಂತಲೂ ಹೆಚ್ಚು ಮಾಡುವುದೇ?\n\nದೀರ್ಘ ಅವಧಿಯವರೆಗೆ ಹೆಚ್ಚಿನ ವಾಲ್ಯೂಮ್‌ನಲ್ಲಿ ಆಲಿಸುವುದರಿಂದ ನಿಮ್ಮ ಆಲಿಸುವಿಕೆ ಸಾಮರ್ಥ್ಯಕ್ಕೆ ಹಾನಿಯುಂಟು ಮಾಡಬಹುದು."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"ಪ್ರವೇಶಿಸುವಿಕೆ ಶಾರ್ಟ್‌ಕಟ್ ಬಳಸುವುದೇ?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"ಶಾರ್ಟ್‌ಕಟ್ ಆನ್ ಆಗಿರುವಾಗ, ಎರಡೂ ವಾಲ್ಯೂಮ್ ಬಟನ್‌ಗಳನ್ನು 3 ಸೆಕೆಂಡುಗಳ ಕಾಲ ಒತ್ತಿದರೆ ಪ್ರವೇಶಿಸುವಿಕೆ ವೈಶಿಷ್ಟ್ಯವೊಂದು ಪ್ರಾರಂಭವಾಗುತ್ತದೆ."</string>
- <string name="accessibility_shortcut_multiple_service_warning_title" msgid="8417489297036013065">"ಪ್ರವೇಶಿಸುವಿಕೆ ವೈಶಿಷ್ಟ್ಯಗಳನ್ನು ಆನ್ ಮಾಡುವುದೇ?"</string>
- <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"ಎರಡೂ ವಾಲ್ಯೂಮ್ ಕೀಗಳನ್ನು ಕೆಲವು ಸೆಕೆಂಡುಗಳ ಕಾಲ ಹಿಡಿದಿಟ್ಟುಕೊಳ್ಳುವುದರಿಂದ ಪ್ರವೇಶಿಸುವಿಕೆ ವೈಶಿಷ್ಟ್ಯಗಳು ಆನ್ ಆಗುತ್ತವೆ. ಇದು ನಿಮ್ಮ ಸಾಧನವು ಹೇಗೆ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ ಎಂಬುದನ್ನು ಬದಲಾಯಿಸಬಹುದು.\n\n ಪ್ರಸ್ತುತ ವೈಶಿಷ್ಟ್ಯಗಳು:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nಸೆಟ್ಟಿಂಗ್‌ಗಳು ಮತ್ತು ಅಕ್ಸೆಸಿಬಿಲಿಟಿಯಲ್ಲಿ ಆಯ್ದ ವೈಶಿಷ್ಟ್ಯಗಳನ್ನು ನೀವು ಬದಲಾಯಿಸಬಹುದು."</string>
+ <string name="accessibility_shortcut_multiple_service_warning_title" msgid="8417489297036013065">"ಪ್ರವೇಶಿಸುವಿಕೆ ವೈಶಿಷ್ಟ್ಯಗಳನ್ನು ಆನ್ ಮಾಡಬೇಕೇ?"</string>
+ <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"ಎರಡೂ ವಾಲ್ಯೂಮ್ ಕೀಗಳನ್ನು ಕೆಲವು ಸೆಕೆಂಡುಗಳ ಕಾಲ ಹಿಡಿದಿಟ್ಟುಕೊಳ್ಳುವುದರಿಂದ ಪ್ರವೇಶಿಸುವಿಕೆ ವೈಶಿಷ್ಟ್ಯಗಳು ಆನ್ ಆಗುತ್ತವೆ. ಇದು ನಿಮ್ಮ ಸಾಧನವು ಹೇಗೆ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ ಎಂಬುದನ್ನು ಬದಲಾಯಿಸಬಹುದು.\n\n ಪ್ರಸ್ತುತ ವೈಶಿಷ್ಟ್ಯಗಳು:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nಸೆಟ್ಟಿಂಗ್‌ಗಳು ಮತ್ತು ಆ್ಯಕ್ಸೆಸಿಬಿಲಿಟಿಯಲ್ಲಿ ಆಯ್ದ ವೈಶಿಷ್ಟ್ಯಗಳನ್ನು ನೀವು ಬದಲಾಯಿಸಬಹುದು."</string>
<string name="accessibility_shortcut_multiple_service_list" msgid="6935581470716541531">" • <xliff:g id="SERVICE">%1$s</xliff:g>\n"</string>
<string name="accessibility_shortcut_single_service_warning_title" msgid="2819109500943271385">"<xliff:g id="SERVICE">%1$s</xliff:g> ಅನ್ನು ಆನ್‌ ಮಾಡುವುದೇ?"</string>
<string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"ಎರಡೂ ವಾಲ್ಯೂಮ್ ಕೀಗಳನ್ನು ಕೆಲವು ಸೆಕೆಂಡುಗಳ ಕಾಲ ಹಿಡಿದಿಟ್ಟುಕೊಳ್ಳುವುದರಿಂದ ಪ್ರವೇಶಿಸುವಿಕೆ ವೈಶಿಷ್ಟ್ಯವಾದ <xliff:g id="SERVICE">%1$s</xliff:g> ಆನ್ ಆಗುತ್ತದೆ. ಇದು ನಿಮ್ಮ ಸಾಧನವು ಹೇಗೆ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ ಎಂಬುದನ್ನು ಬದಲಾಯಿಸಬಹುದು.\n\nನೀವು ಈ ಶಾರ್ಟ್‌ಕಟ್ ಅನ್ನು ಸೆಟ್ಟಿಂಗ್‌ಗಳು ಮತ್ತು ಅಕ್ಸೆಸಿಬಿಲಿಟಿಯಲ್ಲಿನ ಮತ್ತೊಂದು ವೈಶಿಷ್ಟ್ಯಕ್ಕೆ ಬದಲಾಯಿಸಬಹುದು."</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 0fe5925e3e25..63c3a379ad66 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -1619,16 +1619,15 @@
<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="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"향후 R 빌드에서는 백그라운드에서 시작된 <xliff:g id="PACKAGENAME">%1$s</xliff:g>의 포그라운드 서비스에 더 이상 사용 중인 상태에서 필요한 권한이 부여되지 않습니다. go/r-bg-fgs-restriction 페이지에서 버그 신고를 제출하세요."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"권장 수준 이상으로 볼륨을 높이시겠습니까?\n\n높은 볼륨으로 장시간 청취하면 청력에 손상이 올 수 있습니다."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"접근성 단축키를 사용하시겠습니까?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"단축키가 사용 설정된 경우 볼륨 버튼 두 개를 동시에 3초간 누르면 접근성 기능이 시작됩니다."</string>
<string name="accessibility_shortcut_multiple_service_warning_title" msgid="8417489297036013065">"접근성 기능을 사용하시겠습니까?"</string>
- <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"볼륨 키 2개를 몇 초 동안 길게 누르면 접근성 기능이 사용 설정됩니다. 이렇게 되면 기기 작동 방식이 달라질 수 있습니다.\n\n현재 기능:\n<xliff:g id="SERVICE">%1$s</xliff:g>\n설정 &gt; 접근성에서 선택한 기능을 변경할 수 있습니다."</string>
+ <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"볼륨 키 2개를 몇 초 동안 길게 누르면 접근성 기능이 사용 설정됩니다. 이때 기기 작동 방식이 달라질 수 있습니다.\n\n현재 기능:\n<xliff:g id="SERVICE">%1$s</xliff:g>\n설정 &gt; 접근성에서 선택한 기능을 변경할 수 있습니다."</string>
<string name="accessibility_shortcut_multiple_service_list" msgid="6935581470716541531">" • <xliff:g id="SERVICE">%1$s</xliff:g>\n"</string>
<string name="accessibility_shortcut_single_service_warning_title" msgid="2819109500943271385">"<xliff:g id="SERVICE">%1$s</xliff:g>을(를) 사용하시겠습니까?"</string>
<string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"볼륨 키 2개를 몇 초 동안 길게 누르면 <xliff:g id="SERVICE">%1$s</xliff:g> 접근성 기능이 사용 설정됩니다. 이렇게 되면 기기 작동 방식이 달라질 수 있습니다.\n\n설정 &gt; 접근성에서 이 단축키를 다른 기능으로 변경할 수 있습니다."</string>
- <string name="accessibility_shortcut_on" msgid="5463618449556111344">"사용 설정"</string>
+ <string name="accessibility_shortcut_on" msgid="5463618449556111344">"사용"</string>
<string name="accessibility_shortcut_off" msgid="3651336255403648739">"사용 안 함"</string>
<string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"사용"</string>
<string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"사용 안함"</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index dbbc14f706c0..7fcad66d0003 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -1309,7 +1309,7 @@
<string name="adb_active_notification_title" msgid="408390247354560331">"Мүчүлүштүктөр USB аркылуу оңдолууда"</string>
<string name="adb_active_notification_message" msgid="5617264033476778211">"Өчүрүү үчүн тийип коюңуз"</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_title" msgid="6147343659168302473">"Мүчүлүштүктөр Wi-Fi аркылуу оңдолууда"</string>
<string name="adbwifi_active_notification_message" msgid="930987922852867972">"Мүчүлүштүктөрдү зымсыз оңдоону өчүрүү үчүн таптап коюңуз"</string>
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Мүчүлүштүктөрдү Wi-Fi аркылуу оңдоону өчүрүңүз."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Сыноо программасынын режими иштетилди"</string>
@@ -1619,17 +1619,16 @@
<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> жолу туура эмес көрсөтүлгөндөн кийин, телефондун кулпусун ачуу үчүн Google аккаунтуңузга кирүүгө туура келет.\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="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Фондогу <xliff:g id="PACKAGENAME">%1$s</xliff:g> кызматы активдүү режимде иштеп баштап, кийинки R курамаларында колдонуу учурунда уруксаты болбойт. Төмөнкү бөлүмгө өтүп, мүчүлүштүк тууралуу кабарды тапшырыңыз: go/r-bg-fgs-restriction."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Сунушталган деңгээлден да катуулатып уккуңуз келеби?\n\nМузыканы узакка чейин катуу уксаңыз, угууңуз начарлап кетиши мүмкүн."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Ыкчам иштетесизби?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Атайын мүмкүнчүлүктөр функциясын пайдалануу үчүн ал күйгүзүлгөндө, үндү катуулатып/акырындаткан эки баскычты тең 3 секунддай коё бербей басып туруңуз."</string>
- <string name="accessibility_shortcut_multiple_service_warning_title" msgid="8417489297036013065">"Атайын мүмкүнчүлүктөр күйгүзүлсүнбү?"</string>
- <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"Үндү чоңойтуп/кичирейтүү баскычтарын бир нече секунд коё бербей басып турса, атайын мүмкүнчүлүктөр күйгүзүлөт. Бул түзмөгүңүздүн ишин өзгөртүшү мүмкүн.\n\nУчурдагы функциялар:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nТандалган функцияларды Жөндөөлөр &gt; Атайын мүмкүнчүлүктөр бөлүмүнөн өзгөртө аласыз."</string>
+ <string name="accessibility_shortcut_multiple_service_warning_title" msgid="8417489297036013065">"Атайын мүмкүнчүлүктөрдү иштетесизби?"</string>
+ <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"Атайын мүмкүнчүлүктөр функциясын иштетүү үчүн, үндү чоңойтуп/кичирейтүү баскычтарын бир нече секунд коё бербей басып туруңуз. Ушуну менен, түзмөгүңүз бир аз башкача иштеп калышы мүмкүн.\n\nУчурдагы функциялар:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nТандалган функцияларды өзгөртүү үчүн, Жөндөөлөр &gt; Атайын мүмкүнчүлүктөр бөлүмүнө өтүңүз."</string>
<string name="accessibility_shortcut_multiple_service_list" msgid="6935581470716541531">" • <xliff:g id="SERVICE">%1$s</xliff:g>\n"</string>
<string name="accessibility_shortcut_single_service_warning_title" msgid="2819109500943271385">"<xliff:g id="SERVICE">%1$s</xliff:g> күйгүзүлсүнбү?"</string>
- <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Үндү чоңойтуп/кичирейтүү баскычтарын бир нече секунд коё бербей басып турса, <xliff:g id="SERVICE">%1$s</xliff:g>, атайын мүмкүнчүлүктөр күйгүзүлөт. Бул түзмөгүңүздүн ишин өзгөртүшү мүмкүн.\n\nБул ыкчам баскычты Жөндөөлөр &gt; Атайын мүмкүнчүлүктөр бөлүмүнөн башка функцияга өзгөртө аласыз."</string>
- <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Күйгүзүлсүн"</string>
- <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Күйгүзүлбөсүн"</string>
+ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"<xliff:g id="SERVICE">%1$s</xliff:g> кызматын иштетүү үчүн, үндү чоңойтуп/кичирейтүү баскычтарын бир нече секунд коё бербей басып туруңуз. Ушуну менен, түзмөгүңүз бир аз башкача иштеп калышы мүмкүн.\n\nБаскычтардын ушул айкалышын башка функцияга дайындоо үчүн, Жөндөөлөр &gt; Атайын мүмкүнчүлүктөр бөлүмүнө өтүңүз."</string>
+ <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Ооба"</string>
+ <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Жок"</string>
<string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"КҮЙҮК"</string>
<string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"ӨЧҮК"</string>
<string name="accessibility_enable_service_title" msgid="3931558336268541484">"<xliff:g id="SERVICE">%1$s</xliff:g> кызматына түзмөгүңүздү толугу менен көзөмөлдөөгө уруксат бересизби?"</string>
@@ -1643,7 +1642,7 @@
<string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Жок"</string>
<string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Функцияны колдонуп баштоо үчүн аны таптап коюңуз:"</string>
<string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Атайын мүмкүнчүлүктөр баскычы менен колдонгуңуз келген функцияларды тандаңыз"</string>
- <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Үн деңгээлинин баскычтары менен колдонгуңуз келген функцияларды тандаңыз"</string>
+ <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="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Кыска жолдорду түзөтүү"</string>
<string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Бүттү"</string>
@@ -1651,8 +1650,8 @@
<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>
- <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Үндү катуулатуу/акырындатуу баскычтарын басып туруңуз. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> күйгүзүлдү."</string>
- <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Үндү катуулатуу/акырындатуу баскычтарын басып туруңуз. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> өчүрүлдү."</string>
+ <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Үндү катуулатуу/акырындатуу баскычтары басылып, <xliff:g id="SERVICE_NAME">%1$s</xliff:g> күйгүзүлдү."</string>
+ <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Үндү катуулатуу/акырындатуу баскычтары басылып, <xliff:g id="SERVICE_NAME">%1$s</xliff:g> өчүрүлдү."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> кызматын колдонуу үчүн үнүн чоңойтуп/кичирейтүү баскычтарын үч секунд коё бербей басып туруңуз"</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Атайын мүмкүнчүлүктөр баскычын таптаганыңызда иштей турган функцияны тандаңыз:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Атайын мүмкүнчүлүктөр жаңсоосу үчүн функцияны тандаңыз (эки манжаңыз менен экрандын ылдый жагынан өйдө карай сүрүңүз):"</string>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index 278237954a53..66ec0e691eed 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -1311,7 +1311,7 @@
<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>
+ <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"ເລືອກເພື່ອປິດການນຳໃຊ້ການດີບັກໄຮ້ສາຍ."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"ເປີດໃຊ້ໂໝດ Test Harness ແລ້ວ"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"ດຳເນີນການຣີເຊັດເປັນຄ່າຈາກໂຮງງານເພື່ອປິດການນຳໃຊ້ໂໝດ Test Harness."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"ເປີດນຳໃຊ້ຊີຣຽວຄອນໂຊແລ້ວ"</string>
@@ -1619,7 +1619,6 @@
<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="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"ບໍລິການພື້ນໜ້າທີ່ເລີ່ມຕົ້ນຈາກພື້ນຫຼັງຈາກ <xliff:g id="PACKAGENAME">%1$s</xliff:g> ຈະບໍ່ມີສິດອະນຸຍາດໃນຂະນະທີ່ໃຊ້ໃນ R builds ໃນອະນາຄົດ. ກະລຸນາອ່ານ go/r-bg-fgs-restriction ແລະ ລາຍງານຂໍ້ຜິດພາດ."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"ເພີ່ມ​ລະ​ດັບ​ສຽງ​ໃຫ້​ເກີນກວ່າ​ລະ​ດັບ​ທີ່​ແນະ​ນຳ​ບໍ?\n\n​ການ​ຮັບ​ຟັງ​ສຽງ​ໃນ​ລະ​ດັບ​ທີ່​ສູງ​ເປັນ​ໄລ​ຍະ​ເວ​ລາ​ດົນ​​ອາດ​ເຮັດ​ໃຫ້​ການ​ຟັງ​ຂອງ​ທ່ານ​ມີ​ບັນ​ຫາ​ໄດ້."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"ໃຊ້ປຸ່ມລັດການຊ່ວຍເຂົ້າເຖິງບໍ?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"ເມື່ອເປີດໃຊ້ທາງລັດແລ້ວ, ການກົດປຸ່ມລະດັບສຽງທັງສອງຄ້າງໄວ້ 3 ວິນາທີຈະເປັນການເລີ່ມຄຸນສົມບັດການຊ່ວຍເຂົ້າເຖິງ."</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index a0137c165a4b..4f71c361f98a 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -1663,7 +1663,6 @@
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"Netinkamai nupiešėte atrakinimo piešinį <xliff:g id="NUMBER_0">%1$d</xliff:g> k. Po dar <xliff:g id="NUMBER_1">%2$d</xliff:g> nesėkm. band. būsite paprašyti atrakinti telefoną naudodami „Google“ prisijungimo duomenis.\n\n Bandykite dar kartą po <xliff:g id="NUMBER_2">%3$d</xliff:g> sek."</string>
<string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" – "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Pašalinti"</string>
- <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Fone pradėtai priekinio plano paslaugai iš „<xliff:g id="PACKAGENAME">%1$s</xliff:g>“ nebus suteiktas leidimas naudojimo metu būsimose R versijose. Apsilankykite go/r-bg-fgs-restriction ir pateikite pranešimą apie riktą."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Padidinti garsą daugiau nei rekomenduojamas lygis?\n\nIlgai klausydami dideliu garsu galite pažeisti klausą."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Naudoti spartųjį pritaikymo neįgaliesiems klavišą?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Kai spartusis klavišas įjungtas, paspaudus abu garsumo mygtukus ir palaikius 3 sekundes bus įjungta pritaikymo neįgaliesiems funkcija."</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 09942a99be37..f4938cc0a964 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -1641,7 +1641,6 @@
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"Jūs nepareizi norādījāt atbloķēšanas kombināciju <xliff:g id="NUMBER_0">%1$d</xliff:g> reizes. Pēc vēl <xliff:g id="NUMBER_1">%2$d</xliff:g> neveiksmīgiem mēģinājumiem tālrunis būs jāatbloķē, izmantojot e-pasta kontu.\n\nMēģiniet vēlreiz pēc <xliff:g id="NUMBER_2">%3$d</xliff:g> sekundēm."</string>
<string name="kg_text_message_separator" product="default" msgid="4503708889934976866">"  — "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Noņemt"</string>
- <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Fonā sāktam priekšplāna pakalpojumam no pakotnes <xliff:g id="PACKAGENAME">%1$s</xliff:g> nebūs atļaujas “while-in-use” turpmākajās R versijās. Lūdzu, skatiet vietni go/r-bg-fgs-restriction un iesniedziet kļūdas pārskatu."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Vai palielināt skaļumu virs ieteicamā līmeņa?\n\nIlgstoši klausoties skaņu lielā skaļumā, var tikt bojāta dzirde."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Vai izmantot pieejamības saīsni?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Kad īsinājumtaustiņš ir ieslēgts, nospiežot abas skaļuma pogas un 3 sekundes turot tās, tiks aktivizēta pieejamības funkcija."</string>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index bfad9e964b93..f382ee90378a 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -243,7 +243,7 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"Извештај за грешка"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Завршете ја сесијата"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Слика од екранот"</string>
- <string name="bugreport_title" msgid="8549990811777373050">"Извештај за грешка"</string>
+ <string name="bugreport_title" msgid="8549990811777373050">"Извештај за грешки"</string>
<string name="bugreport_message" msgid="5212529146119624326">"Ова ќе собира информации за моменталната состојба на вашиот уред, за да ги испрати како порака по е-пошта. Тоа ќе одземе малку време почнувајќи од извештајот за грешки додека не се подготви за праќање; бидете трпеливи."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Интерактивен извештај"</string>
<string name="bugreport_option_interactive_summary" msgid="8493795476325339542">"Користете го ова во повеќето ситуации. Ви дозволува да го следите напредокот на извештајот, да внесете повеќе детали во врска со проблемот и да сликате слики од екранот. Може да испушти некои помалку користени делови за коишто е потребно долго време за да се пријават."</string>
@@ -1309,7 +1309,7 @@
<string name="adb_active_notification_title" msgid="408390247354560331">"Поврзано е отстранување грешки преку USB"</string>
<string name="adb_active_notification_message" msgid="5617264033476778211">"Допрете за да го исклучите"</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_title" msgid="6147343659168302473">"Поврзано е безжично отстранување грешки"</string>
<string name="adbwifi_active_notification_message" msgid="930987922852867972">"Допрете за да се исклучи безжичното отстранување грешки"</string>
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Изберете за да се оневозможи безжично отстранување грешки."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Овозможен е режимот на рамка за тестирање"</string>
@@ -1586,7 +1586,7 @@
</plurals>
<string name="kg_pattern_instructions" msgid="8366024510502517748">"Употреби ја својата шема"</string>
<string name="kg_sim_pin_instructions" msgid="6479401489471690359">"Внеси PIN на SIM картичка"</string>
- <string name="kg_pin_instructions" msgid="7355933174673539021">"Внеси PIN"</string>
+ <string name="kg_pin_instructions" msgid="7355933174673539021">"Впишете PIN"</string>
<string name="kg_password_instructions" msgid="7179782578809398050">"Внеси лозинка"</string>
<string name="kg_puk_enter_puk_hint" msgid="6696187482616360994">"SIM картичката е сега оневозможена. Внесете ПУК код за да продолжите. Контактирајте го операторот за детали."</string>
<string name="kg_puk_enter_pin_hint" msgid="8190982314659429770">"Внеси посакуван PIN код"</string>
@@ -1619,7 +1619,6 @@
<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="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Услугата од преден план започната во заднина од <xliff:g id="PACKAGENAME">%1$s</xliff:g> нема да има дозола за „додека се користи“ во идните R-верзии. Погледнете на go/r-bg-fgs-restriction и испратете извештај за грешка."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Да го зголемиме звукот над препорачаното ниво?\n\nСлушањето звуци со голема јачина подолги периоди може да ви го оштети сетилото за слух."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Да се користи кратенка за „Пристапност“?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Кога е вклучена кратенката, ако ги притиснете двете копчиња за јачина на звук во времетраење од 3 секунди, ќе се стартува функција за пристапност."</string>
@@ -1759,7 +1758,7 @@
<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">"Внесете PIN на админстратор"</string>
- <string name="restr_pin_enter_pin" msgid="373139384161304555">"Внеси PIN"</string>
+ <string name="restr_pin_enter_pin" msgid="373139384161304555">"Впишете PIN"</string>
<string name="restr_pin_incorrect" msgid="3861383632940852496">"Неточно"</string>
<string name="restr_pin_enter_old_pin" msgid="7537079094090650967">"Тековен PIN"</string>
<string name="restr_pin_enter_new_pin" msgid="3267614461844565431">"Нов PIN"</string>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index ac32b3cb378d..65b80d50d77f 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -175,7 +175,7 @@
<string name="contentServiceTooManyDeletesNotificationDesc" msgid="4562226280528716090">"ഒരുപാട് <xliff:g id="CONTENT_TYPE">%s</xliff:g> ഇല്ലാതാക്കാൻ ശ്രമിച്ചു."</string>
<string name="low_memory" product="tablet" msgid="5557552311566179924">"ടാബ്‌ലെറ്റ് സ്റ്റോറേജ് കഴിഞ്ഞു. ഇടം ശൂന്യമാക്കാൻ ചില ഫയലുകൾ ഇല്ലാതാക്കുക."</string>
<string name="low_memory" product="watch" msgid="3479447988234030194">"വാച്ചിലെ സ്റ്റോറേജ് നിറഞ്ഞു. ഇടം ശൂന്യമാക്കാൻ കുറച്ച് ഫയലുകൾ ഇല്ലാതാക്കുക."</string>
- <string name="low_memory" product="tv" msgid="6663680413790323318">"Android ടിവി ഉപകരണ സ്‌റ്റോറേജ് നിറഞ്ഞിരിക്കുന്നു. ഇടമുണ്ടാക്കാൻ കുറച്ച് ഫയലുകൾ ഇല്ലാതാക്കുക."</string>
+ <string name="low_memory" product="tv" msgid="6663680413790323318">"Android TV ഉപകരണ സ്‌റ്റോറേജ് നിറഞ്ഞിരിക്കുന്നു. ഇടമുണ്ടാക്കാൻ കുറച്ച് ഫയലുകൾ ഇല്ലാതാക്കുക."</string>
<string name="low_memory" product="default" msgid="2539532364144025569">"ഫോൺ സ്റ്റോറേജ് കഴിഞ്ഞു. ഇടം ശൂന്യമാക്കാൻ ചില ഫയലുകൾ ഇല്ലാതാക്കുക."</string>
<plurals name="ssl_ca_cert_warning" formatted="false" msgid="2288194355006173029">
<item quantity="other">സർട്ടിഫിക്കറ്റ് അതോറിറ്റികൾ ഇൻസ്റ്റാൾ ചെയ്തു</item>
@@ -206,7 +206,7 @@
<string name="personal_apps_suspended_turn_profile_on" msgid="2758012869627513689">"ഓണാക്കുക"</string>
<string name="me" msgid="6207584824693813140">"ഞാന്‍"</string>
<string name="power_dialog" product="tablet" msgid="8333207765671417261">"ടാബ്‌ലെറ്റ് ഓപ്‌ഷനുകൾ"</string>
- <string name="power_dialog" product="tv" msgid="7792839006640933763">"Android ടിവി ഓപ്‌ഷനുകൾ"</string>
+ <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>
@@ -224,7 +224,7 @@
<string name="reboot_to_reset_message" msgid="3347690497972074356">"പുനരാരംഭിക്കുന്നു…"</string>
<string name="shutdown_progress" msgid="5017145516412657345">"ഷട്ട്‌ഡൗൺ ചെയ്യുന്നു..."</string>
<string name="shutdown_confirm" product="tablet" msgid="2872769463279602432">"നിങ്ങളുടെ ടാബ്‌ലെറ്റ് ഷട്ട്‌ഡൗൺ ചെയ്യും."</string>
- <string name="shutdown_confirm" product="tv" msgid="7975942887313518330">"നിങ്ങളുടെ Android ടിവി ഓഫാകും."</string>
+ <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>
@@ -233,7 +233,7 @@
<string name="recent_tasks_title" msgid="8183172372995396653">"അടുത്തിടെയുള്ളത്"</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 ടിവി ഓപ്‌ഷനുകൾ"</string>
+ <string name="global_actions" product="tv" msgid="3871763739487450369">"Android TV ഓപ്‌ഷനുകൾ"</string>
<string name="global_actions" product="default" msgid="6410072189971495460">"ഫോൺ ഓപ്‌ഷനുകൾ"</string>
<string name="global_action_lock" msgid="6949357274257655383">"സ്‌ക്രീൻ ലോക്ക്"</string>
<string name="global_action_power_off" msgid="4404936470711393203">"പവർ ഓഫാക്കുക"</string>
@@ -293,7 +293,7 @@
<string name="android_system_label" msgid="5974767339591067210">"Android സിസ്റ്റം"</string>
<string name="user_owner_label" msgid="8628726904184471211">"വ്യക്തിഗത പ്രൊഫൈലിലേക്ക് മാറുക"</string>
<string name="managed_profile_label" msgid="7316778766973512382">"ഔദ്യോഗിക പ്രൊഫൈലിലേക്ക് മാറുക"</string>
- <string name="permgrouplab_contacts" msgid="4254143639307316920">"കോൺടാക്റ്റ്"</string>
+ <string name="permgrouplab_contacts" msgid="4254143639307316920">"കോൺടാക്റ്റുകൾ"</string>
<string name="permgroupdesc_contacts" msgid="9163927941244182567">"നിങ്ങളുടെ കോൺടാക്റ്റുകൾ ആക്‌സസ്സ് ചെയ്യുക"</string>
<string name="permgrouplab_location" msgid="1858277002233964394">"ലൊക്കേഷൻ"</string>
<string name="permgroupdesc_location" msgid="1995955142118450685">"ഈ ഉപകരണത്തിന്റെ ലൊക്കേഷൻ ആക്സസ് ചെയ്യാൻ"</string>
@@ -357,7 +357,7 @@
<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="tv" msgid="3054753345758011986">"നിങ്ങളുടെ Android ടിവിയിൽ സംഭരിച്ചിരിക്കുന്ന എല്ലാ SMS (ടെക്‌സ്‌റ്റ്) സന്ദേശങ്ങളും വായിക്കാൻ ഈ ആപ്പിന് കഴിയും."</string>
+ <string name="permdesc_readSms" product="tv" msgid="3054753345758011986">"നിങ്ങളുടെ Android TV-യിൽ സംഭരിച്ചിരിക്കുന്ന എല്ലാ 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>
@@ -379,7 +379,7 @@
<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 ടിവിയുടെ വേഗത കുറയ്‌ക്കുകയും ചെയ്യും."</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>
@@ -389,35 +389,35 @@
<string name="permdesc_writeSettings" msgid="8293047411196067188">"സിസ്‌‌റ്റത്തിന്റെ സുരക്ഷ ക്രമീകരണങ്ങളുടെ ഡാറ്റ പരിഷ്‌ക്കരിക്കുന്നതിന് അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. ദോഷകരമായ അപ്ലിക്കേഷനുകൾ നിങ്ങളുടെ സി‌സ്റ്റത്തിന്റെ കോൺഫിഗറേഷനെ കേടാക്കിയേക്കാം."</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 ടിവി ആരംഭിക്കുന്നതിന്റെ വേഗത കുറയ്‌ക്കാനും എപ്പോഴും പ്രവർത്തിക്കാൻ ആപ്പിനെ അനുവദിച്ചുകൊണ്ട് മൊത്തത്തിൽ ഉപകരണത്തിന്റെ വേഗത കുറയ്‌ക്കാനും കഴിയും."</string>
+ <string name="permdesc_receiveBootCompleted" product="tv" msgid="4900842256047614307">"സിസ്‌റ്റം ബൂട്ട് ചെയ്യൽ പൂർത്തിയായിക്കഴിഞ്ഞ് ഉടൻ സ്വയം ആരംഭിക്കാൻ ആപ്പിനെ അനുവദിക്കുന്നു. ഇതിന് നിങ്ങളുടെ Android TV ആരംഭിക്കുന്നതിന്റെ വേഗത കുറയ്‌ക്കാനും എപ്പോഴും പ്രവർത്തിക്കാൻ ആപ്പിനെ അനുവദിച്ചുകൊണ്ട് മൊത്തത്തിൽ ഉപകരണത്തിന്റെ വേഗത കുറയ്‌ക്കാനും കഴിയും."</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">"പ്രക്ഷേപണം അവസാനിച്ച ശേഷവും അവശേഷിക്കുന്ന സ്‌റ്റിക്കി പ്രക്ഷേപണങ്ങൾ അയയ്‌ക്കാൻ ആപ്പിനെ അനുവദിക്കുന്നു. Android ടിവിയുടെ അമിതമായ ഉപയോഗം ഒരുപാട് മെമ്മറി ഉപയോഗിക്കാൻ കാരണമാകുകയും ടിവിയുടെ വേഗത കുറയ്‌ക്കുകയോ അതിനെ അസ്ഥിരമാക്കുകയോ ചെയ്‌തേക്കാം."</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 ടിവിയിൽ സംഭരിച്ച കോൺടാക്റ്റുകളെക്കുറിച്ചുള്ള ഡാറ്റ വായിക്കാൻ ആപ്പിനെ അനുവദിക്കുന്നു. നിങ്ങളുടെ Android ടിവിയിൽ കോണ്ടാക്റ്റുകൾ സൃഷ്ടിച്ച അക്കൗണ്ടുകളിലേക്കുള്ള ആക്സസും ആപ്പുകൾക്ക് ഉണ്ടായിരിക്കും. നിങ്ങൾ ഇൻസ്റ്റാൾ ചെയ്‍ത ആപ്പുകൾ സൃഷ്ടിച്ച അക്കൗണ്ടുകളും ഇതിൽ ഉൾപ്പെട്ടേക്കാം. നിങ്ങളുടെ കോണ്ടാക്റ്റ് ഡാറ്റ സംരക്ഷിക്കാൻ ആപ്പുകളെ ഈ അനുമതി അനുവദിക്കുന്നു, നിങ്ങളുടെ അറിവില്ലാതെ, ദോഷകരമായ ആപ്പുകൾ കോണ്ടാക്റ്റ് ഡാറ്റ പങ്കിടുകയും ചെയ്‌തേക്കാം."</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="tv" msgid="6488872735379978935">"നിങ്ങളുടെ Android ടിവിയിൽ സംഭരിച്ച കോൺടാക്റ്റുകളെക്കുറിച്ചുള്ള ഡാറ്റ പരിഷ്‌ക്കരിക്കാൻ ആപ്പിനെ അനുവദിക്കുന്നു. കോൺടാക്റ്റ് ഡാറ്റ ഇല്ലാതാക്കാൻ അപ്പുകളെ ഈ അനുമതി അനുവദിക്കുന്നു."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"നിങ്ങളുടെ Android TV-യിൽ സംഭരിച്ച കോൺടാക്റ്റുകളെക്കുറിച്ചുള്ള ഡാറ്റ പരിഷ്‌ക്കരിക്കാൻ ആപ്പിനെ അനുവദിക്കുന്നു. കോൺടാക്റ്റ് ഡാറ്റ ഇല്ലാതാക്കാൻ അപ്പുകളെ ഈ അനുമതി അനുവദിക്കുന്നു."</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="permlab_writeCallLog" msgid="670292975137658895">"കോൾ ചരിത്രം റൈറ്റ് ചെയ്യുക"</string>
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"ഇൻകമ്മിംഗ്-ഔട്ട്ഗോയിംഗ് കോളുകളെക്കുറിച്ചുള്ള ഡാറ്റയുൾപ്പെടെയുള്ള നിങ്ങളുടെ ടാബ്‌ലെറ്റിന്‍റെ കോൾ ചരിത്രം പരിഷ്‌ക്കരിക്കാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു.ഇതു വഴി കോൾ ചരിത്ര ഡാറ്റകൾ പരിഷ്‌ക്കരിക്കാനും ഇല്ലാതാക്കാനും ദോഷകരമായ അപ്ലിക്കേഷനുകൾക്ക് കഴിഞ്ഞേയ്ക്കാം."</string>
- <string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"ഇൻകമിംഗ്, ഔട്ട്‌ഗോയിംഗ് കോളുകളെക്കുറിച്ചുള്ള ഡാറ്റ ഉൾപ്പെടെ നിങ്ങളുടെ Android ടിവിയിലെ കോൾ ചരിത്രം പരിഷ്‌ക്കരിക്കാൻ ആപ്പിനെ അനുവദിക്കുന്നു. നിങ്ങളുടെ കോൾ ചരിത്രം മായ്‌ക്കാനോ പരിഷ്‌ക്കരിക്കാനോ ദോഷകരമായ ആപ്പുകൾ ഇത് ഉപയോഗിച്ചേക്കാം."</string>
+ <string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"ഇൻകമിംഗ്, ഔട്ട്‌ഗോയിംഗ് കോളുകളെക്കുറിച്ചുള്ള ഡാറ്റ ഉൾപ്പെടെ നിങ്ങളുടെ Android TV-യിലെ കോൾ ചരിത്രം പരിഷ്‌ക്കരിക്കാൻ ആപ്പിനെ അനുവദിക്കുന്നു. നിങ്ങളുടെ കോൾ ചരിത്രം മായ്‌ക്കാനോ പരിഷ്‌ക്കരിക്കാനോ ദോഷകരമായ ആപ്പുകൾ ഇത് ഉപയോഗിച്ചേക്കാം."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"ഇൻകമ്മിംഗ്-ഔട്ട്ഗോയിംഗ് കോളുകളെക്കുറിച്ചുള്ള ഡാറ്റയുൾപ്പെടെയുള്ള നിങ്ങളുടെ ഫോണിന്‍റെ കോൾ ചരിത്രം പരിഷ്‌ക്കരിക്കാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു.ഇതു വഴി കോൾ ചരിത്ര ഡാറ്റകൾ പരിഷ്‌ക്കരിക്കാനും ഇല്ലാതാക്കാനും ദോഷകരമായ അപ്ലിക്കേഷനുകൾക്ക് കഴിഞ്ഞേയ്ക്കാം."</string>
<string name="permlab_bodySensors" msgid="3411035315357380862">"ശരീര സെൻസറുകൾ (ഹൃദയമിടിപ്പ് നിരക്ക് മോണിറ്ററുകൾ പോലെ) ആക്സസ് ചെയ്യുക"</string>
<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 ടിവിയിൽ സംഭരിച്ചിരിക്കുന്ന എല്ലാ കലണ്ടർ ഇവന്റുകളും വായിക്കാനും നിങ്ങളുടെ കലണ്ടർ ഡാറ്റ പങ്കിടാനോ സംരക്ഷിക്കാനോ സാധിക്കുകയും ചെയ്യും."</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 ടിവിയിൽ കലണ്ടർ ഇവന്റുകൾ ചേർക്കാനും നീക്കം ചെയ്യാനും മാറ്റാനും ഈ ആപ്പിന് കഴിയും. കലണ്ടർ ഉടമകളിൽ നിന്ന് വരുന്നതെന്ന് തോന്നിപ്പിക്കുന്ന സന്ദേശങ്ങൾ അയയ്‌ക്കാനോ ഉടമകൾക്ക് അറിയിപ്പ് നൽകാതെ ഇവന്റുകൾ മാറ്റാനോ ഈ ആപ്പിന് കഴിയും."</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>
@@ -462,15 +462,15 @@
<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 ടിവി ഉറങ്ങുന്നതിൽ നിന്ന് തടയുക"</string>
+ <string name="permlab_wakeLock" product="tv" msgid="2856941418123343518">"നിങ്ങളുടെ Android TV ഉറങ്ങുന്നതിൽ നിന്ന് തടയുക"</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="tv" msgid="2329298966735118796">"നിങ്ങളുടെ Android ടിവിയെ ഉറങ്ങുന്നതിൽ നിന്ന് തടയാൻ ആപ്പിനെ അനുവദിക്കുന്നു."</string>
+ <string name="permdesc_wakeLock" product="tv" msgid="2329298966735118796">"നിങ്ങളുടെ Android TV-യെ ഉറങ്ങുന്നതിൽ നിന്ന് തടയാൻ ആപ്പിനെ അനുവദിക്കുന്നു."</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 ടിവിയുടെ ഇൻഫ്രാറെഡ് ട്രാൻസ്‌മിറ്റർ ഉപയോഗിക്കാൻ ആപ്പിനെ അനുവദിക്കുന്നു."</string>
+ <string name="permdesc_transmitIr" product="tv" msgid="3278506969529173281">"നിങ്ങളുടെ Android TV-യുടെ ഇൻഫ്രാറെഡ് ട്രാൻസ്‌മിറ്റർ ഉപയോഗിക്കാൻ ആപ്പിനെ അനുവദിക്കുന്നു."</string>
<string name="permdesc_transmitIr" product="default" msgid="8484193849295581808">"ഫോണിന്റെ ഇൻഫ്രാറെഡ് ട്രാൻസ്‌മിറ്റർ ഉപയോഗിക്കാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string>
<string name="permlab_setWallpaper" msgid="6959514622698794511">"വാൾപേപ്പർ സജ്ജീകരിക്കുക"</string>
<string name="permdesc_setWallpaper" msgid="2973996714129021397">"സിസ്‌റ്റം വാൾപേപ്പറിനെ സജ്ജീകരിക്കുന്നതിന് അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string>
@@ -478,11 +478,11 @@
<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 ടിവിയുടെ സമയമേഖല മാറ്റാൻ ആപ്പിനെ അനുവദിക്കുന്നു."</string>
+ <string name="permdesc_setTimeZone" product="tv" msgid="9069045914174455938">"നിങ്ങളുടെ Android TV-യുടെ സമയമേഖല മാറ്റാൻ ആപ്പിനെ അനുവദിക്കുന്നു."</string>
<string name="permdesc_setTimeZone" product="default" msgid="4611828585759488256">"ഫോണിന്റെ സമയ മേഖലയെ മാറ്റുന്നതിന് അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string>
<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 ടിവി തിരിച്ചറിയുന്ന അക്കൗണ്ടുകളുടെ ലിസ്‌റ്റ് നേടാൻ ആപ്പിനെ അനുവദിക്കുന്നു. നിങ്ങൾ ഇൻസ്‌റ്റാൾ ചെയ്‌ത ആപ്പുകൾ സൃഷ്‌ടിച്ച ഏത് അക്കൗണ്ടുകളും ഇതിൽ ഉൾപ്പെടാം."</string>
+ <string name="permdesc_getAccounts" product="tv" msgid="437604680436540822">"നിങ്ങളുടെ Android TV തിരിച്ചറിയുന്ന അക്കൗണ്ടുകളുടെ ലിസ്‌റ്റ് നേടാൻ ആപ്പിനെ അനുവദിക്കുന്നു. നിങ്ങൾ ഇൻസ്‌റ്റാൾ ചെയ്‌ത ആപ്പുകൾ സൃഷ്‌ടിച്ച ഏത് അക്കൗണ്ടുകളും ഇതിൽ ഉൾപ്പെടാം."</string>
<string name="permdesc_getAccounts" product="default" msgid="2491273043569751867">"ഫോൺ തിരിച്ചറിയുന്ന അക്കൗണ്ടുകളുടെ ലിസ്റ്റ് നേടാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. ഇതിൽ നിങ്ങൾ ഇൻസ്റ്റാളുചെയ്‌ത അപ്ലിക്കേഷനുകൾ സൃഷ്‌ടിച്ച എല്ലാ അക്കൗണ്ടുകളും ഉൾപ്പെടാം."</string>
<string name="permlab_accessNetworkState" msgid="2349126720783633918">"നെറ്റ്‌വർക്ക് കണക്ഷനുകൾ കാണുക"</string>
<string name="permdesc_accessNetworkState" msgid="4394564702881662849">"ഏതെല്ലാം നെറ്റ്‌വർക്കുകൾ നിലവിലുണ്ടെന്നതും കണക്റ്റുചെയ്‌തിട്ടുണ്ടെന്നതും പോലുള്ള നെറ്റ്‌വർക്ക് കണക്ഷനുകളെക്കുറിച്ചുള്ള വിവരം കാണാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string>
@@ -498,21 +498,21 @@
<string name="permdesc_changeWifiState" msgid="7170350070554505384">"വൈഫൈ ആക്‌സസ്സ് പോയിന്റുകളിലേക്ക് കണക്റ്റുചെയ്യാനും അതിൽ നിന്ന് വിച്ഛേദിക്കാനും വൈഫൈ നെറ്റ്‌വർക്കുകൾക്കായി ഉപകരണ കോൺഫിഗറേഷൻ മാറ്റാനും അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string>
<string name="permlab_changeWifiMulticastState" msgid="285626875870754696">"വൈഫൈ മൾട്ടികാസ്‌റ്റ് റിസപ്‌ഷൻ അനുവദിക്കുക"</string>
<string name="permdesc_changeWifiMulticastState" product="tablet" msgid="191079868596433554">"മൾട്ടികാസ്‌റ്റ് വിലാസങ്ങൾ ഉപയോഗിച്ച് നിങ്ങളുടെ ടബ്‌ലെറ്റിലേക്ക് മാത്രമല്ലാതെ, ഒരു വൈഫൈ നെറ്റ്‌വർക്കിലെ എല്ലാ ഉപകരണങ്ങളിലേക്കും അയച്ച പായ്‌ക്കറ്റുകൾ നേടാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. ഇത് മൾട്ടികാസ്റ്റ് ഇതര മോഡിനേക്കാൾ അധികം പവർ ഉപയോഗിക്കുന്നു."</string>
- <string name="permdesc_changeWifiMulticastState" product="tv" msgid="1336952358450652595">"മൾട്ടികാസ്‌റ്റ് വിലാസങ്ങൾ ഉപയോഗിച്ച് നിങ്ങളുടെ Android ടിവിയിലേക്ക് മാത്രമല്ലാതെ ഒരു വൈഫൈ നെറ്റ്‌വർക്കിലെ എല്ലാ ഉപകരണങ്ങളിലേക്കും അയച്ച പാക്കറ്റുകൾ സ്വീകരിക്കാൻ ആപ്പിനെ അനുവദിക്കുന്നു. ഇത് മൾട്ടികാസ്‌റ്റ് ഇതര മോഡിനേക്കാൾ കൂടുതൽ പവർ ഉപയോഗിക്കുന്നു."</string>
+ <string name="permdesc_changeWifiMulticastState" product="tv" msgid="1336952358450652595">"മൾട്ടികാസ്‌റ്റ് വിലാസങ്ങൾ ഉപയോഗിച്ച് നിങ്ങളുടെ Android TV-യിലേക്ക് മാത്രമല്ലാതെ ഒരു വൈഫൈ നെറ്റ്‌വർക്കിലെ എല്ലാ ഉപകരണങ്ങളിലേക്കും അയച്ച പാക്കറ്റുകൾ സ്വീകരിക്കാൻ ആപ്പിനെ അനുവദിക്കുന്നു. ഇത് മൾട്ടികാസ്‌റ്റ് ഇതര മോഡിനേക്കാൾ കൂടുതൽ പവർ ഉപയോഗിക്കുന്നു."</string>
<string name="permdesc_changeWifiMulticastState" product="default" msgid="8296627590220222740">"മൾട്ടികാസ്‌റ്റ് വിലാസങ്ങൾ ഉപയോഗിച്ച് നിങ്ങളുടെ ഫോണിലേക്ക് മാത്രമല്ലാതെ, ഒരു വൈഫൈ നെറ്റ്‌വർക്കിലെ എല്ലാ ഉപകരണങ്ങളിലേക്കും അയച്ച പായ്‌ക്കറ്റുകൾ നേടാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. ഇത് മൾട്ടികാസ്റ്റ് ഇതര മോഡിനേക്കാൾ അധികം പവർ ഉപയോഗിക്കുന്നു."</string>
<string name="permlab_bluetoothAdmin" msgid="6490373569441946064">"ബ്ലൂടൂത്ത് ക്രമീകരണങ്ങൾ ആക്സസ്സുചെയ്യുക"</string>
<string name="permdesc_bluetoothAdmin" product="tablet" msgid="5370837055438574863">"ഒരു പ്രാദേശിക ബ്ലൂടൂത്ത് ടാബ്‌ലെറ്റ് കോൺഫിഗർചെയ്യുന്നതിനും വിദൂര ഉപകരണങ്ങളെ കണ്ടെത്തി ജോടിയാക്കുന്നതിനും അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string>
- <string name="permdesc_bluetoothAdmin" product="tv" msgid="1623992984547014588">"നിങ്ങളുടെ Android ടിവിയിൽ Bluetooth കോൺഫിഗർ ചെയ്യാനും വിദൂര ഉപകരണങ്ങൾ കണ്ടെത്താനും അവ ജോടിയാക്കാനും ആപ്പിനെ അനുവദിക്കുന്നു."</string>
+ <string name="permdesc_bluetoothAdmin" product="tv" msgid="1623992984547014588">"നിങ്ങളുടെ Android TV-യിൽ Bluetooth കോൺഫിഗർ ചെയ്യാനും വിദൂര ഉപകരണങ്ങൾ കണ്ടെത്താനും അവ ജോടിയാക്കാനും ആപ്പിനെ അനുവദിക്കുന്നു."</string>
<string name="permdesc_bluetoothAdmin" product="default" msgid="7381341743021234863">"ഒരു പ്രാദേശിക ബ്ലൂടൂത്ത് ഫോണിനെ കോൺഫിഗർചെയ്യുന്നതിനും വിദൂര ഉപകരണങ്ങളെ കണ്ടെത്തി ജോടിയാക്കുന്നതിനും അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string>
<string name="permlab_accessWimaxState" msgid="7029563339012437434">"WiMAX കണക്റ്റുചെയ്യുക, അതിൽ നിന്നും വിച്ഛേദിക്കുക"</string>
<string name="permdesc_accessWimaxState" msgid="5372734776802067708">"WiMAX പ്രവർത്തനക്ഷമമാണോയെന്നതും കണക്റ്റുചെയ്‌തിരിക്കുന്ന ഏതെങ്കിലും 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">"WiMAX നെറ്റ്‌വർക്കുകളിലേക്ക് നിങ്ങളുടെ Android ടിവി കണക്‌റ്റ് ചെയ്യാനും അതിൽ നിന്ന് Android ടിവിയെ വിച്‌ഛേദിക്കാനും ആപ്പിനെ അനുവദിക്കുന്നു."</string>
+ <string name="permdesc_changeWimaxState" product="tv" msgid="5373274458799425276">"WiMAX നെറ്റ്‌വർക്കുകളിലേക്ക് നിങ്ങളുടെ Android TV കണക്‌റ്റ് ചെയ്യാനും അതിൽ നിന്ന് Android TV-യെ വിച്‌ഛേദിക്കാനും ആപ്പിനെ അനുവദിക്കുന്നു."</string>
<string name="permdesc_changeWimaxState" product="default" msgid="1551666203780202101">"WiMAX നെറ്റ്‌വർക്കുകളിലേക്ക് ഫോൺ കണക്റ്റുചെയ്യാനും അതിൽ നിന്ന് വിച്ഛേദിക്കാനും അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string>
<string name="permlab_bluetooth" msgid="586333280736937209">"ബ്ലൂടൂത്ത് ഉപകരണങ്ങളുമായി ജോടിയാക്കുക"</string>
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"ടാബ്‌ലെറ്റിലെ ബ്ലൂടൂത്ത് കോൺഫിഗറേഷൻ കാണാനും ജോടിയാക്കിയ ഉപകരണങ്ങളുമായി കണക്ഷനുകൾ നടത്തി അംഗീകരിക്കാനും അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string>
- <string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"നിങ്ങളുടെ Android ടിവിയിലെ Bluetooth കോൺഫിഗറേഷൻ കാണാനും ജോടിയാക്കിയ ഉപകരണങ്ങളുമായി കണക്ഷനുകൾ സൃഷ്‌ടിക്കാനും അംഗീകരിക്കാനും ആപ്പിനെ അനുവദിക്കുന്നു."</string>
+ <string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"നിങ്ങളുടെ Android TV-യിലെ Bluetooth കോൺഫിഗറേഷൻ കാണാനും ജോടിയാക്കിയ ഉപകരണങ്ങളുമായി കണക്ഷനുകൾ സൃഷ്‌ടിക്കാനും അംഗീകരിക്കാനും ആപ്പിനെ അനുവദിക്കുന്നു."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"ഫോണിലെ ബ്ലൂടൂത്ത് കോൺഫിഗറേഷൻ കാണാനും ജോടിയാക്കിയ ഉപകരണങ്ങളുമായി കണക്ഷനുകൾ നടത്തി അംഗീകരിക്കാനും അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"തിരഞ്ഞെടുത്ത NFC പേയ്‌മെന്റ് സേവനത്തെ സംബന്ധിച്ച വിവരങ്ങൾ"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"റൂട്ട് ലക്ഷ്യസ്ഥാനം, രജിസ്‌റ്റർ ചെയ്തിരിക്കുന്ന സഹായങ്ങൾ എന്നിവ പോലുള്ള, തിരഞ്ഞെടുത്ത NFC പേയ്‌മെന്റ് സേവനത്തെ സംബന്ധിച്ച വിവരങ്ങൾ ലഭിക്കാൻ ആപ്പിനെ അനുവദിക്കുന്നു."</string>
@@ -673,10 +673,10 @@
<string name="policydesc_limitPassword" msgid="4105491021115793793">"സ്‌ക്രീൻ ലോക്ക് പാസ്‌വേഡുകളിലും PIN-കളിലും അനുവദിച്ചിരിക്കുന്ന ദൈർഘ്യവും പ്രതീകങ്ങളും നിയന്ത്രിക്കുക."</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 ടിവി ലോക്ക് ചെയ്യുകയോ Android ടിവിയിലെ എല്ലാ ഡാറ്റയും മായ്‌ക്കുകയോ ചെയ്യുക."</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_secondaryUser" product="tablet" msgid="2049038943004297474">"സ്‌ക്രീൻ അൺലോക്കുചെയ്യുമ്പോൾ തെറ്റായി ടൈപ്പുചെയ്‌ത പാസ്‌വേഡുകളുടെ എണ്ണം നിരീക്ഷിക്കുകയും നിരവധി തവണ പാസ്‌വേഡ് ടൈപ്പുചെയ്‌തെങ്കിൽ ടാബ്‌ലെറ്റ് ലോക്കുചെയ്യുകയോ ഈ എല്ലാ ഉപയോക്തൃവിവരവും മായ്‌ക്കുകയോ ചെയ്യുക."</string>
- <string name="policydesc_watchLogin_secondaryUser" product="tv" msgid="8965224107449407052">"സ്‌ക്രീൻ അൺലോക്ക് ചെയ്യുമ്പോൾ തെറ്റായി ടൈപ്പ് ചെയ്‌ത പാസ്‌വേഡുകളുടെ എണ്ണം നിരീക്ഷിക്കുകയും നിരവധി തവണ തെറ്റായ പാസ്‌വേഡുകൾ ടൈപ്പ് ചെയ്‌തിട്ടുണ്ടെങ്കിൽ നിങ്ങളുടെ Android ടിവി ലോക്ക് ചെയ്യുകയോ ഈ ഉപയോക്തൃ ഡാറ്റയെല്ലാം മായ്‌ക്കുകയോ ചെയ്യുക."</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>
@@ -684,11 +684,11 @@
<string name="policydesc_forceLock" msgid="1008844760853899693">"സ്‌ക്രീൻ ലോക്കുകൾ എങ്ങനെ വേണമെന്നും എപ്പോൾ വേണമെന്നും എന്നത് നിയന്ത്രിക്കുക"</string>
<string name="policylab_wipeData" msgid="1359485247727537311">"എല്ലാ ഡാറ്റയും മായ്ക്കുക"</string>
<string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"ഒരു ഫാക്‌ടറി ഡാറ്റ പുനഃസജ്ജീകരണം നടപ്പിലാക്കുന്നതിലൂടെ ടാബ്‌ലെറ്റിന്റെ ഡാറ്റ മുന്നറിയിപ്പില്ലാതെ മായ്‌ക്കുക."</string>
- <string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"ഫാക്‌ടറി ഡാറ്റ റീസെറ്റ് ചെയ്‌ത് നിങ്ങളുടെ Android ടിവിയിലെ ഉപകരണ ഡാറ്റ മുന്നറിയിപ്പില്ലാതെ മായ്‌ക്കുക."</string>
+ <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="tv" msgid="2293713284515865200">"ഈ Android ടിവിയിലെ ഈ ഉപയോക്തൃ ഡാറ്റ മുന്നറിയിപ്പില്ലാതെ മായ്‌ക്കുക."</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">"ഉപകരണ ഗ്ലോബൽ പ്രോക്‌സി സജ്ജീകരിക്കുക"</string>
<string name="policydesc_setGlobalProxy" msgid="7149665222705519604">"നയം പ്രവർത്തനക്ഷമമാക്കിയിരിക്കുമ്പോൾ ഉപകരണ ഗ്ലോബൽ പ്രോക്‌സി ഉപയോഗിക്കുന്നത് സജ്ജമാക്കുക. ഉപകരണ ഉടമയ്‌ക്ക് മാത്രമേ ഗ്ലോബൽ പ്രോക്‌സി സജ്ജമാക്കാനാകൂ."</string>
@@ -838,7 +838,7 @@
<string name="faceunlock_multiple_failures" msgid="681991538434031708">"മുഖം തിരിച്ചറിഞ്ഞുള്ള അൺലോക്ക് ശ്രമങ്ങളുടെ പരമാവധി കഴിഞ്ഞു"</string>
<string name="lockscreen_missing_sim_message_short" msgid="1248431165144893792">"സിം കാർഡില്ല"</string>
<string name="lockscreen_missing_sim_message" product="tablet" msgid="8596805728510570760">"ടാബ്‌ലെറ്റിൽ സിം കാർഡൊന്നുമില്ല."</string>
- <string name="lockscreen_missing_sim_message" product="tv" msgid="2582768023352171073">"നിങ്ങളുടെ Android ടിവിയിൽ സിം കാർഡില്ല."</string>
+ <string name="lockscreen_missing_sim_message" product="tv" msgid="2582768023352171073">"നിങ്ങളുടെ Android TV-യിൽ സിം കാർഡില്ല."</string>
<string name="lockscreen_missing_sim_message" product="default" msgid="1408695081255172556">"ഫോണിൽ സിം കാർഡൊന്നുമില്ല."</string>
<string name="lockscreen_missing_sim_instructions" msgid="8473601862688263903">"ഒരു സിം കാർഡ് ചേർക്കുക."</string>
<string name="lockscreen_missing_sim_instructions_long" msgid="3664999892038416334">"സിം കാർഡ് കാണുന്നില്ല അല്ലെങ്കിൽ റീഡുചെയ്യാനായില്ല. ഒരു സിം കാർഡ് ചേർക്കുക."</string>
@@ -861,13 +861,13 @@
<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> ശ്രമങ്ങൾ കൂടി പരാജയപ്പെട്ടാൽ Google സൈൻ ഇൻ ഉപയോഗിച്ച് നിങ്ങളുടെ Android ടിവി അൺലോക്ക് ചെയ്യാൻ ആവശ്യപ്പെടും.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> സെക്കൻഡിന് ശേഷം വീണ്ടും ശ്രമിക്കുക."</string>
+ <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="6399092175942158529">"നിങ്ങളുടെ അൺലോക്ക് പാറ്റേൺ <xliff:g id="NUMBER_0">%1$d</xliff:g> തവണ തെറ്റായി വരച്ചു. <xliff:g id="NUMBER_1">%2$d</xliff:g> ശ്രമങ്ങൾ കൂടി പരാജയപ്പെട്ടാൽ Google സൈൻ ഇൻ ഉപയോഗിച്ച് നിങ്ങളുടെ Android TV അൺലോക്ക് ചെയ്യാൻ ആവശ്യപ്പെടും.\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">"നിങ്ങൾ <xliff:g id="NUMBER_0">%1$d</xliff:g> തവണ തെറ്റായി Android ടിവി അൺലോക്ക് ചെയ്യാൻ ശ്രമിച്ചു. <xliff:g id="NUMBER_1">%2$d</xliff:g> ശ്രമങ്ങൾ കൂടി പരാജയപ്പെട്ടാൽ, നിങ്ങളുടെ Android ടിവി ഫാക്‌ടറി ഡിഫോൾട്ടിലേക്ക് റീസെറ്റ് ചെയ്യപ്പെടുകയും എല്ലാ ഉപയോക്തൃ ഡാറ്റയും നഷ്‌ടപ്പെടുകയും ചെയ്യും."</string>
+ <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="4275591249631864248">"നിങ്ങൾ <xliff:g id="NUMBER_0">%1$d</xliff:g> തവണ തെറ്റായി Android TV അൺലോക്ക് ചെയ്യാൻ ശ്രമിച്ചു. <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">"നിങ്ങൾ <xliff:g id="NUMBER">%d</xliff:g> തവണ തെറ്റായി Android ടിവി അൺലോക്ക് ചെയ്യാൻ ശ്രമിച്ചു. നിങ്ങളുടെ Android ടിവി ഇപ്പോൾ ഫാക്‌ടറി ഡിഫോൾട്ടിലേക്ക് റീസെറ്റ് ചെയ്യപ്പെടും."</string>
+ <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="2205435033340091883">"നിങ്ങൾ <xliff:g id="NUMBER">%d</xliff:g> തവണ തെറ്റായി Android TV അൺലോക്ക് ചെയ്യാൻ ശ്രമിച്ചു. നിങ്ങളുടെ 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_forgot_pattern_button_text" msgid="8362442730606839031">"പാറ്റേൺ മറന്നോ?"</string>
@@ -954,7 +954,7 @@
<string name="permdesc_readHistoryBookmarks" msgid="2323799501008967852">"ബ്രൗസർ സന്ദർശിച്ച എല്ലാ URL-കളുടെയും ചരിത്രവും ബ്രൗസറിന്റെ എല്ലാ ബുക്ക്‌മാർക്കുകളും റീഡുചെയ്യാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. ശ്രദ്ധിക്കുക: ഈ അനുമതി മൂന്നാം കക്ഷി ബ്രൗസറുകളോ വെബ് ബ്രൗസിംഗ് കഴിവുകളുള്ള മറ്റ് അപ്ലിക്കേഷനുകളോ നടപ്പിലാക്കാനിടയില്ല."</string>
<string name="permlab_writeHistoryBookmarks" msgid="6090259925187986937">"വെബ് ബുക്ക്‌മാർക്കുകളും ചരിത്രവും റൈറ്റുചെയ്യുക"</string>
<string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="573341025292489065">"നിങ്ങളുടെ ടാബ്‌ലെറ്റിൽ സംഭരിച്ചിരിക്കുന്ന ബ്രൗസറിന്റെ ചരിത്രമോ ബുക്ക്‌മാർക്കുകളോ പരിഷ്‌ക്കരിക്കാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. ഇത് ബ്രൗസർ ഡാറ്റ മായ്‌ക്കാനോ പരിഷ്‌ക്കരിക്കാനോ അപ്ലിക്കേഷനെ അനുവദിക്കാനിടയുണ്ട്. ശ്രദ്ധിക്കുക: ഈ അനുമതി മൂന്നാം കക്ഷി ബ്രൗസറുകളോ വെബ് ബ്രൗസിംഗ് കഴിവുകളുള്ള മറ്റ് അപ്ലിക്കേഷനുകളോ നടപ്പിലാക്കാനിടയില്ല."</string>
- <string name="permdesc_writeHistoryBookmarks" product="tv" msgid="88642768580408561">"നിങ്ങളുടെ Android ടിവിയിൽ സംഭരിച്ചിരിക്കുന്ന ബ്രൗസറിന്റെ ചരിത്രവും ബുക്ക്‌മാർക്കുകളും പരിഷ്‌ക്കരിക്കാൻ ആപ്പിനെ അനുവദിക്കുന്നു. ബ്രൗസർ ഡാറ്റ മായ്‌ക്കാനോ പരിഷ്‌ക്കരിക്കാനോ ഇത് ആപ്പിനെ അനുവദിച്ചേക്കാം. ശ്രദ്ധിക്കുക: മൂന്നാം കക്ഷി ബ്രൗസറുകൾക്കോ വെബ് ബ്രൗസിംഗ് ശേഷികളുള്ള മറ്റ് ആപ്പുകൾക്കോ ഈ അനുമതി നടപ്പിലാക്കാനായേക്കില്ല."</string>
+ <string name="permdesc_writeHistoryBookmarks" product="tv" msgid="88642768580408561">"നിങ്ങളുടെ Android TV-യിൽ സംഭരിച്ചിരിക്കുന്ന ബ്രൗസറിന്റെ ചരിത്രവും ബുക്ക്‌മാർക്കുകളും പരിഷ്‌ക്കരിക്കാൻ ആപ്പിനെ അനുവദിക്കുന്നു. ബ്രൗസർ ഡാറ്റ മായ്‌ക്കാനോ പരിഷ്‌ക്കരിക്കാനോ ഇത് ആപ്പിനെ അനുവദിച്ചേക്കാം. ശ്രദ്ധിക്കുക: മൂന്നാം കക്ഷി ബ്രൗസറുകൾക്കോ വെബ് ബ്രൗസിംഗ് ശേഷികളുള്ള മറ്റ് ആപ്പുകൾക്കോ ഈ അനുമതി നടപ്പിലാക്കാനായേക്കില്ല."</string>
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="2245203087160913652">"നിങ്ങളുടെ ഫോണിൽ സംഭരിച്ചിരിക്കുന്ന ബ്രൗസറിന്റെ ചരിത്രമോ ബുക്ക്‌മാർക്കുകളോ പരിഷ്‌ക്കരിക്കാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. ഇത് ബ്രൗസർ ഡാറ്റ മായ്‌ക്കാനോ പരിഷ്‌ക്കരിക്കാനോ അപ്ലിക്കേഷനെ അനുവദിക്കാനിടയുണ്ട്. ശ്രദ്ധിക്കുക: ഈ അനുമതി മൂന്നാം കക്ഷി ബ്രൗസറുകളോ വെബ് ബ്രൗസിംഗ് കഴിവുകളുള്ള മറ്റ് അപ്ലിക്കേഷനുകളോ നടപ്പിലാക്കാനിടയില്ല."</string>
<string name="permlab_setAlarm" msgid="1158001610254173567">"ഒരു അലാറം സജ്ജീകരിക്കുക"</string>
<string name="permdesc_setAlarm" msgid="2185033720060109640">"ഒരു ഇൻസ്റ്റാളുചെയ്‌ത അലാറം ക്ലോക്ക് അപ്ലിക്കേഷനിൽ അലാറം സജ്ജീകരിക്കുന്നതിന് അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. ചില അലാറം ക്ലോക്ക് അപ്ലിക്കേഷനുകൾ ഈ സവിശേഷത നടപ്പിലാക്കാതിരുന്നേക്കാം."</string>
@@ -1309,7 +1309,7 @@
<string name="adb_active_notification_title" msgid="408390247354560331">"USB ഡീബഗ്ഗിംഗ് കണക്റ്റ് ചെയ്തു"</string>
<string name="adb_active_notification_message" msgid="5617264033476778211">"USB ഡീബഗ്ഗിംഗ് ഓഫാക്കാൻ ടാപ്പ് ചെയ്യുക"</string>
<string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"USB ഡീബഗ്ഗുചെയ്യൽ പ്രവർത്തനരഹിതമാക്കാൻ തിരഞ്ഞെടുക്കുക."</string>
- <string name="adbwifi_active_notification_title" msgid="6147343659168302473">"വയർലെസ് ഡീബഗ്ഗിംഗ് കണക്റ്റ് ചെയ്തിരിക്കുന്നു"</string>
+ <string name="adbwifi_active_notification_title" msgid="6147343659168302473">"വയർലെസ് ഡീബഗ്ഗിംഗ് കണക്റ്റ് ചെയ്തു"</string>
<string name="adbwifi_active_notification_message" msgid="930987922852867972">"വയർലെസ് ഡീബഗ്ഗിംഗ് ഓഫാക്കാൻ ടാപ്പ് ചെയ്യുക"</string>
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"വയർലെസ് ഡീബഗ്ഗിംഗ് പ്രവർത്തനരഹിതമാക്കാൻ തിരഞ്ഞെടുക്കുക."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"പരിശോധനാ സംവിധാനങ്ങൾ മോഡ് പ്രവർത്തനക്ഷമമാക്കി"</string>
@@ -1609,22 +1609,21 @@
<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">"നിങ്ങൾ <xliff:g id="NUMBER_0">%1$d</xliff:g> തവണ തെറ്റായി Android ടിവി അൺലോക്ക് ചെയ്യാൻ ശ്രമിച്ചു. <xliff:g id="NUMBER_1">%2$d</xliff:g> ശ്രമങ്ങൾ കൂടി പരാജയപ്പെട്ടാൽ, നിങ്ങളുടെ Android ടിവി ഫാക്‌ടറി ഡിഫോൾട്ടിലേക്ക് റീസെറ്റ് ചെയ്യപ്പെടുകയും എല്ലാ ഉപയോക്തൃ ഡാറ്റയും നഷ്‌ടപ്പെടുകയും ചെയ്യും."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="9064457748587850217">"നിങ്ങൾ <xliff:g id="NUMBER_0">%1$d</xliff:g> തവണ തെറ്റായി Android TV അൺലോക്ക് ചെയ്യാൻ ശ്രമിച്ചു. <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">"നിങ്ങൾ <xliff:g id="NUMBER">%d</xliff:g> തവണ തെറ്റായി Android ടിവി അൺലോക്ക് ചെയ്യാൻ ശ്രമിച്ചു. നിങ്ങളുടെ Android ടിവി ഇപ്പോൾ ഫാക്‌ടറി ഡിഫോൾട്ടിലേക്ക് റീസെറ്റ് ചെയ്യപ്പെടും."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tv" msgid="5045460916106267585">"നിങ്ങൾ <xliff:g id="NUMBER">%d</xliff:g> തവണ തെറ്റായി Android TV അൺലോക്ക് ചെയ്യാൻ ശ്രമിച്ചു. നിങ്ങളുടെ 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_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 ടിവി അൺലോക്ക് ചെയ്യാൻ ആവശ്യപ്പെടും.\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_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"നീക്കംചെയ്യുക"</string>
- <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> എന്നതിൽ നിന്നുള്ള പശ്ചാത്തലത്തിൽ ആരംഭിച്ച് ഫോർഗ്രൗണ്ടിൽ വരുന്ന സേവനത്തിന് ഭാവി R ബിൽഡുകളിൽ, \'ഉപയോഗിക്കുമ്പോൾ മാത്രമുള്ള അനുമതി\' ഉണ്ടായിരിക്കില്ല. go/r-bg-fgs-restriction കണ്ട് ബഗ് റിപ്പോർട്ട് ഫയൽ ചെയ്യുക."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"മുകളിൽക്കൊടുത്തിരിക്കുന്ന ശുപാർശചെയ്‌ത ലെവലിലേക്ക് വോളിയം വർദ്ധിപ്പിക്കണോ?\n\nഉയർന്ന വോളിയത്തിൽ ദീർഘനേരം കേൾക്കുന്നത് നിങ്ങളുടെ ശ്രവണ ശേഷിയെ ദോഷകരമായി ബാധിക്കാം."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"ഉപയോഗസഹായി കുറുക്കുവഴി ഉപയോഗിക്കണോ?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"കുറുക്കുവഴി ഓണായിരിക്കുമ്പോൾ, രണ്ട് വോളിയം ബട്ടണുകളും 3 സെക്കൻഡ് നേരത്തേക്ക് അമർത്തുന്നത് ഉപയോഗസഹായി ഫീച്ചർ ആരംഭിക്കും."</string>
<string name="accessibility_shortcut_multiple_service_warning_title" msgid="8417489297036013065">"ഉപയോഗസഹായി ഫീച്ചറുകൾ ഓണാക്കണോ?"</string>
- <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"രണ്ട് വോളിയം കീകളും അൽപ്പ നേരത്തേക്ക് അമർത്തിപ്പിടിക്കുന്നത്, ഉപയോഗസഹായി ഫീച്ചറുകൾ ഓണാക്കുന്നു. നിങ്ങളുടെ ഉപകരണം പ്രവർത്തിക്കുന്ന വിധം ഇത് മാറ്റിയേക്കാം.\n\nനിലവിലുള്ള ഫീച്ചറുകൾ:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nതിരഞ്ഞെടുത്ത ഫീച്ചറുകൾ ക്രമീകരണം &gt; ഉപയോഗസഹായി എന്നതിൽ മാറ്റാനാവും."</string>
+ <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"രണ്ട് വോളിയം കീകളും അൽപ്പ നേരത്തേക്ക് അമർത്തിപ്പിടിക്കുന്നത്, ഉപയോഗസഹായി ഫീച്ചറുകൾ ഓണാക്കുന്നു. നിങ്ങളുടെ ഉപകരണം പ്രവർത്തിക്കുന്ന രീതിയെ ഇത് മാറ്റിയേക്കാം.\n\nനിലവിലുള്ള ഫീച്ചറുകൾ:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nതിരഞ്ഞെടുത്ത ഫീച്ചറുകൾ ക്രമീകരണം &gt; ഉപയോഗസഹായി എന്നതിൽ മാറ്റാനാവും."</string>
<string name="accessibility_shortcut_multiple_service_list" msgid="6935581470716541531">" • <xliff:g id="SERVICE">%1$s</xliff:g>\n"</string>
<string name="accessibility_shortcut_single_service_warning_title" msgid="2819109500943271385">"<xliff:g id="SERVICE">%1$s</xliff:g> ഓണാക്കണോ?"</string>
<string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"രണ്ട് വോളിയം കീകളും അൽപ്പ നേരത്തേക്ക് അമർത്തിപ്പിടിക്കുന്നത് ഉപയോഗസഹായി ഫീച്ചറായ <xliff:g id="SERVICE">%1$s</xliff:g> എന്നതിനെ ഓണാക്കുന്നു. നിങ്ങളുടെ ഉപകരണം പ്രവർത്തിക്കുന്ന വിധം ഇത് മാറ്റിയേക്കാം.\n\nക്രമീകരണം &gt; ഉപയോഗസഹായി എന്നതിലെ മറ്റൊരു ഫീച്ചറിലേക്ക് നിങ്ങൾക്ക് ഈ കുറുക്കുവഴി മാറ്റാനാവും."</string>
@@ -1641,9 +1640,9 @@
<string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"ഇതിന് ഒരു ആപ്പുമായോ ഹാർഡ്‌വെയർ സെൻസറുമായോ ഉള്ള നിങ്ങളുടെ ആശയവിനിമയങ്ങൾ ട്രാക്ക് ചെയ്യാനും നിങ്ങളുടെ പേരിൽ ആശയവിനിമയം നടത്താനും കഴിയും."</string>
<string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"അനുവദിക്കൂ"</string>
<string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"നിരസിക്കുക"</string>
- <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"ഇത് ഉപയോഗിക്കാൻ ആരംഭിക്കുന്നതിന് ഫീച്ചർ ടാപ്പ് ചെയ്യുക:"</string>
+ <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"ഉപയോഗിച്ച് തുടങ്ങാൻ ഫീച്ചർ ടാപ്പ് ചെയ്യുക:"</string>
<string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"ഉപയോഗസഹായി ബട്ടണിന്റെ സഹായത്തോടെ, ഉപയോഗിക്കാൻ ഫീച്ചറുകൾ തിരഞ്ഞെടുക്കുക"</string>
- <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"വോളിയം കീ കുറുക്കുവഴിയുടെ സഹായത്തോടെ, ഉപയോഗിക്കാൻ ഫീച്ചറുകൾ തിരഞ്ഞെടുക്കുക"</string>
+ <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="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"കുറുക്കുവഴികൾ തിരുത്തുക"</string>
<string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"പൂർത്തിയാക്കി"</string>
@@ -1652,7 +1651,7 @@
<string name="color_inversion_feature_name" msgid="326050048927789012">"വർണ്ണ വിപര്യയം"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"നിറം ക്രമീകരിക്കൽ"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"വോളിയം കീകൾ പിടിച്ചു. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ഓണാക്കി."</string>
- <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"വോളിയം കീകൾ പിടിച്ചു. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ഓഫാക്കി."</string>
+ <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"വോളിയം കീകൾ അമർത്തിപ്പിടിച്ചു. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ഓഫാക്കി."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> ഉപയോഗിക്കാൻ, രണ്ട് വോളിയം കീകളും മൂന്ന് സെക്കൻഡ് അമർത്തിപ്പിടിക്കുക"</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"നിങ്ങൾ ഉപയോഗസഹായി ബട്ടൺ ടാപ്പ് ചെയ്യുമ്പോൾ ഉപയോഗിക്കുന്നതിന് ഒരു ഫീച്ചർ തിരഞ്ഞെടുക്കുക:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"ഉപയോഗസഹായി വിരൽചലനത്തോടൊപ്പം ഉപയോഗിക്കാൻ ഒരു ഫീച്ചർ തിരഞ്ഞെടുക്കുക (രണ്ട് വിരലുകളുപയോഗിച്ച് സ്‌ക്രീനിന്റെ താഴെ നിന്ന് മുകളിലോട്ട് സ്വൈപ്പ് ചെയ്യുക):"</string>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 11683ae46138..121b71c1b4a7 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -175,7 +175,7 @@
<string name="contentServiceTooManyDeletesNotificationDesc" msgid="4562226280528716090">"Хэт олон <xliff:g id="CONTENT_TYPE">%s</xliff:g>-г устгах оролдлого хийсэн байна."</string>
<string name="low_memory" product="tablet" msgid="5557552311566179924">"Таблетийн сан дүүрсэн. Зай чөлөөлөх бол зарим файлыг устгана уу."</string>
<string name="low_memory" product="watch" msgid="3479447988234030194">"Цагны сан дүүрсэн. Зай чөлөөлөх бол зарим файлыг устгана уу."</string>
- <string name="low_memory" product="tv" msgid="6663680413790323318">"Android TВ төхөөрөмжийн хадгалах сан дүүрсэн байна. Зай гаргахын тулд зарим файлыг устгана уу."</string>
+ <string name="low_memory" product="tv" msgid="6663680413790323318">"Android TV төхөөрөмжийн хадгалах сан дүүрсэн байна. Зай гаргахын тулд зарим файлыг устгана уу."</string>
<string name="low_memory" product="default" msgid="2539532364144025569">"Утасны сан дүүрсэн. Зай чөлөөлөх бол зарим файлыг устгана уу."</string>
<plurals name="ssl_ca_cert_warning" formatted="false" msgid="2288194355006173029">
<item quantity="other">Сертификатын эрхийг суулгасан</item>
@@ -206,7 +206,7 @@
<string name="personal_apps_suspended_turn_profile_on" msgid="2758012869627513689">"Асаах"</string>
<string name="me" msgid="6207584824693813140">"Би"</string>
<string name="power_dialog" product="tablet" msgid="8333207765671417261">"Таблетын сонголтууд"</string>
- <string name="power_dialog" product="tv" msgid="7792839006640933763">"Android ТВ-н сонголт"</string>
+ <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>
@@ -224,7 +224,7 @@
<string name="reboot_to_reset_message" msgid="3347690497972074356">"Дахин эхэлж байна..."</string>
<string name="shutdown_progress" msgid="5017145516412657345">"Унтрааж байна…"</string>
<string name="shutdown_confirm" product="tablet" msgid="2872769463279602432">"Таны таблет унтрах болно."</string>
- <string name="shutdown_confirm" product="tv" msgid="7975942887313518330">"Таны Android ТВ төхөөрөмж унтарна."</string>
+ <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>
@@ -233,7 +233,7 @@
<string name="recent_tasks_title" msgid="8183172372995396653">"Сүүлийн"</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 ТВ-н сонголт"</string>
+ <string name="global_actions" product="tv" msgid="3871763739487450369">"Android TV-н сонголт"</string>
<string name="global_actions" product="default" msgid="6410072189971495460">"Утасны сонголтууд"</string>
<string name="global_action_lock" msgid="6949357274257655383">"Дэлгэцний түгжээ"</string>
<string name="global_action_power_off" msgid="4404936470711393203">"Унтраах"</string>
@@ -357,7 +357,7 @@
<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="tv" msgid="3054753345758011986">"Энэ апп таны Android ТВ төхөөрөмжид хадгалсан бүх SMS (текст) мессежийг уншиж чадна."</string>
+ <string name="permdesc_readSms" product="tv" msgid="3054753345758011986">"Энэ апп таны Android TV төхөөрөмжид хадгалсан бүх 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>
@@ -379,7 +379,7 @@
<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 ТВ төхөөрөмжийг удаашруулж буй бусад аппад боломжтой санах ойг хязгаарлаж болно."</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">"интерактив (foreground) үйлчилгээг ажиллуулах"</string>
<string name="permdesc_foregroundService" msgid="8720071450020922795">"Аппад интерактив (foreground) үйлчилгээг ашиглахыг зөвшөөрнө үү."</string>
@@ -389,35 +389,35 @@
<string name="permdesc_writeSettings" msgid="8293047411196067188">"Апп нь системийн тохиргооны датаг өөрчлөх боломжтой. Хортой апп нь таны системийн тохиргоог сүйтгэх боломжтой."</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 ТВ төхөөрөмжийн эхлэх хугацааг удаашруулах боломжтойгоос гадна аппыг тогтмол ажиллуулснаар төхөөрөмжийн ерөнхий хурдыг удаашруулж болзошгүй."</string>
+ <string name="permdesc_receiveBootCompleted" product="tv" msgid="4900842256047614307">"Аппад системийг ачаалж дуусмагц өөрийгөө эхлүүлэхийг зөвшөөрнө. Энэ нь таны Android TV төхөөрөмжийн эхлэх хугацааг удаашруулах боломжтойгоос гадна аппыг тогтмол ажиллуулснаар төхөөрөмжийн ерөнхий хурдыг удаашруулж болзошгүй."</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">"Аппад нэвтрүүлэг дууссаны дараа үлдэх бэхлэгдсэн нэвтрүүлэг илгээхийг зөвшөөрнө. Хэт их ашиглах нь санах ойн ачааллыг нэмэгдүүлж, улмаар таны Android ТВ төхөөрөмжийг удаан эсвэл тогтворгүй болгож болзошгүй."</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">"Аппaд таны таблет дээр хадгалагдсан харилцагчдын өгөгдлийг уншихыг зөвшөөрнө. Мөн аппууд нь таны таблет дээрх харилцагч үүсгэсэн бүртгэлд хандах боломжтой байна. Үүнд таны суулгасан аппуудын үүсгэсэн бүртгэлийг оролцуулж болзошгүй. Энэ зөвшөөрөл нь аппуудад таны харилцагчийн өгөгдлийг хадгалахыг зөвшөөрөх бөгөөд хортой аппууд нь танд мэдэгдэлгүйгээр харилцагчийн өгөгдлийг хуваалцаж болзошгүй."</string>
- <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Аппaд таны Android TВ төхөөрөмж дээр хадгалагдсан харилцагчдын өгөгдлийг уншихыг зөвшөөрнө. Мөн аппууд нь таны Android TВ төхөөрөмж дээрх харилцагч үүсгэсэн бүртгэлд хандах боломжтой байна. Үүнд таны суулгасан аппуудын үүсгэсэн бүртгэлийг оролцуулж болзошгүй. Энэ зөвшөөрөл нь аппуудад таны харилцагчийн өгөгдлийг хадгалахыг зөвшөөрөх бөгөөд хортой аппууд нь танд мэдэгдэлгүйгээр харилцагчийн өгөгдлийг хуваалцаж болзошгүй."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Аппaд таны Android TV төхөөрөмж дээр хадгалагдсан харилцагчдын өгөгдлийг уншихыг зөвшөөрнө. Мөн аппууд нь таны Android TV төхөөрөмж дээрх харилцагч үүсгэсэн бүртгэлд хандах боломжтой байна. Үүнд таны суулгасан аппуудын үүсгэсэн бүртгэлийг оролцуулж болзошгүй. Энэ зөвшөөрөл нь аппуудад таны харилцагчийн өгөгдлийг хадгалахыг зөвшөөрөх бөгөөд хортой аппууд нь танд мэдэгдэлгүйгээр харилцагчийн өгөгдлийг хуваалцаж болзошгүй."</string>
<string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Аппaд таны утсан дээр хадгалагдсан харилцагчдын өгөгдлийг уншихыг зөвшөөрнө. Мөн аппууд нь таны утсан дээрх харилцагч үүсгэсэн бүртгэлд хандах боломжтой байна. Үүнд таны суулгасан аппуудын үүсгэсэн бүртгэлийг оролцуулж болзошгүй. Энэ зөвшөөрөл нь аппуудад таны харилцагчийн өгөгдлийг хадгалахыг зөвшөөрөх бөгөөд хортой аппууд нь танд мэдэгдэлгүйгээр харилцагчийн өгөгдлийг хуваалцаж болзошгүй."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"таны харилцагчдыг өөрчлөх"</string>
<string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Аппад таны таблет дээр хадгалагдсан харилцагчдын өгөгдлийг өөрчлөхийг зөвшөөрнө. Энэ зөвшөөрөл нь харилцагчийн өгөгдлийг устгахыг аппуудад зөвшөөрнө."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Аппaд таны Android TВ төхөөрөмж дээр хадгалагдсан харилцагчдын өгөгдлийг өөрчлөхийг зөвшөөрнө. Энэ зөвшөөрөл нь харилцагчийн өгөгдлийг устгахыг аппуудад зөвшөөрнө."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Аппaд таны Android TV төхөөрөмж дээр хадгалагдсан харилцагчдын өгөгдлийг өөрчлөхийг зөвшөөрнө. Энэ зөвшөөрөл нь харилцагчийн өгөгдлийг устгахыг аппуудад зөвшөөрнө."</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="permlab_writeCallLog" msgid="670292975137658895">"дуудлагын логруу бичих"</string>
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Апп нь таны таблетын ирсэн гарсан дуудлага зэргийг агуулсан дуудлагын логыг унших боломжтой. Хортой апп нь энийг ашиглан таны дуудлагын логыг өөрчлөх болон арилгах боломжтой."</string>
- <string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Аппад таны Android ТВ төхөөрөмжийн ирсэн болон залгасан дуудлага зэрэг өгөгдөл бүхий дуудлагын жагсаалтыг өөрчлөхийг зөвшөөрнө. Хортой аппууд үүнийг ашиглан таны дуудлагын жагсаалтыг устгаж эсвэл өөрчилж болзошгүй."</string>
+ <string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Аппад таны Android TV төхөөрөмжийн ирсэн болон залгасан дуудлага зэрэг өгөгдөл бүхий дуудлагын жагсаалтыг өөрчлөхийг зөвшөөрнө. Хортой аппууд үүнийг ашиглан таны дуудлагын жагсаалтыг устгаж эсвэл өөрчилж болзошгүй."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Апп нь таны утасны ирсэн гарсан дуудлага зэргийг агуулсан дуудлагын логыг өөрчлөх боломжтой. Хортой апп нь энийг ашиглан таны дуудлагын логыг өөрчлөх болон арилгах боломжтой."</string>
<string name="permlab_bodySensors" msgid="3411035315357380862">"биеийн мэдрэгчид хандах (зүрхний хэмнэл шалгагч г.м)"</string>
<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 ТВ төхөөрөмжид хадгалсан календарийн бүх арга хэмжээг унших болон таны календарийн өгөгдлийг хуваалцах эсвэл хадгалах боломжтой."</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 ТВ төхөөрөмжид календарийн арга хэмжээ нэмэх, үүнийг устгах, эсвэл өөрчлөх боломжтой. Энэ апп календарийн өмчлөгчөөс ирсэн мэт харагдаж болох мессеж илгээх эсвэл арга хэмжээг өмчлөгчид нь мэдэгдэлгүйгээр өөрчлөх боломжтой."</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>
@@ -462,15 +462,15 @@
<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 TВ төхөөрөмжийг идэвхгүй болохоос сэргийлэх"</string>
+ <string name="permlab_wakeLock" product="tv" msgid="2856941418123343518">"таны Android TV төхөөрөмжийг идэвхгүй болохоос сэргийлэх"</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="tv" msgid="2329298966735118796">"Аппад таны Android ТВ төхөөрөмжийг идэвхгүй болохоос сэргийлэхийг зөвшөөрнө."</string>
+ <string name="permdesc_wakeLock" product="tv" msgid="2329298966735118796">"Аппад таны Android TV төхөөрөмжийг идэвхгүй болохоос сэргийлэхийг зөвшөөрнө."</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 ТВ төхөөрөмжийн хэт улаан туяаны дамжуулагчийг ашиглахыг зөвшөөрнө."</string>
+ <string name="permdesc_transmitIr" product="tv" msgid="3278506969529173281">"Аппад таны Android TV төхөөрөмжийн хэт улаан туяаны дамжуулагчийг ашиглахыг зөвшөөрнө."</string>
<string name="permdesc_transmitIr" product="default" msgid="8484193849295581808">"Апп-д утасны хэт улаан дамжуулагчийг ашиглахыг зөвшөөрнө."</string>
<string name="permlab_setWallpaper" msgid="6959514622698794511">"ханын зургийг тохируулах"</string>
<string name="permdesc_setWallpaper" msgid="2973996714129021397">"Апп нь системийн ханын зургийг тохируулах боломжтой."</string>
@@ -478,11 +478,11 @@
<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 ТВ төхөөрөмжийн цагийн бүсийг өөрчлөхийг зөвшөөрнө."</string>
+ <string name="permdesc_setTimeZone" product="tv" msgid="9069045914174455938">"Аппад таны Android TV төхөөрөмжийн цагийн бүсийг өөрчлөхийг зөвшөөрнө."</string>
<string name="permdesc_setTimeZone" product="default" msgid="4611828585759488256">"Апп нь утасны цагийн бүсийг өөрчлөх боломжтой."</string>
<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 ТВ төхөөрөмжөөр танигдсан бүртгэлийн жагсаалтыг авахыг зөвшөөрнө. Үүнд таны суулгасан аппуудын үүсгэсэн аливаа бүртгэлийг оруулж болзошгүй."</string>
+ <string name="permdesc_getAccounts" product="tv" msgid="437604680436540822">"Аппад таны Android TV төхөөрөмжөөр танигдсан бүртгэлийн жагсаалтыг авахыг зөвшөөрнө. Үүнд таны суулгасан аппуудын үүсгэсэн аливаа бүртгэлийг оруулж болзошгүй."</string>
<string name="permdesc_getAccounts" product="default" msgid="2491273043569751867">"Апп нь утсанд мэдэгдэж байгаа бүртгэлийн жагсаалтыг авах боломжтой. Энд таны суулгасан аппликейшнүүдийг үүсгэсэн бүх акаунтууд хамрагдана."</string>
<string name="permlab_accessNetworkState" msgid="2349126720783633918">"сүлжээний холболтыг үзэх"</string>
<string name="permdesc_accessNetworkState" msgid="4394564702881662849">"Апп нь сүлжээ байгаа болон холбогдсон эсэх зэрэг сүлжээний холболтын талаарх мэдээллийг харах боломжтой."</string>
@@ -498,21 +498,21 @@
<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="tv" msgid="1336952358450652595">"Аппад таны Android ТВ төхөөрөмжөөс гадна Wi-Fi сүлжээг ашиглаж буй бүх төхөөрөмжид илгээсэн багцыг олон цэгийн хаяг ашиглан хүлээн авахыг зөвшөөрнө. Энэ нь олон цэгийн бус горимоос илүү их тэжээл ашиглана."</string>
+ <string name="permdesc_changeWifiMulticastState" product="tv" msgid="1336952358450652595">"Аппад таны Android TV төхөөрөмжөөс гадна Wi-Fi сүлжээг ашиглаж буй бүх төхөөрөмжид илгээсэн багцыг олон цэгийн хаяг ашиглан хүлээн авахыг зөвшөөрнө. Энэ нь олон цэгийн бус горимоос илүү их тэжээл ашиглана."</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">"Апп нь дотоод блютүүт таблетын тохиргоог харах боломжтой ба хос болох төхөөрөмжтэй холболтыг зөвшөөрөх болон хийх боломжтой"</string>
- <string name="permdesc_bluetoothAdmin" product="tv" msgid="1623992984547014588">"Аппад таны Android ТВ төхөөрөмжийн Bluetooth-г тохируулах болон алсын төхөөрөмжүүдийг илрүүлж, тэдгээртэй хослуулахыг зөвшөөрнө."</string>
+ <string name="permdesc_bluetoothAdmin" product="tv" msgid="1623992984547014588">"Аппад таны Android TV төхөөрөмжийн Bluetooth-г тохируулах болон алсын төхөөрөмжүүдийг илрүүлж, тэдгээртэй хослуулахыг зөвшөөрнө."</string>
<string name="permdesc_bluetoothAdmin" product="default" msgid="7381341743021234863">"Апп нь утасны дотоод блютүүтыг тохируулах боломжтой ба гадаад төхөөрөмжийг олох болон хос үүсгэх боломжтой."</string>
<string name="permlab_accessWimaxState" msgid="7029563339012437434">"WiMAX-д холбогдох болон салах"</string>
<string name="permdesc_accessWimaxState" msgid="5372734776802067708">"Апп нь WiMAX идэвхтэй эсэх болон холбогдсон 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 ТВ төхөөрөмжид холбогдож, үүнийг 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="permlab_bluetooth" msgid="586333280736937209">"Bluetooth төхөөрөмжтэй хос үүсгэх"</string>
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Апп нь таблет дээрх блютүүт тохиргоог харах боломжтой ба хос болох төхөөрөмжтэй холболтыг зөвшөөрөх болон хийх боломжтой."</string>
- <string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Аппад таны Android ТВ төхөөрөмж дээрх Bluetooth-н тохируулгыг харах болон хослуулсан төхөөрөмжүүдтэй холболт хийж, холболтыг баталгаажуулахыг зөвшөөрнө."</string>
+ <string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Аппад таны Android TV төхөөрөмж дээрх Bluetooth-н тохируулгыг харах болон хослуулсан төхөөрөмжүүдтэй холболт хийж, холболтыг баталгаажуулахыг зөвшөөрнө."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Апп нь утсан дээрх Bluetooth тохиргоог харах боломжтой ба хос болох төхөөрөмжтэй холболтыг зөвшөөрөх болон хийх боломжтой."</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Сонгосон NFC төлбөрийн үйлчилгээний мэдээлэл"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Бүртгүүлсэн төхөөрөмж болон маршрутын хүрэх цэг зэрэг сонгосон nfc төлбөрийн үйлчилгээний мэдээллийг авахыг аппад зөвшөөрдөг."</string>
@@ -673,10 +673,10 @@
<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 ТВ төхөөрөмжийг түгжиж эсвэл үүний бүх өгөгдлийг устгана."</string>
+ <string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"Дэлгэцийн түгжээг тайлахаар буруу оруулсан нууц үгийн тоог хянаж, нууц үгийг хэт олон удаа буруу оруулсан тохиолдолд таны Android TV төхөөрөмжийг түгжиж эсвэл үүний бүх өгөгдлийг устгана."</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 ТВ төхөөрөмжийг түгжиж эсвэл энэ хэрэглэгчийн бүх өгөгдлийг устгана."</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>
@@ -684,11 +684,11 @@
<string name="policydesc_forceLock" msgid="1008844760853899693">"Дэлгэц хэзээ яаж түгжихийг удирдах"</string>
<string name="policylab_wipeData" msgid="1359485247727537311">"Бүх датаг арилгах"</string>
<string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"Үйлдвэрийн дата утгыг өгсөнөөр таблетын дата шууд арилгагдана."</string>
- <string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"Таны Android ТВ төхөөрөмжийн өгөгдлийг танд анхааруулалгүйгээр үйлдвэрээс гарсан төлөвт шилжүүлэн устгана."</string>
+ <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="tv" msgid="2293713284515865200">"Энэ Android ТВ төхөөрөмж дээрх хэрэглэгчийн өгөгдлийг хэрэглэгчид анхааруулалгүйгээр устгана."</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">"Төхөрөөмжийн глобал проксиг тохируулах"</string>
<string name="policydesc_setGlobalProxy" msgid="7149665222705519604">"Бодлогыг ашиглах боломжтой үед төхөөрөмжийн олон улсын эрхийг тохируулах. Зөвхөн төхөөрөмж эзэмшигч нь олон улсын эрхийг тохируулах боломжтой."</string>
@@ -838,7 +838,7 @@
<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>
- <string name="lockscreen_missing_sim_message" product="tv" msgid="2582768023352171073">"Таны Android ТВ төхөөрөмжид SIM карт алга."</string>
+ <string name="lockscreen_missing_sim_message" product="tv" msgid="2582768023352171073">"Таны Android TV төхөөрөмжид SIM карт алга."</string>
<string name="lockscreen_missing_sim_message" product="default" msgid="1408695081255172556">"Утсанд SIM карт байхгүй."</string>
<string name="lockscreen_missing_sim_instructions" msgid="8473601862688263903">"SIM картыг оруулна уу."</string>
<string name="lockscreen_missing_sim_instructions_long" msgid="3664999892038416334">"SIM карт байхгүй эсвэл унших боломжгүй. SIM карт оруулна уу."</string>
@@ -861,13 +861,13 @@
<string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="3118353451602377380">"Та нууц үгээ <xliff:g id="NUMBER_0">%1$d</xliff:g> удаа буруу бичив. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> секундын дараа дахин оролдоно уу."</string>
<string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="2874278239714821984">"Та PIN кодоо <xliff:g id="NUMBER_0">%1$d</xliff:g> удаа буруу бичив. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> секундын дараа дахин оролдоно уу."</string>
<string name="lockscreen_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 ТВ төхөөрөмжийнхөө түгжээг тайлахын тулд 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 ТВ төхөөрөмжийнхөө түгжээг тайлахаар <xliff:g id="NUMBER_0">%1$d</xliff:g> удаа буруу оролдсон байна. <xliff:g id="NUMBER_1">%2$d</xliff:g> удаагийн амжилтгүй оролдлогын дараагаас таны Android ТВ төхөөрөмжийг үйлдвэрийн өгөгдмөл төлөвт шинэчлэх бөгөөд хэрэглэгчийн бүх өгөгдөл устах болно."</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 ТВ төхөөрөмжийнхөө түгжээг тайлахаар <xliff:g id="NUMBER">%d</xliff:g> удаа буруу оролдсон байна. Таны Android ТВ төхөөрөмжийг одоо үйлдвэрийн өгөгдмөл төлөвт шинэчилнэ."</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_forgot_pattern_button_text" msgid="8362442730606839031">"Хээг мартсан уу?"</string>
@@ -954,7 +954,7 @@
<string name="permdesc_readHistoryBookmarks" msgid="2323799501008967852">"Апп нь Хөтчийн зочилж байсан бүх URL-н түүх болон Хөтчийн бүх хавчуургыг унших боломжтой. Анхаар: Энэ зөвшөөрөл нь гуравдагч талын хөтөч эсвэл вебээр хөтөчлөх чадавхтай аппликейшнүүдэд ашиглагдахгүй байх боломжтой."</string>
<string name="permlab_writeHistoryBookmarks" msgid="6090259925187986937">"вэб хавчуурга болон түүхийг бичих"</string>
<string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="573341025292489065">"Апп нь таны таблет дээр хадгалагдсан Хөтчийн түүх эсвэл хавчуургыг өөрчлөх боломжтой. Энэ нь апп-д Хөтчийн датаг арилгах эсвэл өөрчлөх боломжийг олгоно. Анхаар: Энэ зөвшөөрөл нь гуравдагч талын хөтөч эсвэл вебээр хөтөчлөх чадвартай аппликейшнд ажиллахгүй байх боломжтой."</string>
- <string name="permdesc_writeHistoryBookmarks" product="tv" msgid="88642768580408561">"Аппад таны Android ТВ төхөөрөмжид хадгалсан Хөтчийн түүх эсвэл хавчуургыг өөрчлөхийг зөвшөөрнө. Энэ нь аппад Хөтчийн өгөгдлийг устгах эсвэл өөрчлөхийг зөвшөөрч болзошгүй. Санамж: энэ зөвшөөрөл нь гуравдагч талын хөтөч эсвэл вэб хөтчийн чадамжтай бусад аппад хэрэгжихгүй байж болзошгүй."</string>
+ <string name="permdesc_writeHistoryBookmarks" product="tv" msgid="88642768580408561">"Аппад таны Android TV төхөөрөмжид хадгалсан Хөтчийн түүх эсвэл хавчуургыг өөрчлөхийг зөвшөөрнө. Энэ нь аппад Хөтчийн өгөгдлийг устгах эсвэл өөрчлөхийг зөвшөөрч болзошгүй. Санамж: энэ зөвшөөрөл нь гуравдагч талын хөтөч эсвэл вэб хөтчийн чадамжтай бусад аппад хэрэгжихгүй байж болзошгүй."</string>
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="2245203087160913652">"Апп нь таны утсан дээр хадгалагдсан Хөтчийн түүх эсвэл хавчуургыг өөрчлөх боломжтой. Энэ нь апп-д Хөтчийн датаг арилгах эсвэл өөрчлөх боломжийг олгоно. Анхаар: Энэ зөвшөөрөл нь гуравдагч талын хөтөч эсвэл вебээр хөтөчлөх чадвартай аппликейшнд ажиллахгүй байх боломжтой."</string>
<string name="permlab_setAlarm" msgid="1158001610254173567">"сэрүүлэг тохируулах"</string>
<string name="permdesc_setAlarm" msgid="2185033720060109640">"Апп нь суулгагдсан сэрүүлэгний апп дээр сэрүүлэг тохируулах боломжтой. Зарим сэрүүлэгний апп нь энэ функцийг дэмжихгүй байж болзошгүй."</string>
@@ -1609,27 +1609,26 @@
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="3328686432962224215">"Та PIN кодоо <xliff:g id="NUMBER_0">%1$d</xliff:g> удаа буруу бичив. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> секундын дараа дахин оролдоно уу."</string>
<string name="kg_too_many_failed_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 ТВ төхөөрөмжийнхөө түгжээг тайлахаар <xliff:g id="NUMBER_0">%1$d</xliff:g> удаа буруу оролдсон байна. <xliff:g id="NUMBER_1">%2$d</xliff:g> удаагийн амжилтгүй оролдлогын дараагаас таны Android ТВ төхөөрөмжийг үйлдвэрийн өгөгдмөл төлөвт шинэчлэх бөгөөд хэрэглэгчийн бүх өгөгдөл устах болно."</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 ТВ төхөөрөмжийнхөө түгжээг тайлахаар <xliff:g id="NUMBER">%d</xliff:g> удаа буруу оролдсон байна. Таны Android ТВ төхөөрөмжийг одоо үйлдвэрийн өгөгдмөл төлөвт шинэчилнэ."</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_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 ТВ төхөөрөмжийнхөө түгжээг имэйл бүртгэлээрээ тайлах шаардлагатай болно.\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_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Устгах"</string>
- <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"<xliff:g id="PACKAGENAME">%1$s</xliff:g>-н дэлгэц дээрх үйлчилгээг эхлүүлдэг дэвсгэр нь цаашид R хийцийн ашиглах үеийн зөвшөөрөлгүй болно. go/r-bg-fgs-restriction-г үзэж, алдааны мэдээ илгээнэ үү."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Дууг санал болгосноос чанга болгож өсгөх үү?\n\nУрт хугацаанд чанга хөгжим сонсох нь таны сонсголыг муутгаж болно."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Хүртээмжийн товчлолыг ашиглах уу?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Товчлол асаалттай үед дууны түвшний хоёр товчлуурыг хамтад нь 3 секунд дарснаар хандалтын онцлогийг эхлүүлнэ."</string>
<string name="accessibility_shortcut_multiple_service_warning_title" msgid="8417489297036013065">"Хандалтын онцлогуудыг асаах уу?"</string>
- <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"Дууны түвшний түлхүүрийг хэдэн секундийн турш зэрэг дарах нь хандалтын онцлогуудыг асаадаг. Энэ нь таны төхөөрөмжийн ажиллах зарчмыг өөрчилж болзошгүй.\n\nОдоогийн онцлогууд:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nТа сонгосон онцлогуудыг Тохиргоо &gt; Хандалт хэсэгт өөрчлөх боломжтой."</string>
+ <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"Дууны түвшний түлхүүрийг хэдэн секундийн турш зэрэг дарснаар хандалтын онцлогууд асна. Энэ нь таны төхөөрөмжийн ажиллах зарчмыг өөрчилж болзошгүй.\n\nОдоогийн онцлогууд:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nТа сонгосон онцлогуудыг Тохиргоо &gt; Хандалт хэсэгт өөрчлөх боломжтой."</string>
<string name="accessibility_shortcut_multiple_service_list" msgid="6935581470716541531">" • <xliff:g id="SERVICE">%1$s</xliff:g>\n"</string>
<string name="accessibility_shortcut_single_service_warning_title" msgid="2819109500943271385">"<xliff:g id="SERVICE">%1$s</xliff:g>-г асаах уу?"</string>
<string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Дууны түвшний түлхүүрийг хэдэн секундийн турш зэрэг дарах нь хандалтын онцлог болох <xliff:g id="SERVICE">%1$s</xliff:g>-г асаадаг. Энэ нь таны төхөөрөмжийн ажиллах зарчмыг өөрчилж болзошгүй.\n\nТа Тохиргоо &gt; Хандалт хэсэгт энэ товчлолыг өөр онцлогт оноож өөрчлөх боломжтой."</string>
<string name="accessibility_shortcut_on" msgid="5463618449556111344">"Асаах"</string>
- <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Битгий асаа"</string>
+ <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Бүү асаа"</string>
<string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ИДЭВХТЭЙ"</string>
<string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"ИДЭВХГҮЙ"</string>
<string name="accessibility_enable_service_title" msgid="3931558336268541484">"<xliff:g id="SERVICE">%1$s</xliff:g>-д таны төхөөрөмжийг бүрэн хянахыг зөвшөөрөх үү?"</string>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index f2bec3160830..e5d19533d27d 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -1619,7 +1619,6 @@
<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="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> कडून बॅकग्राउंडने फोरग्राउंडमध्ये सुरू केलेल्या सेवेला भविष्यातील आर बिल्डमध्ये वापर करते वेळची परवानगी नसेल. कृपया go/r-bg-fgs-restriction पहा आणि बगची तक्रार नोंदवा."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"शिफारस केलेल्‍या पातळीच्या वर आवाज वाढवायचा?\n\nउच्च आवाजात दीर्घ काळ ऐकण्‍याने आपल्‍या श्रवणशक्तीची हानी होऊ शकते."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"प्रवेशयोग्यता शॉर्टकट वापरायचा?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"शॉर्टकट सुरू असताना, दोन्ही व्‍हॉल्‍यूम बटणे तीन सेकंदांसाठी दाबून ठेवल्याने अ‍ॅक्सेसिबिलिटी वैशिष्ट्य सुरू होईल."</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index fd6025ec0879..6d2d060d6451 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -1619,7 +1619,6 @@
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"Anda telah tersilap lukis corak buka kunci sebanyak <xliff:g id="NUMBER_0">%1$d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi percubaan yang tidak berjaya, anda akan diminta membuka kunci telefon anda menggunakan log masuk Google anda.\n\n Cuba lagi dalam <xliff:g id="NUMBER_2">%3$d</xliff:g> saat."</string>
<string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Alih keluar"</string>
- <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Perkhidmatan latar depan dimulakan latar belakang daripada <xliff:g id="PACKAGENAME">%1$s</xliff:g> tidak akan mempunyai kebenaran semasa-dalam-penggunaan dalam binaan R akan datang. Sila lihat go/r-bg-fgs-restriction dan failkan laporan pepijat."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Naikkan kelantangan melebihi paras yang disyokorkan?\n\nMendengar pada kelantangan yang tinggi untuk tempoh yang lama boleh merosakkan pendengaran anda."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Gunakan Pintasan Kebolehaksesan?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Apabila pintasan dihidupkan, tindakan menekan kedua-dua butang kelantangan selama 3 saat akan memulakan ciri kebolehaksesan."</string>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index d910fc03e165..2363860968da 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -142,7 +142,7 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"WiFi ခေါ်ဆိုမှု"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
- <string name="wifi_calling_off_summary" msgid="5626710010766902560">"ပိတ်ထားရသည်"</string>
+ <string name="wifi_calling_off_summary" msgid="5626710010766902560">"ပိတ်ထားသည်"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Wi-Fi သုံး၍ ခေါ်ဆိုသည်"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"မိုဘိုင်းကွန်ရက်သုံး၍ ခေါ်ဆိုသည်"</string>
<string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"ကြိုးမဲ့အင်တာနက် သာလျှင်"</string>
@@ -1619,7 +1619,6 @@
<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="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> တွင် မှ စတင်သည့် foreground ဝန်ဆောင်မှုသည် နောက်ထွက်ရှိမည့် R စုပေါင်းစပ်ပေါင်း ပရိုဂရမ်များတွင် အသုံးပြုစဉ်အတွင်း ခွင့်ပြုချက် ရရှိမည်မဟုတ်ပါ။ go/r-bg-fgs-ကန့်သတ်ချက်များကို ကြည့်ပြီး အမှားသတင်းပို့ချက်တစ်ခု တင်သွင်းပါ။"</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"အသံကို အကြံပြုထားသည့် ပမာဏထက် မြှင့်ပေးရမလား?\n\nအသံကို မြင့်သည့် အဆင့်မှာ ကြာရှည်စွာ နားထောင်ခြင်းက သင်၏ နားကို ထိခိုက်စေနိုင်သည်။"</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"အများသုံးစွဲနိုင်မှု ဖြတ်လမ်းလင့်ခ်ကို အသုံးပြုလိုပါသလား။"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"ဖြတ်လမ်းလင့်ခ်ကို ဖွင့်ထားစဉ် အသံထိန်းခလုတ် နှစ်ခုစလုံးကို ၃ စက္ကန့်ခန့် ဖိထားခြင်းဖြင့် အများသုံးစွဲနိုင်မှုဆိုင်ရာ ဝန်ဆောင်မှုကို ဖွင့်နိုင်သည်။"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 949c7f23e6e7..1d15398f8539 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -1619,7 +1619,6 @@
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"Du har tegnet opplåsningsmønsteret feil <xliff:g id="NUMBER_0">%1$d</xliff:g> ganger. Etter ytterligere <xliff:g id="NUMBER_1">%2$d</xliff:g> gale forsøk, blir du bedt om å låse opp telefonen via en e-postkonto.\n\n Prøv på nytt om <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunder."</string>
<string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Fjern"</string>
- <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Forgrunnstjenesten fra <xliff:g id="PACKAGENAME">%1$s</xliff:g>, som ble startet i bakgrunnen, kommer ikke til å ha tillatelser mens den er i bruk i fremtidige R-delversjoner. Les go/r-bg-fgs-restriction og send inn en feilrapport."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Vil du øke volumet til over anbefalt nivå?\n\nHvis du hører på et høyt volum over lengre perioder, kan det skade hørselen din."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Vil du bruke tilgjengelighetssnarveien?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Når snarveien er på, starter en tilgjengelighetsfunksjon når du trykker inn begge volumknappene i tre sekunder."</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 25cc45b9e964..e86867689fa4 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -175,7 +175,7 @@
<string name="contentServiceTooManyDeletesNotificationDesc" msgid="4562226280528716090">"अति धेरै <xliff:g id="CONTENT_TYPE">%s</xliff:g> मेटाउने प्रयास गरियो।"</string>
<string name="low_memory" product="tablet" msgid="5557552311566179924">"ट्याब्लेट भण्डारण खाली छैन! ठाउँ खाली गर्नको लागि केही फाइलहरू मेटाउनुहोस्।"</string>
<string name="low_memory" product="watch" msgid="3479447988234030194">"भण्डारण भरिएको छ हेर्नुहोस्। ठाउँ खाली गर्न केही फाइलहरू मेटाउनुहोस्।"</string>
- <string name="low_memory" product="tv" msgid="6663680413790323318">"Android TV यन्त्रको भण्डारण भरिएको छ। ठाउँ खाली गर्न केही फाइलहरू मेट्नुहोस्।"</string>
+ <string name="low_memory" product="tv" msgid="6663680413790323318">"Android टिभी यन्त्रको भण्डारण भरिएको छ। ठाउँ खाली गर्न केही फाइलहरू मेट्नुहोस्।"</string>
<string name="low_memory" product="default" msgid="2539532364144025569">"फोन भण्डारण भरिएको छ! ठाउँ खाली गर्नको लागि केही फाइलहरू मेटाउनुहोस्।"</string>
<plurals name="ssl_ca_cert_warning" formatted="false" msgid="2288194355006173029">
<item quantity="other">प्रमाणपत्रका अख्तियारीहरूलाई स्थापना गरियो</item>
@@ -206,7 +206,7 @@
<string name="personal_apps_suspended_turn_profile_on" msgid="2758012869627513689">"सक्रिय गर्नुहोस्"</string>
<string name="me" msgid="6207584824693813140">"मलाई"</string>
<string name="power_dialog" product="tablet" msgid="8333207765671417261">"ट्याब्लेट विकल्पहरू"</string>
- <string name="power_dialog" product="tv" msgid="7792839006640933763">"Android TV सम्बन्धी विकल्पहरू"</string>
+ <string name="power_dialog" product="tv" msgid="7792839006640933763">"Android टिभी सम्बन्धी विकल्पहरू"</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>
@@ -224,7 +224,7 @@
<string name="reboot_to_reset_message" msgid="3347690497972074356">"पुनःसुरु हुँदै ..."</string>
<string name="shutdown_progress" msgid="5017145516412657345">"बन्द गर्दै..."</string>
<string name="shutdown_confirm" product="tablet" msgid="2872769463279602432">"तपाईँको ट्याब्लेट बन्द हुने छ।"</string>
- <string name="shutdown_confirm" product="tv" msgid="7975942887313518330">"तपाईंको Android TV यन्त्र बन्द हुने छ।"</string>
+ <string name="shutdown_confirm" product="tv" msgid="7975942887313518330">"तपाईंको Android टिभी यन्त्र बन्द हुने छ।"</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>
@@ -233,7 +233,7 @@
<string name="recent_tasks_title" msgid="8183172372995396653">"नयाँ"</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="tv" msgid="3871763739487450369">"Android टिभी सम्बन्धी विकल्पहरू"</string>
<string name="global_actions" product="default" msgid="6410072189971495460">"फोन विकल्पहरू"</string>
<string name="global_action_lock" msgid="6949357274257655383">"स्क्रिन बन्द"</string>
<string name="global_action_power_off" msgid="4404936470711393203">"बन्द गर्नुहोस्"</string>
@@ -357,7 +357,7 @@
<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="tv" msgid="3054753345758011986">"यस अनुप्रयोगले तपाईंको Android TV यन्त्रमा भण्डार गरिएका सबै SMS.(पाठ) सन्देशहरू पढ्न सक्छ।"</string>
+ <string name="permdesc_readSms" product="tv" msgid="3054753345758011986">"यस अनुप्रयोगले तपाईंको Android टिभी यन्त्रमा भण्डार गरिएका सबै 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>
@@ -379,7 +379,7 @@
<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="tv" msgid="6800526387664131321">"एपलाई आफ्ना केही अंशहरू मेमोरीमा स्थायी रूपमा राख्ने अनुमति दिन्छ। यसले गर्दा अन्य अनुप्रयोगहरूका लागि मेमोरीको अभाव हुन सक्ने भएकाले तपाईंको Android टिभी यन्त्र सुस्त हुन सक्छ।"</string>
<string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"एपलाई मेमोरीमा आफैंको निरन्तरको अंश बनाउन अनुमति दिन्छ। यसले फोनलाई ढिला बनाएर अन्य एपहरूमा मेमोरी SIMित गर्न सक्दछन्।"</string>
<string name="permlab_foregroundService" msgid="1768855976818467491">"अग्रभूमिको सेवा सञ्चालन गर्नुहोस्"</string>
<string name="permdesc_foregroundService" msgid="8720071450020922795">"एपलाई अग्रभूमिका सेवाहरू प्रयोग गर्ने अनुमति दिन्छ।"</string>
@@ -389,35 +389,35 @@
<string name="permdesc_writeSettings" msgid="8293047411196067188">"प्रणालीका सेटिङ डेटालाई परिवर्तन गर्नको लागि एपलाई अनुमति दिन्छ। खराब एपहरूले सायद तपाईँको प्रणालीको कन्फिगरेसनलाई क्षति पुर्‍याउन सक्छन्।"</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="tv" msgid="4900842256047614307">"एपलाई प्रणाली बुट हुने बित्तिकै स्वत: सुरु हुने अनुमति दिन्छ। यसो गर्दा एप सधैँ चलिरहने भएकाले तपाईंको Android टिभी यन्त्र सुरु हुन बढी समय लाग्नुका साथै यन्त्रको समग्र कार्यसम्पादन सुस्त हुन सक्छ।"</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">"एपलाई प्रसारण समाप्त भइसकेपछि पनि रहिरहने स्टिकी प्रसारणहरू पठाउने अनुमति दिन्छ। यो सुविधाको अत्यधिक प्रयोगले धेरै मेमोरी प्रयोग हुने भएकाले तपाईंको Android TV यन्त्र सुस्त वा अस्थिर हुन सक्छ।"</string>
+ <string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"एपलाई प्रसारण समाप्त भइसकेपछि पनि रहिरहने स्टिकी प्रसारणहरू पठाउने अनुमति दिन्छ। यो सुविधाको अत्यधिक प्रयोगले धेरै मेमोरी प्रयोग हुने भएकाले तपाईंको Android टिभी यन्त्र सुस्त वा अस्थिर हुन सक्छ।"</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="tv" msgid="8400138591135554789">"एपलाई तपाईंको Android टिभी यन्त्रमा भण्डारण गरिएका सम्पर्क ठेगानासम्बन्धी डेटा पढ्न अनुमति दिन्छ। एपहरूले सम्पर्क ठेगानाहरू बनाउने तपाईंको Android टिभी यन्त्रमा भण्डार गरिएका खाताहरूमाथि पनि पहुँच प्राप्त गर्ने छन्। यसमा तपाईंले स्थापना गरेका एपहरूले बनाएका खाताहरू पर्न सक्छन्। यस अनुमतिले अनुप्रयोगहरूलाई तपाईंको सम्पर्क ठेगानासम्बन्धी डेटा सुरक्षित गर्न दिने भएकाले हानिकारक एपहरूले तपाईंलाई थाहै नदिइकन सम्पर्क ठेगानासम्बन्धी डेटा आदान प्रदान गर्न सक्छन्।"</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="tv" msgid="6488872735379978935">"एपलाई तपाईंको Android TV यन्त्रमा भण्डारण गरिएका सम्पर्क ठेगानासम्बन्धी डेटा परिमार्जन गर्न अनुमति दिन्छ। यो अनुमतिले एपलाई सम्पर्क ठेगानासम्बन्धी डेटा मेटाउन अनुमति दिन्छ।"</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"एपलाई तपाईंको Android टिभी यन्त्रमा भण्डारण गरिएका सम्पर्क ठेगानासम्बन्धी डेटा परिमार्जन गर्न अनुमति दिन्छ। यो अनुमतिले एपलाई सम्पर्क ठेगानासम्बन्धी डेटा मेटाउन अनुमति दिन्छ।"</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="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>
+ <string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"एपलाई तपाईंको Android टिभी यन्त्रको आगमन र बहिर्गमन कलसम्बन्धी डेटासहित कल लग परिमार्जन गर्ने अनुमति दिन्छ। हानिकारक एपहरूले यसलाई तपाईंको कल लग मेटाउन वा परिमार्जन गर्न प्रयोग गर्न सक्छन्।"</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"एपलाई तपाईंको फोनको आउने र बाहिर जाने कलहरूको बारेको डेटा सहित कल लग परिमार्जन गर्न अनुमति दिन्छ। खराब एपहरूले यसलाई तपाईंको कल लग मेटाउन वा परिमार्जन गर्न प्रयोग गर्न सक्दछ।"</string>
<string name="permlab_bodySensors" msgid="3411035315357380862">"शरीरका सेन्सरहरूमा पहुँच गराउनुहोस् (जस्तै हृदय धड्कन निगरानीहरू)"</string>
<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 टिभी यन्त्रमा भण्डार गरिएका पात्रोसम्बन्धी सबै कार्यक्रमहरू पढ्न र तपाईंको पात्रोको डेटा आदान प्रदान वा सुरक्षित गर्न सक्छ।"</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="tv" msgid="951246749004952706">"यस अनुप्रयोगले तपाईंको Android टिभी यन्त्रमा पात्रोका कार्यक्रमहरू थप्न, हटाउन वा परिवर्तन गर्न सक्छ। यस अनुप्रयोगले पात्रोका मालिकहरूले पठाएको जस्तै देखिने सन्देशहरू पठाउन वा कार्यक्रमका मालिकहरूलाई सूचित नगरिकन कार्यक्रमहरू परिवर्तन गर्न सक्छ।"</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>
@@ -462,15 +462,15 @@
<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="tv" msgid="2856941418123343518">"आफ्नो Android टिभी यन्त्रलाई शयन अवस्थामा जान नदिनुहोस्"</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="tv" msgid="2329298966735118796">"एपलाई तपाईंको Android TV यन्त्रलाई शयन अवस्थामा जानबाट रोक्ने अनुमति दिन्छ।"</string>
+ <string name="permdesc_wakeLock" product="tv" msgid="2329298966735118796">"एपलाई तपाईंको Android टिभी यन्त्रलाई शयन अवस्थामा जानबाट रोक्ने अनुमति दिन्छ।"</string>
<string name="permdesc_wakeLock" product="default" msgid="3689523792074007163">"फोनलाई निस्क्रिय हुनबाट रोक्नको लागि एपलाई अनुमति दिन्छ।"</string>
<string name="permlab_transmitIr" msgid="8077196086358004010">"infrared ट्रान्समिट गर्नुहोस्"</string>
<string name="permdesc_transmitIr" product="tablet" msgid="5884738958581810253">"ट्याबलेटको infrared transmitter प्रयोगको लागि एप अनुमति दिन्छ।"</string>
- <string name="permdesc_transmitIr" product="tv" msgid="3278506969529173281">"एपलाई तपाईंको Android TV यन्त्रको इन्फ्रारेड ट्रान्समिटर प्रयोग गर्ने अनुमति दिन्छ।"</string>
+ <string name="permdesc_transmitIr" product="tv" msgid="3278506969529173281">"एपलाई तपाईंको Android टिभी यन्त्रको इन्फ्रारेड ट्रान्समिटर प्रयोग गर्ने अनुमति दिन्छ।"</string>
<string name="permdesc_transmitIr" product="default" msgid="8484193849295581808">"फोनको infrared transmitter प्रयोगको लागि एप अनुमति दिन्छ।"</string>
<string name="permlab_setWallpaper" msgid="6959514622698794511">"वालपेपर सेट गर्नुहोस्"</string>
<string name="permdesc_setWallpaper" msgid="2973996714129021397">"एपलाई प्रणाली वालपेपर सेट गर्न अनुमति दिन्छ।"</string>
@@ -478,11 +478,11 @@
<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>
+ <string name="permdesc_setTimeZone" product="tv" msgid="9069045914174455938">"एपलाई तपाईंको Android टिभी यन्त्रको समय क्षेत्र परिवर्तन गर्ने अनुमति दिन्छ।"</string>
<string name="permdesc_setTimeZone" product="default" msgid="4611828585759488256">"एपलाई फोनको समय क्षेत्र परिवर्तन गर्न अनुमति दिन्छ।"</string>
<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="tv" msgid="437604680436540822">"एपलाई तपाईंको Android टिभी यन्त्रले चिनेका खाताहरूको सूची प्राप्त गर्ने अनुमति दिन्छ। उक्त सूचीमा तपाईंले स्थापना गर्नुभएका एपहरूले बनाएका कुनै पनि खाताहरू पर्न सक्छन्।"</string>
<string name="permdesc_getAccounts" product="default" msgid="2491273043569751867">"फोनलाई थाहा भएका खाताहरूको सूची प्राप्त गर्न एपलाई अनुमति दिन्छ। यसले तपाईँले स्थापना गर्नु भएका अनुप्रयोगहरूबाट सृजित कुनै खाताहरू समावेश हुन सक्छ।"</string>
<string name="permlab_accessNetworkState" msgid="2349126720783633918">"नेटवर्क जडानहरू हेर्नहोस्"</string>
<string name="permdesc_accessNetworkState" msgid="4394564702881662849">"एपलाई नेटवर्क जडानहरू जस्तै कुन नेटवर्कहरू अवस्थित हुन्छन् र जडित छन् जसले हेर्नलाई अनुमति दिन्छ।"</string>
@@ -498,21 +498,21 @@
<string name="permdesc_changeWifiState" msgid="7170350070554505384">"एपलाई Wi-Fi पहुँच बिन्दुबाट जडान गर्न र विच्छेदन गर्न र Wi-Fi नेटवर्कहरूको लागि उपकरण कन्फिगरेसनमा परिवर्तनहरू गर्न अनुमति दिन्छ।"</string>
<string name="permlab_changeWifiMulticastState" msgid="285626875870754696">"Wi-Fi Multicast स्विकृतिलाई अनुमति दिनुहोस्"</string>
<string name="permdesc_changeWifiMulticastState" product="tablet" msgid="191079868596433554">"एपलाई मल्टिकाष्ट ठेगानाहरू प्रयोग गरेर Wi-Fi नेटवर्कमा पठाइएको प्याकेटहरू प्राप्त गर्न अनुमति दिन्छ, केवल तपाईंको ट्याब्लेट मात्र होइन। यसले गैर-मल्टिकाष्ट मोड भन्दा बढी उर्जा प्रयोग गर्दछ।"</string>
- <string name="permdesc_changeWifiMulticastState" product="tv" msgid="1336952358450652595">"एपलाई मल्टिकास्ट ठेगानाहरू प्रयोग गरी तपाईंको Android TV यन्त्रमा मात्र नभई कुनै Wi-Fi नेटवर्कमा जोडिएका सबै यन्त्रहरूमा पठाइएका प्याकेटहरू प्राप्त गर्ने अनुमति दिन्छ। यसले गैर मल्टिकास्ट मोडभन्दा बढी पावर खपत गर्छ।"</string>
+ <string name="permdesc_changeWifiMulticastState" product="tv" msgid="1336952358450652595">"एपलाई मल्टिकास्ट ठेगानाहरू प्रयोग गरी तपाईंको Android टिभी यन्त्रमा मात्र नभई कुनै Wi-Fi नेटवर्कमा जोडिएका सबै यन्त्रहरूमा पठाइएका प्याकेटहरू प्राप्त गर्ने अनुमति दिन्छ। यसले गैर मल्टिकास्ट मोडभन्दा बढी पावर खपत गर्छ।"</string>
<string name="permdesc_changeWifiMulticastState" product="default" msgid="8296627590220222740">"तपाईँको फोन मात्र होइन, मल्टिकास्ट ठेगानाहरूको प्रयोग गरे Wi-Fi नेटवर्कका सबै उपकरणहरूमा पठाइएका प्याकेटहरू प्राप्त गर्न एपलाई अनुमति दिन्छ। यसले गैर-मल्टिकास्ट मोडभन्दा बढी उर्जा प्रयोग गर्छ।"</string>
<string name="permlab_bluetoothAdmin" msgid="6490373569441946064">"ब्लुटुथ सेटिङहरूमा पहुँच गर्नुहोस्"</string>
<string name="permdesc_bluetoothAdmin" product="tablet" msgid="5370837055438574863">"स्थानीय ब्लुटुथ ट्याब्लेटलाई कन्फिगर गर्नको लागि र टाढाका उपकरणहरूलाई पत्ता लगाउन र जोड्नको लागि एपलाई अनुमति दिन्छ।"</string>
- <string name="permdesc_bluetoothAdmin" product="tv" msgid="1623992984547014588">"एपलाई तपाईंको Android TV यन्त्रको ब्लुटुथ कन्फिगर गर्ने तथा टाढा रहेका यन्त्रहरू पत्ता लगाई ती यन्त्रहरूसँग जोडा बनाउने अनुमति दिन्छ।"</string>
+ <string name="permdesc_bluetoothAdmin" product="tv" msgid="1623992984547014588">"एपलाई तपाईंको Android टिभी यन्त्रको ब्लुटुथ कन्फिगर गर्ने तथा टाढा रहेका यन्त्रहरू पत्ता लगाई ती यन्त्रहरूसँग जोडा बनाउने अनुमति दिन्छ।"</string>
<string name="permdesc_bluetoothAdmin" product="default" msgid="7381341743021234863">"एपलाई स्थानीय ब्लुटुथ फोन कन्फिगर गर्न र टाढाका उपकरणहरूसँग खोज गर्न र जोडी गर्न अनुमति दिन्छ।"</string>
<string name="permlab_accessWimaxState" msgid="7029563339012437434">"WiMAXसँग जोड्नुहोस् वा छुटाउनुहोस्"</string>
<string name="permdesc_accessWimaxState" msgid="5372734776802067708">"एपलाई वाइम्याक्स सक्षम छ कि छैन र जडान भएको कुनै पनि वाइम्याक्स नेटवर्कहरूको बारेमा जानकारी निर्धारिण गर्न अनुमति दिन्छ।"</string>
<string name="permlab_changeWimaxState" msgid="6223305780806267462">"वाइम्याक्स अवस्था परिवर्तन गर्नुहोस्"</string>
<string name="permdesc_changeWimaxState" product="tablet" msgid="4011097664859480108">"एपलाई वाइम्याक्स नेटवर्कहरूबाट ट्याब्लेट जडान गर्न र ट्याब्लेट विच्छेदन गर्न अनुमति दिन्छ।"</string>
- <string name="permdesc_changeWimaxState" product="tv" msgid="5373274458799425276">"एपलाई तपाईंको Android TV यन्त्र WiMAX नेटवर्कहरूमा जोड्ने वा ती नेटवर्कहरूबाट विच्छेद गर्ने अनुमति दिन्छ।"</string>
+ <string name="permdesc_changeWimaxState" product="tv" msgid="5373274458799425276">"एपलाई तपाईंको Android टिभी यन्त्र WiMAX नेटवर्कहरूमा जोड्ने वा ती नेटवर्कहरूबाट विच्छेद गर्ने अनुमति दिन्छ।"</string>
<string name="permdesc_changeWimaxState" product="default" msgid="1551666203780202101">"वाइम्याक्स नेटवर्कहरूसँग फोन जोड्न र छुटाउन एपलाई अनुमति दिन्छ।"</string>
<string name="permlab_bluetooth" msgid="586333280736937209">"ब्लुटुथ उपकरणहरूसँग जोडी मिलाउनुहोस्"</string>
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"ट्याब्लेटमा ब्लुटुथको कन्फिगुरेसनलाई हेर्न र बनाउन र जोडी उपकरणहरूसँग जडानहरूलाई स्वीकार गर्न एपलाई अनुमति दिन्छ।"</string>
- <string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"एपलाई तपाईंको Android TV यन्त्रको ब्लुटुथको कन्फिगुरेसन हेर्ने तथा जोडा बनाइएका यन्त्रहरूसँग जोडिने वा ती यन्त्रहरूले पठाएका जोडिने अनुरोध स्वीकार्ने अनुमति दिन्छ।"</string>
+ <string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"एपलाई तपाईंको Android टिभी यन्त्रको ब्लुटुथको कन्फिगुरेसन हेर्ने तथा जोडा बनाइएका यन्त्रहरूसँग जोडिने वा ती यन्त्रहरूले पठाएका जोडिने अनुरोध स्वीकार्ने अनुमति दिन्छ।"</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"एपलाई फोनमा ब्लुटुथको कन्फिगरेसन हेर्न र जोडी भएका उपकरणहरूसँग जडानहरू बनाउन र स्वीकार गर्न अनुमति दिन्छ।"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"NFC भुक्तानी सेवासम्बन्धी रुचाइएको जानकारी"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"यसले एपलाई दर्ता गरिएका सहायता तथा मार्गको गन्तव्य जस्ता रुचाइएका NFC भुक्तानी सेवासम्बन्धी जानकारी प्राप्त गर्न दिन्छ।"</string>
@@ -673,10 +673,10 @@
<string name="policydesc_limitPassword" msgid="4105491021115793793">"स्क्रिन लक पासवर्ड र PIN हरूमा अनुमति दिइएको लम्बाइ र वर्णहरूको नियन्त्रण गर्नुहोस्।"</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 यन्त्र लक गर्नुहोस् वा यन्त्रमा भएको सम्पूर्ण डेटा मेटाउनुहोस्।"</string>
+ <string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"स्क्रिन अनलक गर्दा गलत पासवर्ड टाइप गरेको सङ्ख्या निरीक्षण गर्नुहोस्, र धेरै पटक गलत पासवर्डहरू टाइप गरिएको खण्डमा आफ्नो Android टिभी यन्त्र लक गर्नुहोस् वा यन्त्रमा भएको सम्पूर्ण डेटा मेटाउनुहोस्।"</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 टिभी यन्त्र लक गर्नुहोस् वा यो प्रयोगकर्ताको सम्पूर्ण डेटा मेटाउनुहोस्।"</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>
@@ -684,11 +684,11 @@
<string name="policydesc_forceLock" msgid="1008844760853899693">"कसरी र कहिले स्क्रिन लक गर्ने नियन्त्रण गर्नुहोस्।"</string>
<string name="policylab_wipeData" msgid="1359485247727537311">"सबै डेटा मेट्नुहोस्"</string>
<string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"एउटा फ्याक्ट्रि डेटा रिसेट गरेर चेतावनी नआउँदै ट्याबल्टको डेटा मेट्नुहोस्।"</string>
- <string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"फ्याक्ट्री डेटा रिसेट गरेर चेतावनी नदिइकन आफ्नो Android TV यन्त्रको डेटा मेटाउनुहोस्।"</string>
+ <string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"फ्याक्ट्री डेटा रिसेट गरेर चेतावनी नदिइकन आफ्नो Android टिभी यन्त्रको डेटा मेटाउनुहोस्।"</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="tv" msgid="2293713284515865200">"यो Android TV यन्त्रमा भएको यस प्रयोगकर्ताको डेटा चेतावनी नदिइकन मेटाउनुहोस्।"</string>
+ <string name="policydesc_wipeData_secondaryUser" product="tv" msgid="2293713284515865200">"यो Android टिभी यन्त्रमा भएको यस प्रयोगकर्ताको डेटा चेतावनी नदिइकन मेटाउनुहोस्।"</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>
@@ -838,7 +838,7 @@
<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>
- <string name="lockscreen_missing_sim_message" product="tv" msgid="2582768023352171073">"तपाईंको Android TV यन्त्रमा SIM कार्ड छैन।"</string>
+ <string name="lockscreen_missing_sim_message" product="tv" msgid="2582768023352171073">"तपाईंको Android टिभी यन्त्रमा SIM कार्ड छैन।"</string>
<string name="lockscreen_missing_sim_message" product="default" msgid="1408695081255172556">"फोनमा SIM कार्ड छैन।"</string>
<string name="lockscreen_missing_sim_instructions" msgid="8473601862688263903">"SIM कार्ड घुसाउनुहोस्"</string>
<string name="lockscreen_missing_sim_instructions_long" msgid="3664999892038416334">"SIM कार्ड छैन वा पढ्न मिल्दैन। SIM कार्ड हाल्नुहोस्।"</string>
@@ -861,13 +861,13 @@
<string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="3118353451602377380">"तपाईंले गलत तरिकाले आफ्नो पासवर्ड <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक टाइप गर्नुभयो। \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> सेकेन्डमा फेरि प्रयास गर्नुहोस्।"</string>
<string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="2874278239714821984">"तपाईँले गलत तरिकाले तपाईँको PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक टाइप गर्नु भएको छ। \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> सेकेन्डमा फेरि प्रयास गर्नुहोस्।"</string>
<string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="3069635524964070596">"तपाईँले तपाईँको अनलक ढाँचा गलत तरिकाले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक खिच्नु भएको छ। पछि <xliff:g id="NUMBER_1">%2$d</xliff:g> थप असफल कोसिसहरू, तपाईँको Google साइन इन प्रयोग गरी तपाईँको ट्याब्लेट अनलक गर्न भनिने छ।\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकेन्डमा फरि प्रयास गर्नुहोस्।"</string>
- <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="6399092175942158529">"तपाईंले आफ्नो अनलक शैली <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक गलत तरिकाले कोर्नुभएको छ। थप <xliff:g id="NUMBER_1">%2$d</xliff:g> प्रयासहरू असफल भएपछि तपाईंलाई आफ्नो Google खाता मार्फत साइन इन गरेर आफ्नो Android TV यन्त्र अनलक गर्न अनुरोध गरिनेछ।\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकेन्डपछि फेरि प्रयास गर्नुहोस्।"</string>
+ <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="6399092175942158529">"तपाईंले आफ्नो अनलक शैली <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक गलत तरिकाले कोर्नुभएको छ। थप <xliff:g id="NUMBER_1">%2$d</xliff:g> प्रयासहरू असफल भएपछि तपाईंलाई आफ्नो Google खाता मार्फत साइन इन गरेर आफ्नो Android टिभी यन्त्र अनलक गर्न अनुरोध गरिनेछ।\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकेन्डपछि फेरि प्रयास गर्नुहोस्।"</string>
<string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="5691623136957148335">"तपाईँले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक गलत तरिकाले तपाईँको अनलक ढाँचालाई कोर्नु भएको छ। पछि <xliff:g id="NUMBER_1">%2$d</xliff:g> अरू धेरै असफल कोसिसहरूपछि, तपाईँलाई तपाईँको फोन Google साइन इन प्रयोग गरेर अनलक गर्नको लागि सोधिने छ। \n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकेन्डमा पुनः प्रयास गर्नुहोस्।"</string>
<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="tv" msgid="4275591249631864248">"तपाईंले आफ्नो Android टिभी यन्त्र <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक गलत तरिकाले अनलक गर्ने प्रयास गर्नुभएको छ। थप <xliff:g id="NUMBER_1">%2$d</xliff:g> प्रयासहरू असफल भएपछि तपाईंको Android टिभी यन्त्रलाई रिसेट गरेर पूर्वनिर्धारित फ्याक्ट्री सेटिङ लागू गरिने छ र प्रयोगकर्ताको सम्पूर्ण डेटा गुम्ने छ।"</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 टिभी यन्त्र <xliff:g id="NUMBER">%d</xliff:g> पटक गलत तरिकाले अनलक गर्ने प्रयास गर्नुभएको छ। अब तपाईंको Android टिभी यन्त्रलाई रिसेट गरेर पूर्वनिर्धारित फ्याक्ट्री सेटिङ लागू गरिनेछ।"</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_forgot_pattern_button_text" msgid="8362442730606839031">"ढाँचा बिर्सनु भयो?"</string>
@@ -954,7 +954,7 @@
<string name="permdesc_readHistoryBookmarks" msgid="2323799501008967852">"ब्राउजरले भ्रमण गरेको सबै URL हरूको इतिहास र ब्राउजरका सबै बुकमार्कहरू पढ्नको लागि एपलाई अनुमति दिन्छ। नोट: यो अनुमतिलाई तेस्रो पक्ष ब्राउजरहरूद्वारा वा वेब ब्राउज गर्ने क्षमताद्वारा बलपूर्वक गराउन सकिँदैन।"</string>
<string name="permlab_writeHistoryBookmarks" msgid="6090259925187986937">"वेब बुकमार्कहरू र इतिहास लेख्नुहोस्"</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="tv" msgid="88642768580408561">"एपलाई तपाईंको Android टिभी यन्त्रमा भण्डार गरिएका ब्राउजरको इतिहास र पुस्तक चिन्हहरू परिमार्जन गर्ने अनुमति दिन्छ। यसले एपलाई ब्राउजरको डेटा मेटाउने वा परिमार्जन गर्ने अनुमति दिन सक्छ। ध्यान दिनुहोस्: तेस्रो पक्षीय ब्राउजर वा वेब ब्राउज गर्ने सुविधा प्रदान गर्ने अन्य एपहरूले यो अनुमति लागू गर्न सक्दैनन्।"</string>
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="2245203087160913652">"तपाईँको फोनमा भण्डारण भएको ब्राउजरको इतिहास वा बुकमार्कहरू परिवर्तन गर्नको लागि एपलाई अनुमति दिन्छ। यसले सायद ब्राउजर डेटालाई मेट्न वा परिवर्तन गर्नको लागि एपलाई अनुमति दिन्छ। नोट: वेब ब्राउज गर्ने क्षमतासहितका अन्य एपहरू वा तेस्रो- पक्ष ब्राउजरद्वारा सायद यस अनुमतिलाई लागु गर्न सकिंदैन।"</string>
<string name="permlab_setAlarm" msgid="1158001610254173567">"एउटा आलर्म सेट गर्नुहोस्"</string>
<string name="permdesc_setAlarm" msgid="2185033720060109640">"स्थापना गरिएको सङ्केत घडी अनुप्रयोगमा सङ्केत समय मिलाउन एपलाई अनुमति दिन्छ। केही सङ्केत घडी एपहरूले यो सुविधा कार्यान्वयन नगर्न सक्छन्।"</string>
@@ -1555,7 +1555,7 @@
<string name="activity_resolver_use_once" msgid="948462794469672658">"एक पटक मात्र"</string>
<string name="activity_resolver_work_profiles_support" msgid="4071345609235361269">"%1$s कार्य प्रोफाइल समर्थन गर्दैन"</string>
<string name="default_audio_route_name" product="tablet" msgid="367936735632195517">"ट्याब्लेट"</string>
- <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"TV"</string>
+ <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"टिभी"</string>
<string name="default_audio_route_name" product="default" msgid="9213546147739983977">"फोन"</string>
<string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"डक स्पिकरहरू"</string>
<string name="default_audio_route_name_hdmi" msgid="5474470558160717850">"HDMI"</string>
@@ -1613,22 +1613,21 @@
<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="tv" msgid="9064457748587850217">"तपाईंले आफ्नो Android टिभी यन्त्र <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक गलत तरिकाले अनलक गर्ने प्रयास गर्नुभएको छ। थप <xliff:g id="NUMBER_1">%2$d</xliff:g> प्रयासहरू असफल भएपछि तपाईंको Android टिभी यन्त्रलाई रिसेट गरेर पूर्वनिर्धारित फ्याक्ट्री सेटिङ लागू गरिने छ र प्रयोगकर्ताको सम्पूर्ण डेटा गुम्ने छ।"</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="tv" msgid="5045460916106267585">"तपाईंले आफ्नो Android टिभी यन्त्र <xliff:g id="NUMBER">%d</xliff:g> पटक गलत तरिकाले अनलक गर्ने प्रयास गर्नुभएको छ। अब तपाईंको Android टिभी यन्त्रलाई रिसेट गरेर पूर्वनिर्धारित फ्याक्ट्री सेटिङ लागू गरिनेछ।"</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="tv" msgid="4670840383567106114">"तपाईंले आफ्नो अनलक शैली <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक गलत तरिकाले कोर्नुभएको छ। थप <xliff:g id="NUMBER_1">%2$d</xliff:g> प्रयासहरू असफल भएपछि तपाईंलाई आफ्नो इमेल खाता प्रयोग गरेर आफ्नो Android टिभी यन्त्र अनलक गर्न अनुरोध गरिनेछ।\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="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> को पृष्ठभूमिबाट सुरु गरिने अग्रभूमि सेवाका भविष्यमा आउने R बिल्डहरूमा चलाउँदै गर्दा प्रयोग गर्ने अनुमतिको दिइने छैन। कृपया go/r-bg-fgs-restriction हेर्नुहोस् र कुनै बगसम्बन्धी रिपोर्ट फाइल गर्नुहोस्।"</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"सिफारिस तहभन्दा आवाज ठुलो गर्नुहुन्छ?\n\nलामो समय सम्म उच्च आवाजमा सुन्दा तपाईँको सुन्ने शक्तिलाई हानी गर्न सक्छ।"</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"पहुँच सम्बन्धी सर्टकट प्रयोग गर्ने हो?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"यो सर्टकट सक्रिय हुँदा, ३ सेकेन्डसम्म दुवै भोल्युम बटन थिच्नुले पहुँचसम्बन्धी कुनै सुविधा सुरु गर्ने छ।"</string>
<string name="accessibility_shortcut_multiple_service_warning_title" msgid="8417489297036013065">"पहुँचसम्बन्धी सुविधाहरू सक्रिय गर्ने हो?"</string>
- <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"केही सेकेन्डसम्म दुवै भोल्युम बटन थिचिराख्नुले पहुँचसम्बन्धी सुविधाहरू सक्रिय गर्छ। यसले तपाईंको यन्त्रले काम गर्ने तरिका परिवर्तन गर्न सक्छ।\n\nहालका सुविधाहरू:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nतपाईं सेटिङ &gt; पहुँचमा गएर चयन गरिएका सुविधाहरू परिवर्तन गर्न सक्नुहुन्छ।"</string>
+ <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"केही सेकेन्डसम्म दुवै भोल्युम बटन थिचिराख्नुभयो भने पहुँचसम्बन्धी सुविधाहरू सक्रिय हुन्छ। यसले तपाईंको यन्त्रले काम गर्ने तरिका परिवर्तन गर्न सक्छ।\n\nहालका सुविधाहरू:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nतपाईं सेटिङ &gt; पहुँचमा गएर चयन गरिएका सुविधाहरू परिवर्तन गर्न सक्नुहुन्छ।"</string>
<string name="accessibility_shortcut_multiple_service_list" msgid="6935581470716541531">" • <xliff:g id="SERVICE">%1$s</xliff:g>\n"</string>
<string name="accessibility_shortcut_single_service_warning_title" msgid="2819109500943271385">"<xliff:g id="SERVICE">%1$s</xliff:g> सक्रिय गर्ने हो?"</string>
<string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"केही सेकेन्डसम्म दुवै भोल्युम बटन थिचिराख्नुले <xliff:g id="SERVICE">%1$s</xliff:g> नामक पहुँचसम्बन्धी सुविधा सक्रिय गर्छ। यसले तपाईंको यन्त्रले काम गर्ने तरिका परिवर्तन गर्न सक्छ।\n\nतपाईं सेटिङ &gt; पहुँचमा गई यो सर्टकटमार्फत अर्को सुविधा खुल्ने बनाउन सक्नुहुन्छ।"</string>
@@ -1655,13 +1654,13 @@
<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>
- <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"तपाईंले भोल्युम बटनहरू थिचिराख्नुभयो। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> सक्रिय पारियो।"</string>
- <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"तपाईंले भोल्युम बटनहरू थिचिराख्नुभयो। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> निष्क्रिय पारियो।"</string>
+ <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"तपाईंले भोल्युम बटनहरू थिचिराख्नुभयो। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> अन भयो।"</string>
+ <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"तपाईंले भोल्युम बटनहरू थिचिराख्नुभयो। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> अफ भयो।"</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> प्रयोग गर्न दुवै भोल्युम कुञ्जीहरूलाई तीन सेकेन्डसम्म थिचिराख्नुहोस्"</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"तपाईंले पहुँचको बटन ट्याप गर्दा प्रयोग गर्न चाहनुभएको सुविधा छनौट गर्नुहोस्:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"तपाईंले पहुँचको इसारामार्फत प्रयोग गर्न चाहनुभएको सुविधा छनौट गर्नुहोस् (दुईवटा औँलाले स्क्रिनको फेदबाट माथितिर स्वाइप गर्नुहोस्):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"तपाईंले पहुँचको इसारामार्फत प्रयोग गर्न चाहनुभएको सुविधा छनौट गर्नुहोस् (तीनवटा औँलाले स्क्रिनको फेदबाट माथितिर स्वाइप गर्नुहोस्):"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"एउटा सुविधाबाट अर्को सुविधामा जान पहुँचको बटनमा छोइराख्नुहोस्।"</string>
+ <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"एउटा सुविधाबाट अर्को सुविधामा जान पहुँच बटन छोइराख्नुहोस्।"</string>
<string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"एउटा सुविधाबाट अर्को सुविधामा जान दुईवटा औँलाले माथितिर स्वाइप गरी स्क्रिनमा छोइराख्नुहोस्।"</string>
<string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"एउटा सुविधाबाट अर्को सुविधामा जान तीनवटा औँलाले माथितिर स्वाइप गरी स्क्रिनमा छोइराख्नुहोस्।"</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"म्याग्निफिकेसन"</string>
@@ -1948,12 +1947,12 @@
<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_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>
<string name="autofill_save_no" msgid="9212826374207023544">"पर्दैन, धन्यवाद"</string>
<string name="autofill_save_notnow" msgid="2853932672029024195">"अहिले होइन"</string>
<string name="autofill_save_never" msgid="6821841919831402526">"कहिल्यै होइन"</string>
- <string name="autofill_update_yes" msgid="4608662968996874445">"अद्यावधिक गर्नुहोस्"</string>
+ <string name="autofill_update_yes" msgid="4608662968996874445">"अपडेट गर्नुहोस्"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"जारी राख्नुहोस्"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"पासवर्ड"</string>
<string name="autofill_save_type_address" msgid="3111006395818252885">"ठेगाना"</string>
diff --git a/core/res/res/values-night/colors.xml b/core/res/res/values-night/colors.xml
index 98fece3b3c6c..39cdce9cc46b 100644
--- a/core/res/res/values-night/colors.xml
+++ b/core/res/res/values-night/colors.xml
@@ -35,6 +35,7 @@
<color name="resolver_empty_state_text">#FFFFFF</color>
<color name="resolver_empty_state_icon">#FFFFFF</color>
+ <color name="chooser_chip_icon">#8AB4F8</color> <!-- Blue 300 -->
<color name="personal_apps_suspension_notification_color">#8AB4F8</color>
</resources>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index b1c4fbbf0b09..6feb69f348d3 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -237,7 +237,7 @@
<string name="global_actions" product="default" msgid="6410072189971495460">"Telefoonopties"</string>
<string name="global_action_lock" msgid="6949357274257655383">"Schermvergrendeling"</string>
<string name="global_action_power_off" msgid="4404936470711393203">"Uitschakelen"</string>
- <string name="global_action_power_options" msgid="1185286119330160073">"Voeding"</string>
+ <string name="global_action_power_options" msgid="1185286119330160073">"Aan/uit"</string>
<string name="global_action_restart" msgid="4678451019561687074">"Opnieuw opstarten"</string>
<string name="global_action_emergency" msgid="1387617624177105088">"Noodgeval"</string>
<string name="global_action_bug_report" msgid="5127867163044170003">"Bugrapport"</string>
@@ -1619,7 +1619,6 @@
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"Je hebt je ontgrendelingspatroon <xliff:g id="NUMBER_0">%1$d</xliff:g> keer onjuist getekend. Na nog eens <xliff:g id="NUMBER_1">%2$d</xliff:g> mislukte pogingen wordt u gevraagd je telefoon te ontgrendelen via een e-mailaccount.\n\n Probeer het over <xliff:g id="NUMBER_2">%3$d</xliff:g> seconden opnieuw."</string>
<string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Verwijderen"</string>
- <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"De op de achtergrond gestarte voorgrondservice van <xliff:g id="PACKAGENAME">%1$s</xliff:g> heeft geen rechten tijdens gebruik in toekomstige R-builds. Ga naar go/r-bg-fgs-restriction en dien een bugrapport in."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Volume verhogen tot boven het aanbevolen niveau?\n\nAls je langere tijd op hoog volume naar muziek luistert, raakt je gehoor mogelijk beschadigd."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Snelkoppeling toegankelijkheid gebruiken?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Als de snelkoppeling is ingeschakeld, kun je drie seconden op beide volumeknoppen drukken om een toegankelijkheidsfunctie te starten."</string>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index 5986e7652fa3..6a729dc39870 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -175,7 +175,7 @@
<string name="contentServiceTooManyDeletesNotificationDesc" msgid="4562226280528716090">"ବହୁତ <xliff:g id="CONTENT_TYPE">%s</xliff:g>କୁ ଡିଲିଟ୍ କରିବା ପାଇଁ ଚେଷ୍ଟା କରାଯାଇଛି"</string>
<string name="low_memory" product="tablet" msgid="5557552311566179924">"ଟାବଲେଟ୍‍ ଷ୍ଟୋରେଜ୍‍ ପୂର୍ଣ୍ଣ ହୋଇଯାଇଛି। ସ୍ଥାନ ଖାଲି କରିବା ପାଇଁ କିଛି ଫାଇଲ୍‍ ଡିଲିଟ୍‍ କରନ୍ତୁ।"</string>
<string name="low_memory" product="watch" msgid="3479447988234030194">"ୱାଚ୍‍ ଷ୍ଟୋରେଜ୍‍ ପୂର୍ଣ୍ଣ ହୋଇଯାଇଛି। ସ୍ଥାନ ଖାଲି କରିବାକୁ କିଛି ଫାଇଲ୍‍ ଡିଲିଟ୍‍ କରନ୍ତୁ।"</string>
- <string name="low_memory" product="tv" msgid="6663680413790323318">"Android ଟିଭି ଡିଭାଇସ୍‌ର ଷ୍ଟୋରେଜ୍ ପୂର୍ଣ୍ଣ ଅଛି। ଜାଗା ଖାଲି କରିବାକୁ କିଛି ଫାଇଲ୍ ଡିଲିଟ୍ କରନ୍ତୁ।"</string>
+ <string name="low_memory" product="tv" msgid="6663680413790323318">"Android TV ଡିଭାଇସ୍‌ର ଷ୍ଟୋରେଜ୍ ପୂର୍ଣ୍ଣ ଅଛି। ଜାଗା ଖାଲି କରିବାକୁ କିଛି ଫାଇଲ୍ ଡିଲିଟ୍ କରନ୍ତୁ।"</string>
<string name="low_memory" product="default" msgid="2539532364144025569">"ଫୋନ୍‍ ଷ୍ଟୋରେଜ୍‍ ପୂର୍ଣ୍ଣ ହୋଇଯାଇଛି। ସ୍ଥାନ ଖାଲି କରିବା ପାଇଁ କିଛି ଫାଇଲ୍‍ ଡିଲିଟ୍‍ କରନ୍ତୁ।"</string>
<plurals name="ssl_ca_cert_warning" formatted="false" msgid="2288194355006173029">
<item quantity="other">ସର୍ଟିଫିକେଟ୍‍ ଅଥରିଟିଗୁଡ଼ିକ ଇନଷ୍ଟଲ୍‍ ହେଲା</item>
@@ -206,7 +206,7 @@
<string name="personal_apps_suspended_turn_profile_on" msgid="2758012869627513689">"ଚାଲୁ କରନ୍ତୁ"</string>
<string name="me" msgid="6207584824693813140">"ମୁଁ"</string>
<string name="power_dialog" product="tablet" msgid="8333207765671417261">"ଟାବଲେଟ୍‌ର ବିକଳ୍ପ"</string>
- <string name="power_dialog" product="tv" msgid="7792839006640933763">"Android ଟିଭିର ବିକଳ୍ପଗୁଡ଼ିକ"</string>
+ <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>
@@ -224,7 +224,7 @@
<string name="reboot_to_reset_message" msgid="3347690497972074356">"ରିଷ୍ଟାର୍ଟ କରାଯାଉଛି…"</string>
<string name="shutdown_progress" msgid="5017145516412657345">"ବନ୍ଦ କରାଯାଉଛି…"</string>
<string name="shutdown_confirm" product="tablet" msgid="2872769463279602432">"ଆପଣଙ୍କ ଟାବଲେଟ୍ ବନ୍ଦ ହୋଇଯିବ।"</string>
- <string name="shutdown_confirm" product="tv" msgid="7975942887313518330">"ଆପଣଙ୍କର Android ଟିଭି ଡିଭାଇସ୍ ବନ୍ଦ ହୋଇଯିବ।"</string>
+ <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>
@@ -233,7 +233,7 @@
<string name="recent_tasks_title" msgid="8183172372995396653">"ବର୍ତ୍ତମାନର"</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 ଟିଭିର ବିକଳ୍ପଗୁଡ଼ିକ"</string>
+ <string name="global_actions" product="tv" msgid="3871763739487450369">"Android TVର ବିକଳ୍ପଗୁଡ଼ିକ"</string>
<string name="global_actions" product="default" msgid="6410072189971495460">"ଫୋନ ବିକଳ୍ପ"</string>
<string name="global_action_lock" msgid="6949357274257655383">"ସ୍କ୍ରୀନ୍‌ ଲକ୍‌"</string>
<string name="global_action_power_off" msgid="4404936470711393203">"ପାୱାର୍ ବନ୍ଦ"</string>
@@ -357,7 +357,7 @@
<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="tv" msgid="3054753345758011986">"ଏହି ଆପ୍ ଆପଣଙ୍କର Android ଟିଭି ଡିଭାଇସ୍‌ରେ ଷ୍ଟୋର୍ କରାଯାଇଥିବା ସମସ୍ତ SMS (ଟେକ୍ସଟ୍) ପଢ଼ି ପାରିବ।"</string>
+ <string name="permdesc_readSms" product="tv" msgid="3054753345758011986">"ଏହି ଆପ୍ ଆପଣଙ୍କର Android TV ଡିଭାଇସ୍‌ରେ ଷ୍ଟୋର୍ କରାଯାଇଥିବା ସମସ୍ତ 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>
@@ -379,7 +379,7 @@
<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 ଟିଭି ଡିଭାଇସ୍‌କୁ ଧୀର କରି ଅନ୍ୟ ଆପ୍ ପାଇଁ ଉପଲବ୍ଧ ମେମୋରୀକୁ ସୀମିତ କରିପାରେ।"</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>
@@ -389,11 +389,11 @@
<string name="permdesc_writeSettings" msgid="8293047411196067188">"ଆପ୍‍କୁ, ସିଷ୍ଟମର ସେଟିଙ୍ଗ ଡାଟା ବଦଳାଇବାକୁ ଦେଇଥାଏ। ହାନୀକାରକ ଆପ୍‍ ଦ୍ୱାରା ଆପଣଙ୍କ ସିଷ୍ଟମର କନଫିଗରେସନ୍‍ ଖରାପ ହୋଇପାରେ।"</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 ଟିଭି ଡିଭାଇସ୍ ଆରମ୍ଭ କରିବାକୁ ଅଧିକ ସମୟ ନେଇଥାଏ ଏବଂ ସର୍ବଦା ଚାଲି ସମଗ୍ର ଡିଭାଇସ୍‌କୁ ଧୀର କରିବା ପାଇଁ ଆପ୍‌କୁ ଅନୁମତି ଦେଇଥାଏ।"</string>
+ <string name="permdesc_receiveBootCompleted" product="tv" msgid="4900842256047614307">"ଯେତେ ଶୀଘ୍ର ସମ୍ଭବ ସିଷ୍ଟମ୍ ବୁଟିଂ ସମାପ୍ତ ହେବା ପରେ ଆପ୍ ନିଜକୁ ନିଜେ ଆରମ୍ଭ ହେବାକୁ ଅନୁମତି ଦିଏ। ଏହା Android TV ଡିଭାଇସ୍ ଆରମ୍ଭ କରିବାକୁ ଅଧିକ ସମୟ ନେବାକୁ ଦେଇଥାଏ ଏବଂ ସର୍ବଦା ଚାଲି ସମଗ୍ର ଡିଭାଇସ୍‌କୁ ଧୀର କରିବା ପାଇଁ ଆପ୍‌କୁ ଅନୁମତି ଦେଇଥାଏ।"</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">"ଷ୍ଟିକି ବ୍ରଡକାଷ୍ଟ୍ ପଠାଇବା ପାଇଁ ଆପ୍‌କୁ ଅନୁମତି ଦେଇଥାଏ, ଯାହା ବ୍ରଡକାଷ୍ଟ୍ ଶେଷ ହେବାପରେ ରହିଥାଏ। ଅତ୍ୟଧିକ ବ୍ୟବହାର ଦ୍ୱାରା ଅଧିକ ମେମୋରୀ ବ୍ୟବହାର ହୋଇ ଆପଣଙ୍କର Android ଟିଭି ଡିଭାଇସ୍‌କୁ ଧୀର କିମ୍ବା ଅସ୍ଥିର କରିପାରେ।"</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>
@@ -407,17 +407,17 @@
<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 ଟିଭି ଡିଭାଇସ୍‌ର କଲ୍ ଲଗ୍ ସଂଶୋଧନ କରିବାକୁ ଆପ୍‍କୁ ଅନୁମତି ଦେଇଥାଏ। କ୍ଷତିକାରକ ଆପ୍‌ଗୁଡ଼ିକ ଆପଣଙ୍କ କଲ୍ ଲଗ୍ ଲିଭାଇବାକୁ କିମ୍ବା ସଂଶୋଧନ କରିବା ପାଇଁ ଏହାକୁ ବ୍ୟବହାର କରିପାରନ୍ତି।"</string>
+ <string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"ଇନ୍‍କମିଂ ତଥା ଆଉଟ୍‌ଗୋଇଂ କଲ୍ ଡାଟା ସହ ଆପଣଙ୍କ Android TV ଡିଭାଇସ୍‌ର କଲ୍ ଲଗ୍ ସଂଶୋଧନ କରିବାକୁ ଆପ୍‍କୁ ଅନୁମତି ଦେଇଥାଏ। କ୍ଷତିକାରକ ଆପ୍‌ଗୁଡ଼ିକ ଆପଣଙ୍କ କଲ୍ ଲଗ୍ ଲିଭାଇବାକୁ କିମ୍ବା ସଂଶୋଧନ କରିବା ପାଇଁ ଏହାକୁ ବ୍ୟବହାର କରିପାରନ୍ତି।"</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"ଇନ୍‍କମିଙ୍ଗ ତଥା ଆଉଟ୍‍ଗୋଇଙ୍ଗ କଲ୍‌ ଡାଟା ସହ ଆପଣଙ୍କ ଫୋନ୍‍ର କଲ୍‍ ଲଗ୍‍ ବଦଳାଇବା ପାଇଁ ଆପ୍‍କୁ ଅନୁମତି ଦିଏ। ହାନୀକାରକ ଆପ୍‍ ଆପଣଙ୍କ କଲ୍‍ ଲଗ୍‍ ଲିଭାଇବାକୁ କିମ୍ବା ବଦଳାଇବାକୁ ଏହା ବ୍ୟବହାର କରିପାରନ୍ତି।"</string>
<string name="permlab_bodySensors" msgid="3411035315357380862">"ବଡୀ ସେନ୍ସର୍‍ ଆକ୍ସେସ୍‍ କରେ (ଯେପରିକି ହୃଦ୍‍ ହାର ମନିଟର୍‍)"</string>
<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 ଟିଭି ଡିଭାଇସ୍‌ରେ ଷ୍ଟୋର୍ କରାଯାଇଥିବା ସମସ୍ତ କ୍ୟାଲେଣ୍ଡର ଇଭେଣ୍ଟ ପଢ଼ିପାରେ ଏବଂ ଆପଣଙ୍କ କ୍ୟାଲେଣ୍ଡର ଡାଟା ସେୟାର୍ କରିପାରେ କିମ୍ବା ସେଭ୍ କରିପାରେ।"</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 ଟିଭି ଡିଭାଇସ୍‌ରେ କ୍ୟାଲେଣ୍ଡର ଇଭେଣ୍ଟଗୁଡ଼ିକୁ ଯୋଗ କରିପାରେ, କାଢ଼ି ପାରେ କିମ୍ବା ପରିବର୍ତ୍ତନ କରିପାରେ। ଏହି ଆପ୍ ଏପରି ମେସେଜ୍ ପଠାଇ ପାରେ, ଯାହା କ୍ୟାଲେଣ୍ଡର ମାଲିକଙ୍କଠାରୁ ଆସିଥିବା ପରି ଜଣାପଡ଼େ କିମ୍ବା ମାଲିକଙ୍କୁ ନଜଣାଇ ଇଭେଣ୍ଟରେ ପରିବର୍ତ୍ତନ କରିପାରେ।"</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>
@@ -462,7 +462,7 @@
<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 ଟିଭି ଡିଭାଇସ୍‌କୁ ପ୍ରତିରୋଧ କରନ୍ତୁ"</string>
+ <string name="permlab_wakeLock" product="tv" msgid="2856941418123343518">"ସ୍ଲିପିଂରୁ ଆପଣଙ୍କର Android TV ଡିଭାଇସ୍‌କୁ ପ୍ରତିରୋଧ କରନ୍ତୁ"</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>
@@ -470,7 +470,7 @@
<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 ଟିଭି ଡିଭାଇସ୍‌ର ଇନ୍‍ଫ୍ରାରେଡ୍ ଟ୍ରାନ୍ସମିଟର୍ ବ୍ୟବହାର କରିବା ପାଇଁ ଆପ୍‍କୁ ଅନୁମତି ଦେଇଥାଏ।"</string>
+ <string name="permdesc_transmitIr" product="tv" msgid="3278506969529173281">"ଆପଣଙ୍କର Android TV ଡିଭାଇସ୍‌ର ଇନ୍‍ଫ୍ରାରେଡ୍ ଟ୍ରାନ୍ସମିଟର୍ ବ୍ୟବହାର କରିବା ପାଇଁ ଆପ୍‍କୁ ଅନୁମତି ଦେଇଥାଏ।"</string>
<string name="permdesc_transmitIr" product="default" msgid="8484193849295581808">"ଫୋନ୍‍ର ଇନଫ୍ରାରେଡ୍‍ ଟ୍ରାନ୍ସମିଟର୍‍ ବ୍ୟବହାର କରିବାକୁ ଆପ୍‍କୁ ଅନୁମତି ଦେଇଥାଏ।"</string>
<string name="permlab_setWallpaper" msgid="6959514622698794511">"ୱାଲପେପର୍‍ ସେଟ୍ କରନ୍ତୁ"</string>
<string name="permdesc_setWallpaper" msgid="2973996714129021397">"ଆପ୍‍କୁ, ସିଷ୍ଟମ୍‍ ୱାଲପେପର୍‍ ସେଟ୍‍ କରିବାକୁ ଦେଇଥାଏ।"</string>
@@ -478,11 +478,11 @@
<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 ଟିଭି ଡିଭାଇସ୍‌ର ଟାଇମ୍ ଜୋନ୍ ପରିବର୍ତ୍ତନ କରିବାକୁ ଆପ୍‍କୁ ଅନୁମତି ଦେଇଥାଏ।"</string>
+ <string name="permdesc_setTimeZone" product="tv" msgid="9069045914174455938">"ଆପଣଙ୍କର Android TV ଡିଭାଇସ୍‌ର ଟାଇମ୍ ଜୋନ୍ ପରିବର୍ତ୍ତନ କରିବାକୁ ଆପ୍‍କୁ ଅନୁମତି ଦେଇଥାଏ।"</string>
<string name="permdesc_setTimeZone" product="default" msgid="4611828585759488256">"ଆପ୍‍କୁ, ଫୋନ୍‍ର ଟାଇମ୍‍ ଜୋନ୍‍ ବଦଳାଇବାକୁ ଦେଇଥାଏ।"</string>
<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 ଟିଭି ଡିଭାଇସ୍‌କୁ ଜଣାଥିବା ଆକାଉଣ୍ଟଗୁଡ଼ିକର ତାଲିକା ପାଇବା ପାଇଁ ଆପ୍‌କୁ ଅନୁମତି ଦେଇଥାଏ। ଆପଣ ଇନ୍‌ଷ୍ଟଲ୍ କରିଥିବା ଆପ୍ଲିକେସନ୍ ମାଧ୍ୟମରେ ଏହା ଯେ କୌଣସି ଆକାଉଣ୍ଟକୁ ହୁଏତ ଅନ୍ତର୍ଭୁକ୍ତ କରିପାରେ।"</string>
+ <string name="permdesc_getAccounts" product="tv" msgid="437604680436540822">"ଆପଣଙ୍କର Android TV ଡିଭାଇସ୍‌କୁ ଜଣାଥିବା ଆକାଉଣ୍ଟଗୁଡ଼ିକର ତାଲିକା ପାଇବା ପାଇଁ ଆପ୍‌କୁ ଅନୁମତି ଦେଇଥାଏ। ଆପଣ ଇନ୍‌ଷ୍ଟଲ୍ କରିଥିବା ଆପ୍ଲିକେସନ୍ ମାଧ୍ୟମରେ ଏହା ଯେ କୌଣସି ଆକାଉଣ୍ଟକୁ ଅନ୍ତର୍ଭୁକ୍ତ କରିପାରେ।"</string>
<string name="permdesc_getAccounts" product="default" msgid="2491273043569751867">"ଫୋନ୍‌ ଦ୍ୱାରା ପରିଚିତ ଆକାଉଣ୍ଟର ତାଲିକା ପ୍ରାପ୍ତ କରିବାକୁ ଆପ୍‌କୁ ଅନୁମତି ଦେଇଥାଏ। ଆପଣ ଇନଷ୍ଟଲ୍‍ କରିଥିବା ଆପ୍ଲିକେଶନ୍‍ ଦ୍ୱାରା ତିଆରି କରାଯାଇଥିବା କୌଣସି ଆକାଉଣ୍ଟ ବି ଏଥିରେ ସାମିଲ୍ ହୋଇପାରେ।"</string>
<string name="permlab_accessNetworkState" msgid="2349126720783633918">"ନେଟ୍‍ୱର୍କ ସଂଯୋଗ ଦେଖନ୍ତୁ"</string>
<string name="permdesc_accessNetworkState" msgid="4394564702881662849">"କେଉଁ ନେଟ୍‌ୱର୍କ ଉପସ୍ଥିତ ତଥା ସଂଯୁକ୍ତ ଅଛି, ତାହା ବିଷୟରେ ସୂଚନା ଦେଖିବାକୁ ଆପ୍‍କୁ ଅନୁମତି ଦେଇଥାଏ।"</string>
@@ -498,21 +498,21 @@
<string name="permdesc_changeWifiState" msgid="7170350070554505384">"ଆପ୍‌କୁ ୱାଇ-ଫାଇ ଆକ୍ସେସ୍‍ ପଏଣ୍ଟ ସହିତ ସଂଯୋଗ ଓ ବିଚ୍ଛିନ୍ନ କରିବାକୁ ତଥା ୱାଇ-ଫାଇ ନେଟ୍‌ୱର୍କ ପାଇଁ ଡିଭାଇସ୍‌ କନଫିଗରେଶନ୍‍ରେ ପରିବର୍ତ୍ତନ କରିବାକୁ ଅନୁମତି ଦେଇଥାଏ।"</string>
<string name="permlab_changeWifiMulticastState" msgid="285626875870754696">"ୱାଇ-ଫାଇ ମଲ୍ଟିକାଷ୍ଟ ରିସେପଶନ ପାଇଁ ଅନୁମତି ଦିଅନ୍ତୁ"</string>
<string name="permdesc_changeWifiMulticastState" product="tablet" msgid="191079868596433554">"କେବଳ ଆପଣଙ୍କ ଟାବ୍‍ଲେଟ୍‍ ନୁହେଁ, ବରଂ ମଲ୍ଟିକାଷ୍ଟ ଠିକଣାଗୁଡ଼ିକ ବ୍ୟବହାର କରି ଏକ ୱାଇ-ଫାଇ ନେଟ୍‍ୱର୍କରେ ଥିବା ସମସ୍ତ ଡିଭାଇସ୍‌‍କୁ ପଠାଯିବା ପ୍ୟାକେଟ୍‍ଗୁଡ଼ିକ ପ୍ରାପ୍ତ କରିବାକୁ ଆପ୍‍ଟି ଅନୁମତି ଦେଇଥାଏ। ଅଣ-ମଲ୍ଟିକାଷ୍ଟ ମୋଡ୍‍ ତୁଳନାରେ ଏହା ଅଧିକ ପାୱାର୍‍ ବ୍ୟବହାର କରେ।"</string>
- <string name="permdesc_changeWifiMulticastState" product="tv" msgid="1336952358450652595">"କେବଳ ଆପଣଙ୍କର Android ଟିଭି ଡିଭାଇସ୍ ନୁହେଁ, ମଲ୍ଟିକାଷ୍ଟ ଠିକଣାଗୁଡ଼ିକୁ ବ୍ୟବହାର କରି ଏକ ୱାଇ-ଫାଇ ନେଟ୍‌ୱାର୍କରେ ସମସ୍ତ ଡିଭାଇସ୍‍କୁ ପଠାଯାଇଥିବା ପ୍ୟାକେଟ୍ ପ୍ରାପ୍ତ କରିବା ପାଇଁ ଆପ୍‍କୁ ଅନୁମତି ଦେଇଥାଏ। ଏହା ମଲ୍ଟିକାଷ୍ଟ ମୋଡ୍ ନଥିବା ତୁଳନାରେ ଅଧିକ ପାୱାର୍ ବ୍ୟବହାର କରିଥାଏ।"</string>
+ <string name="permdesc_changeWifiMulticastState" product="tv" msgid="1336952358450652595">"କେବଳ ଆପଣଙ୍କର Android TV ଡିଭାଇସ୍ ନୁହେଁ, ମଲ୍ଟିକାଷ୍ଟ ଠିକଣାଗୁଡ଼ିକୁ ବ୍ୟବହାର କରି ଏକ ୱାଇ-ଫାଇ ନେଟ୍‌ୱାର୍କରେ ସମସ୍ତ ଡିଭାଇସ୍‍କୁ ପଠାଯାଇଥିବା ପ୍ୟାକେଟ୍ ପ୍ରାପ୍ତ କରିବା ପାଇଁ ଆପ୍‍କୁ ଅନୁମତି ଦେଇଥାଏ। ଏହା ମଲ୍ଟିକାଷ୍ଟ ମୋଡ୍ ନଥିବା ତୁଳନାରେ ଅଧିକ ପାୱାର୍ ବ୍ୟବହାର କରିଥାଏ।"</string>
<string name="permdesc_changeWifiMulticastState" product="default" msgid="8296627590220222740">"କେବଳ ଆପଣଙ୍କ ଫୋନ୍‍ ନୁହେଁ, ବରଂ ମଲ୍ଟିକାଷ୍ଟ ଠିକଣାଗୁଡ଼ିକ ବ୍ୟବହାର କରି ଏକ ୱାଇ-ଫାଇ ନେଟ୍‍ୱର୍କରେ ଥିବା ସମସ୍ତ ଡିଭାଇସ୍‌‍କୁ ପଠାଯିବା ପ୍ୟାକେଟ୍‍ଗୁଡ଼ିକ ପ୍ରାପ୍ତ କରିବାକୁ ଆପ୍‍ଟି ଅନୁମତି ଦେଇଥାଏ। ଅଣ-ମଲ୍ଟିକାଷ୍ଟ ମୋଡ୍‍ ତୁଳନାରେ ଏହା ଅଧିକ ପାୱାର୍‍ ବ୍ୟବହାର କରେ।"</string>
<string name="permlab_bluetoothAdmin" msgid="6490373569441946064">"ବ୍ଲୁଟୂଥ୍‍‍ ସେଟିଙ୍ଗ ଆକ୍ସେସ୍‌ କରନ୍ତୁ"</string>
<string name="permdesc_bluetoothAdmin" product="tablet" msgid="5370837055438574863">"ସ୍ଥାନୀୟ ବ୍ଲୁ-ଟୁଥ, ଟାବଲେଟ୍‍କୁ କନଫିଗର୍ କରିବାକୁ ଏବଂ ରିମୋର୍ଟ ଡିଭାଇସ୍‌କୁ ଚିହ୍ନାଇବା ତଥା ସେଗୁଡ଼ିକୁ ପେୟାର୍‍ କରିବା ପାଇଁ ଆପ୍‍କୁ ଅନୁମତି ଦେଇଥାଏ।"</string>
- <string name="permdesc_bluetoothAdmin" product="tv" msgid="1623992984547014588">"ଆପଣଙ୍କର Android ଟିଭି ଡିଭାଇସ୍‌ରେ ବ୍ଲୁଟୁଥ୍‍ର କନଫିଗର୍ କରିବା ପାଇଁ ଏବଂ ରିମୋଟ୍ ଡିଭାଇସ୍‌ଗୁଡ଼ିକୁ ଖୋଜିବା ସହ ପେୟାର୍ କରିବା ପାଇଁ ଆପ୍‌କୁ ଅନୁମତି ଦେଇଥାଏ।"</string>
+ <string name="permdesc_bluetoothAdmin" product="tv" msgid="1623992984547014588">"ଆପଣଙ୍କର Android TV ଡିଭାଇସ୍‌ରେ ବ୍ଲୁଟୁଥ୍‍ର କନଫିଗର୍ କରିବା ପାଇଁ ଏବଂ ରିମୋଟ୍ ଡିଭାଇସ୍‌ଗୁଡ଼ିକୁ ଖୋଜିବା ସହ ପେୟାର୍ କରିବା ପାଇଁ ଆପ୍‌କୁ ଅନୁମତି ଦେଇଥାଏ।"</string>
<string name="permdesc_bluetoothAdmin" product="default" msgid="7381341743021234863">"ସ୍ଥାନୀୟ ବ୍ଲୁ-ଟୁଥ, ଫୋନ୍‍କୁ କନଫିଗର୍ କରିବାକୁ ଏବଂ ରିମୋର୍ଟ ଡିଭାଇସ୍‌କୁ ଚିହ୍ନାଇବା ତଥା ସେଗୁଡ଼ିକୁ ପେୟାର୍‍ କରିବା ପାଇଁ ଆପ୍‍କୁ ଅନୁମତି ଦେଇଥାଏ।"</string>
<string name="permlab_accessWimaxState" msgid="7029563339012437434">"WiMAX ସହିତ ସଂଯୋଗ ଏବଂ ଏଥିରୁ ବିଚ୍ଛିନ୍ନ କରନ୍ତୁ"</string>
<string name="permdesc_accessWimaxState" msgid="5372734776802067708">"WiMAX ସକ୍ଷମ କି ନାହିଁ ସ୍ଥିର କରିବାକୁ ଏବଂ ସଂଯୁକ୍ତ ଥିବା କୌଣସି 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">"WiMAX ନେଟ୍‌ୱାର୍କରୁ ଆପଣଙ୍କର Android ଟିଭି ଡିଭାଇସ୍ ସଂଯୋଗ କରିବାକୁ ଏବଂ ବିଚ୍ଛିନ୍ନ କରିବା ପାଇଁ ଆପ୍‌କୁ ଅନୁମତି ଦେଇଥାଏ।"</string>
+ <string name="permdesc_changeWimaxState" product="tv" msgid="5373274458799425276">"WiMAX ନେଟ୍‌ୱାର୍କରୁ ଆପଣଙ୍କର Android TV ଡିଭାଇସ୍ ସଂଯୋଗ କରିବାକୁ ଏବଂ ବିଚ୍ଛିନ୍ନ କରିବା ପାଇଁ ଆପ୍‌କୁ ଅନୁମତି ଦେଇଥାଏ।"</string>
<string name="permdesc_changeWimaxState" product="default" msgid="1551666203780202101">"WiMAX ନେଟ୍‌ୱର୍କରୁ ଫୋନ୍ ସଂଯୋଗ କରିବାକୁ ଏବଂ ବିଚ୍ଛିନ୍ନ କରିବା ପାଇଁ ଆପ୍‌କୁ ଅନୁମତି ଦେଇଥାଏ।"</string>
<string name="permlab_bluetooth" msgid="586333280736937209">"ବ୍ଲୁଟୂଥ୍‍‍ ଡିଭାଇସ୍‍ ଦେଖନ୍ତୁ"</string>
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"ଟାବଲେଟ୍‌ରେ ଥିବା ବ୍ଲୁ-ଟୁଥ୍‌ର କନଫିଗରେଶନ୍‍ ଦେଖିବାକୁ ଏବଂ ପେୟାର୍‍ କରାଯାଇଥିବା ଡିଭାଇସ୍‌ ସହିତ ସଂଯୋଗ ସ୍ୱୀକାର କରିବା ପାଇଁ ଆପ୍‌କୁ ଅନୁମତି ଦେଇଥାଏ।"</string>
- <string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"ଆପଣଙ୍କର Android ଟିଭି ଡିଭାଇସ୍‌ରେ ବ୍ଲୁଟୁଥ୍‍ର କନଫିଗ୍‌ରେସନ୍ ଦେଖିବା ପାଇଁ ଏବଂ ପେୟାର୍ କରାଯାଇଥିବା ଡିଭାଇସ୍‌ଗୁଡ଼ିକ ସହ ସଂଯୋଗଗୁଡ଼ିକୁ ତିଆରି ଏବଂ ସ୍ୱୀକାର କରିବା ପାଇଁ ଆପ୍‌କୁ ଅନୁମତି ଦେଇଥାଏ।"</string>
+ <string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"ଆପଣଙ୍କର Android TV ଡିଭାଇସ୍‌ରେ ବ୍ଲୁଟୁଥ୍‍ର କନଫିଗ୍‌ରେସନ୍ ଦେଖିବା ପାଇଁ ଏବଂ ପେୟାର୍ କରାଯାଇଥିବା ଡିଭାଇସ୍‌ଗୁଡ଼ିକ ସହ ସଂଯୋଗଗୁଡ଼ିକୁ ତିଆରି ଏବଂ ସ୍ୱୀକାର କରିବା ପାଇଁ ଆପ୍‌କୁ ଅନୁମତି ଦେଇଥାଏ।"</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"ଫୋନ୍‌ରେ ଥିବା ବ୍ଲୁ-ଟୁଥ୍‌ର କନଫିଗରେଶନ୍‍ ଦେଖିବାକୁ ଏବଂ ପେୟାର୍‍ କରାଯାଇଥିବା ଡିଭାଇସ୍‌ ସହିତ ସଂଯୋଗ ସ୍ୱୀକାର କରିବା ପାଇଁ ଆପ୍‌କୁ ଅନୁମତି ଦେଇଥାଏ।"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"ପସନ୍ଦର NFC ପେମେଣ୍ଟ ସେବା ସୂଚନା"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"ପଞ୍ଜିକୃତ ଯନ୍ତ୍ର ଏବଂ ମାର୍ଗ ଲକ୍ଷସ୍ଥଳ ପରି ପସନ୍ଦର nfc ପେମେଣ୍ଟ ସେବା ସୂଚନା ପାଇବାକୁ ଆପ୍ ଅନୁମତି କରିଥାଏ।"</string>
@@ -673,10 +673,10 @@
<string name="policydesc_limitPassword" msgid="4105491021115793793">"ଲକ୍‍ ସ୍କ୍ରୀନ୍‍ ପାସ୍‌ୱର୍ଡ ଓ PINରେ ଅନୁମୋଦିତ ଦୀର୍ଘତା ଓ ବର୍ଣ୍ଣ ନିୟନ୍ତ୍ରଣ କରନ୍ତୁ।"</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 ଟିଭି ଡିଭାଇସ୍‌କୁ ଲକ୍ କରିଦିଏ କିମ୍ବା ଯଦି ଅନେକ ଭୁଲ ପାସ୍‌ୱାର୍ଡ ଟାଇପ୍ କରାଯାଇଥାଏ, ତେବେ ଆପଣଙ୍କ Android ଟିଭି ଡିଭାଇସ୍‌ର ସମସ୍ତ ଡାଟା ଲିଭାଇ ଦେଇଥାଏ।"</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_secondaryUser" product="tablet" msgid="2049038943004297474">"ସ୍କ୍ରୀନ୍‍ ଅନଲକ୍‍ କରିବାବେଳେ ଟାଇପ୍‍ କରାଯାଇଥିବା ଭୁଲ ପାସ୍‌ୱର୍ଡର ସଂଖ୍ୟାକୁ ନୀରିକ୍ଷଣ କରେ ଏବଂ ଟାବଲେଟ୍‍କୁ ଲକ୍‍ କରିଦିଏ କିମ୍ବା ଯଦି ଅନେକ ଭୁଲ ପାସ୍‌ୱର୍ଡ ଟାଇପ୍‍ କରାଯାଇଥାଏ, ତେବେ ସମସ୍ତ ଡାଟା ଲିଭାଇଦିଏ।"</string>
- <string name="policydesc_watchLogin_secondaryUser" product="tv" msgid="8965224107449407052">"ସ୍କ୍ରିନ୍ ଅନ୍‌ଲକ୍ କରିବା ସମୟରେ ଟାଇପ୍ କରାଯାଇଥିବା ଭୁଲ ପାସ୍‌ୱାର୍ଡଗୁଡ଼ିକର ସଂଖ୍ୟାକୁ ନିରୀକ୍ଷଣ କରେ ଏବଂ ଆପଣଙ୍କର Android ଟିଭି ଡିଭାଇସ୍‌କୁ ଲକ୍ କରିଦିଏ କିମ୍ବା ଯଦି ଅନେକ ଭୁଲ ପାସ୍‌ୱାର୍ଡ ଟାଇପ୍ କରାଯାଇଥାଏ, ତେବେ ସମସ୍ତ ଡାଟା ଲିଭାଇ ଦିଏ।"</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>
@@ -684,11 +684,11 @@
<string name="policydesc_forceLock" msgid="1008844760853899693">"ସ୍କ୍ରିନ୍ କିପରି ଓ କେତେବେଳେ ଲକ୍‍ କରାଯିବ, ତାହା ନିୟନ୍ତ୍ରଣ କରେ।"</string>
<string name="policylab_wipeData" msgid="1359485247727537311">"ସମସ୍ତ ଡାଟା ଖାଲି କରିବା"</string>
<string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"ବିନା ଚେତାବନୀରେ ଫ୍ୟାକ୍ଟୋରୀ ସେଟିଙ୍ଗ କରାଇ ଟାବ୍‍ଲେଟ୍‍ର ଡାଟା ଲିଭାଇଥାଏ।"</string>
- <string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"ଏକ ଫ୍ୟାକ୍ଟୋରୀ ଡାଟା ରିସେଟ୍ କରି ବିନା ଆଲର୍ଟରେ ଆପଣଙ୍କର Android ଟିଭି ଡିଭାଇସ୍‌ର ଡାଟା ଲିଭାନ୍ତୁ।"</string>
+ <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="tv" msgid="2293713284515865200">"ବିନା ଚେତାବନୀରେ ଏହି Android ଟିଭି ଡିଭାଇସ୍‌ରେ ଏହି ଉପଯୋଗକର୍ତ୍ତାଙ୍କ ଡାଟା ଲିଭାଇ ଦିଅନ୍ତୁ।"</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">"ଗ୍ଲୋବଲ୍ ପ୍ରକ୍ସୀ ଡିଭାଇସ୍‌କୁ ସେଟ୍ କରନ୍ତୁ"</string>
<string name="policydesc_setGlobalProxy" msgid="7149665222705519604">"ପଲିସୀ ସକ୍ଷମ କରାଯାଇଥିବାବେଳେ ବ୍ୟବହାର କରିବା ପାଇଁ ଗ୍ଲୋବାଲ୍‍ ପ୍ରକ୍ସୀ ସେଟ୍‍ କରନ୍ତୁ। କେବଳ ଡିଭାଇସ୍‍ ମାଲିକ ଗ୍ଲୋବାଲ୍‍ ପ୍ରକ୍ସୀ ସେଟ୍‍ କରିପାରିବେ।"</string>
@@ -838,7 +838,7 @@
<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>
- <string name="lockscreen_missing_sim_message" product="tv" msgid="2582768023352171073">"ଆପଣଙ୍କର Android ଟିଭି ଡିଭାଇସ୍‌ରେ କୌଣସି SIM କାର୍ଡ ନାହିଁ।"</string>
+ <string name="lockscreen_missing_sim_message" product="tv" msgid="2582768023352171073">"ଆପଣଙ୍କର Android TV ଡିଭାଇସ୍‌ରେ କୌଣସି SIM କାର୍ଡ ନାହିଁ।"</string>
<string name="lockscreen_missing_sim_message" product="default" msgid="1408695081255172556">"ଫୋନ୍‌ରେ କୌଣସି SIM‍ କାର୍ଡ ନାହିଁ।"</string>
<string name="lockscreen_missing_sim_instructions" msgid="8473601862688263903">"ଏକ SIM କାର୍ଡ ଭର୍ତ୍ତି କରନ୍ତୁ।"</string>
<string name="lockscreen_missing_sim_instructions_long" msgid="3664999892038416334">"SIM କାର୍ଡ ନାହିଁ କିମ୍ବା ଖରାପ ଅଛି। SIM କାର୍ଡ ଭର୍ତ୍ତି କରନ୍ତୁ।"</string>
@@ -861,13 +861,13 @@
<string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="3118353451602377380">"ଆପଣଙ୍କ ପାସୱର୍ଡକୁ ଆପଣ <xliff:g id="NUMBER_0">%1$d</xliff:g> ଥର ଭୁଲ ଭାବେ ଟାଇପ୍‍ କରିଛନ୍ତି। \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> ସେକେଣ୍ଡ ପରେ ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
<string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="2874278239714821984">"ଆପଣଙ୍କ PINକୁ ଆପଣ <xliff:g id="NUMBER_0">%1$d</xliff:g> ଥର ଭୁଲ ଭାବେ ଟାଇପ୍‍ କରିଛନ୍ତି। \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> ସେକେଣ୍ଡ ପରେ ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
<string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="3069635524964070596">"ଅନଲକ୍‍ ପାଟର୍ନକୁ ଆପଣ <xliff:g id="NUMBER_0">%1$d</xliff:g> ଥର ଭୁଲ ଭାବେ ଅଙ୍କନ କରିଛନ୍ତି। ଆଉ <xliff:g id="NUMBER_1">%2$d</xliff:g>ଟି ଭୁଲ ପ୍ରୟାସ ପରେ, Google ସାଇନ୍‌-ଇନ୍‍ ବ୍ୟବହାର କରି ଆପଣଙ୍କୁ ନିଜ ଟାବଲେଟ୍‍କୁ ଅନଲକ୍‍ କରିବାକୁ କୁହାଯିବ।\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> ସେକେଣ୍ଡ ପରେ ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
- <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="6399092175942158529">"ଆପଣ ଆପଣଙ୍କର ଲକ୍ ଖୋଲିବା ପାଟର୍ନକୁ <xliff:g id="NUMBER_0">%1$d</xliff:g> ଥର ଭୁଲ ଆଙ୍କିଛନ୍ତି। <xliff:g id="NUMBER_1">%2$d</xliff:g> ଥର ଅସଫଳ ଚେଷ୍ଟା ପରେ, ଆପଣଙ୍କୁ Google ସାଇନ୍ଇନ୍ ବ୍ୟବହାର କରି ଆପଣଙ୍କର Android ଟିଭି ଡିଭାଇସ୍‌କୁ ଅନ୍‌ଲକ୍ କରିବା ପାଇଁ କୁହାଯିବ। \n\n<xliff:g id="NUMBER_2">%3$d</xliff:g> ସେକେଣ୍ଡ ମଧ୍ୟରେ ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
+ <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="6399092175942158529">"ଆପଣ ଆପଣଙ୍କର ଅନଲକ୍ ପାଟର୍ନକୁ <xliff:g id="NUMBER_0">%1$d</xliff:g> ଥର ଭୁଲ ଭାବେ ଆଙ୍କିଛନ୍ତି। <xliff:g id="NUMBER_1">%2$d</xliff:g> ଥର ଅସଫଳ ଚେଷ୍ଟା ପରେ, ଆପଣଙ୍କୁ Google ସାଇନ୍ଇନ୍ ବ୍ୟବହାର କରି ଆପଣଙ୍କର Android TV ଡିଭାଇସ୍‌କୁ ଅନ୍‌ଲକ୍ କରିବା ପାଇଁ କୁହାଯିବ। \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">"ଆପଣ <xliff:g id="NUMBER_0">%1$d</xliff:g> ଥର ଆପଣଙ୍କର Android ଟିଭି ଡିଭାଇସ୍‌କୁ ଭୁଲ ଭାବେ ଅନ୍‌ଲକ୍ କରିବାକୁ ଚେଷ୍ଟା କରିଛନ୍ତି। <xliff:g id="NUMBER_1">%2$d</xliff:g> ଥର ଅସଫଳ ଚେଷ୍ଟା ପରେ, ଆପଣଙ୍କର Android ଟିଭି ଡିଭାଇସ୍ ଡିଫଲ୍ଟକୁ ଫ୍ୟାକ୍ଟୋରୀ ରିସେଟ୍ କରାଯିବ ଏବଂ ସମସ୍ତ ଉପଯୋଗକର୍ତ୍ତା ଡାଟା ହରାଇବ।"</string>
+ <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="4275591249631864248">"ଆପଣ <xliff:g id="NUMBER_0">%1$d</xliff:g> ଥର ଆପଣଙ୍କର Android TV ଡିଭାଇସ୍‌କୁ ଭୁଲ ଭାବେ ଅନ୍‌ଲକ୍ କରିବାକୁ ଚେଷ୍ଟା କରିଛନ୍ତି। <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">"ଆପଣ <xliff:g id="NUMBER">%d</xliff:g> ଥର ଆପଣଙ୍କର Android ଟିଭି ଡିଭାଇସ୍‌କୁ ଭୁଲ ଭାବେ ଅନ୍‌ଲକ୍ କରିବାକୁ ଚେଷ୍ଟା କରିଛନ୍ତି। ବର୍ତ୍ତମାନ ଆପଣଙ୍କର Android ଟିଭି ଡିଭାଇସ୍ ଫ୍ୟାକ୍ଟୋରୀ ଡିଫଲ୍ଟକୁ ରିସେଟ୍ ହୋଇଯିବ।"</string>
+ <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="2205435033340091883">"ଆପଣ <xliff:g id="NUMBER">%d</xliff:g> ଥର ଆପଣଙ୍କର Android TV ଡିଭାଇସ୍‌କୁ ଭୁଲ ଭାବେ ଅନ୍‌ଲକ୍ କରିବାକୁ ଚେଷ୍ଟା କରିଛନ୍ତି। ବର୍ତ୍ତମାନ ଆପଣଙ୍କର 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_forgot_pattern_button_text" msgid="8362442730606839031">"ପାଟର୍ନ ଭୁଲି ଯାଇଛନ୍ତି କି?"</string>
@@ -954,7 +954,7 @@
<string name="permdesc_readHistoryBookmarks" msgid="2323799501008967852">"ବ୍ରାଉଜର୍‍ରେ ଭିଜିଟ୍‍ କରାଯାଇଥିବା ସମସ୍ତ URL ପଢ଼ିବା ପାଇଁ ଆପ୍‍କୁ ଅନୁମତି ଦିଏ। ଧ୍ୟାନଦିଅନ୍ତୁ: ଏହି ଅନୁମତି ୱେବ୍‍ ବ୍ରାଉଜ୍‍ କରିବା ଦକ୍ଷତା ତୃତୀୟ-ପକ୍ଷ ବ୍ରାଉଜର୍‌ କିମ୍ବା ଅନ୍ୟାନ୍ୟ ଆପ୍ଲିକେଶନ୍‍‍ରେ ଲାଗୁ କରାଯାଇନପାରେ।"</string>
<string name="permlab_writeHistoryBookmarks" msgid="6090259925187986937">"ୱେବ୍‍ ବୁକ୍‍ମାର୍କ ଓ ହିଷ୍ଟୋରୀ ଲେଖନ୍ତୁ"</string>
<string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="573341025292489065">"ଆପଣଙ୍କ ଟାବ୍‍ଲେଟ୍‍ରେ ଷ୍ଟୋର୍‍ କରାଯାଇଥିବା ବ୍ରାଉଜର୍‍ ହିଷ୍ଟୋରୀ କିମ୍ବା ବୁକ୍‍ମାର୍କଗୁଡ଼ିକ ବଦଳାଇବାକୁ ଆପ୍‍କୁ ଅନୁମତି ଦିଏ। ଏହାଦ୍ୱାରା ଆପ୍‍ଟି ବ୍ରାଉଜର୍‍ ଡାଟା ଲିଭାଇପାରେ କିମ୍ବା ବଦଳାଇପାରେ। ଧ୍ୟାନଦିଅନ୍ତୁ: ଏହି ଅନୁମତି ୱେବ୍‍ ବ୍ରାଉଜ୍‍ କରିବାର ଦକ୍ଷତା ତୃତୀୟ-ପକ୍ଷ ବ୍ରାଉଜର୍‌ କିମ୍ବା ଅନ୍ୟାନ୍ୟ ଆପ୍ଲିକେଶନ୍‍‍ରେ ଲାଗୁ କରାଯାଇନପାରେ।"</string>
- <string name="permdesc_writeHistoryBookmarks" product="tv" msgid="88642768580408561">"ଆପଣଙ୍କ Android ଟିଭି ଡିଭାଇସ୍ ଷ୍ଟୋର୍ କରାଯାଇଥିବା ବ୍ରାଉଜର୍ ଇତିହାସ କିମ୍ବା ବୁକମାର୍କଗୁଡ଼ିକ ସଂଶୋଧନ ପାଇଁ ଆପ୍‍କୁ ଅନୁମତି ଦେଇଥାଏ। ଏହା ଦ୍ୱାରା ଆପ୍ ବ୍ରାଉଜର୍ ଡାଟା ଲିଭାଇ ପାରେ କିମ୍ବା ସଂଶୋଧନ କରିପାରେ। ଧ୍ୟାନ ଦିଅନ୍ତୁ: ଏହି ଅନୁମତି ହୁଏତ ୱେବ୍ ବ୍ରାଉଜିଂ ଦକ୍ଷତା ସହ ତୃତୀୟ-ପକ୍ଷ ବ୍ରାଉଜର୍ କିମ୍ବା ଅନ୍ୟ ଆପ୍ଲିକେସନ୍‌ରେ ଲାଗୁ କରାଯାଇ ନପାରେ।"</string>
+ <string name="permdesc_writeHistoryBookmarks" product="tv" msgid="88642768580408561">"ଆପଣଙ୍କ Android TV ଡିଭାଇସ୍ ଷ୍ଟୋର୍ କରାଯାଇଥିବା ବ୍ରାଉଜର୍ ଇତିହାସ କିମ୍ବା ବୁକମାର୍କଗୁଡ଼ିକୁ ସଂଶୋଧନ କରିବା ପାଇଁ ଆପ୍‍କୁ ଅନୁମତି ଦେଇଥାଏ। ଏହା ଦ୍ୱାରା ଆପ୍ ବ୍ରାଉଜର୍ ଡାଟା ଲିଭାଇ ପାରେ କିମ୍ବା ସଂଶୋଧନ କରିପାରେ। ଧ୍ୟାନ ଦିଅନ୍ତୁ: ଏହି ଅନୁମତି ହୁଏତ ୱେବ୍ ବ୍ରାଉଜିଂ ଦକ୍ଷତା ସହ ତୃତୀୟ-ପକ୍ଷ ବ୍ରାଉଜର୍ କିମ୍ବା ଅନ୍ୟ ଆପ୍ଲିକେସନ୍‌ରେ ଲାଗୁ କରାଯାଇ ନପାରେ।"</string>
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="2245203087160913652">"ଆପଣଙ୍କ ଫୋନ୍‍ରେ ଷ୍ଟୋର୍‍ କରାଯାଇଥିବା ବ୍ରାଉଜର୍‍ ହିଷ୍ଟୋରୀ କିମ୍ବା ବୁକ୍‍ମାର୍କଗୁଡ଼ିକ ବଦଳାଇବାକୁ ଆପ୍‍କୁ ଅନୁମତି ଦିଏ। ଏହାଦ୍ୱାରା ଆପ୍‍ଟି ବ୍ରାଉଜର୍‍ ଡାଟା ଲିଭାଇପାରେ କିମ୍ବା ବଦଳାଇପାରେ। ଧ୍ୟାନଦିଅନ୍ତୁ: ଏହି ଅନୁମତି ୱେବ୍‍ ବ୍ରାଉଜ୍‍ କରିବାର ଦକ୍ଷତା ତୃତୀୟ-ପକ୍ଷ ବ୍ରାଉଜର୍‌ କିମ୍ବା ଅନ୍ୟାନ୍ୟ ଆପ୍ଲିକେଶନ୍‍‍ରେ ଲାଗୁ କରାଯାଇନପାରେ।"</string>
<string name="permlab_setAlarm" msgid="1158001610254173567">"ଏକ ଆଲର୍ମ ସେଟ୍‍ କରନ୍ତୁ"</string>
<string name="permdesc_setAlarm" msgid="2185033720060109640">"ଆପ୍‍କୁ, ଇନଷ୍ଟଲ୍‍ ହୋଇଥିବା ଆଲାର୍ମ କ୍ଲକ୍‍ ଆପ୍‍ରେ ଏକ ଆଲାର୍ମ ସେଟ୍‍ କରିବାକୁ ଦେଇଥାଏ। କିଛି ଆଲର୍ମ କ୍ଲକ୍ ଆପ୍‍ ଏହି ବୈଶିଷ୍ଟ୍ୟ ଲାଗୁ କରିନପାରନ୍ତି।"</string>
@@ -1609,17 +1609,16 @@
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="3328686432962224215">"ଆପଣଙ୍କ ପାସ୍‌ୱର୍ଡକୁ ଆପଣ <xliff:g id="NUMBER_0">%1$d</xliff:g>ଥର ଭୁଲ ଭାବେ ଟାଇପ୍ କରିଛନ୍ତି। <xliff:g id="NUMBER_1">%2$d</xliff:g> ସେକେଣ୍ଡ ପରେ \n\nପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="7357404233979139075">"ଆପଣଙ୍କ ଲକ୍‍ ଖୋଲିବା ପାଟର୍ନକୁ ଆପଣ <xliff:g id="NUMBER_0">%1$d</xliff:g>ଥର ଭୁଲ ଭାବେ ଅଙ୍କନ କରିଛନ୍ତି। <xliff:g id="NUMBER_1">%2$d</xliff:g> ସେକେଣ୍ଡ ପରେ \n\nପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</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">"ଆପଣ <xliff:g id="NUMBER_0">%1$d</xliff:g> ଥର ଆପଣଙ୍କର Android ଟିଭି ଡିଭାଇସ୍‌କୁ ଭୁଲ ଭାବେ ଅନ୍‌ଲକ୍ କରିବାକୁ ଚେଷ୍ଟା କରିଛନ୍ତି। <xliff:g id="NUMBER_1">%2$d</xliff:g> ଥର ଅସଫଳ ଚେଷ୍ଟା ପରେ, ଆପଣଙ୍କର Android ଟିଭି ଡିଭାଇସ୍ ଡିଫଲ୍ଟକୁ ଫ୍ୟାକ୍ଟୋରୀ ରିସେଟ୍ କରାଯିବ ଏବଂ ସମସ୍ତ ଉପଯୋଗକର୍ତ୍ତା ଡାଟା ହରାଇବ।"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="9064457748587850217">"ଆପଣ <xliff:g id="NUMBER_0">%1$d</xliff:g> ଥର ଆପଣଙ୍କର Android TV ଡିଭାଇସ୍‌କୁ ଭୁଲ ଭାବେ ଅନ୍‌ଲକ୍ କରିବାକୁ ଚେଷ୍ଟା କରିଛନ୍ତି। <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">"ଆପଣ <xliff:g id="NUMBER">%d</xliff:g> ଥର ଆପଣଙ୍କର Android ଟିଭି ଡିଭାଇସ୍‌କୁ ଭୁଲ ଭାବେ ଅନ୍‌ଲକ୍ କରିବାକୁ ଚେଷ୍ଟା କରିଛନ୍ତି। ବର୍ତ୍ତମାନ ଆପଣଙ୍କର Android ଟିଭି ଡିଭାଇସ୍ ଫ୍ୟାକ୍ଟୋରୀ ଡିଫଲ୍ଟକୁ ରିସେଟ୍ ହୋଇଯିବ।"</string>
+ <string name="kg_failed_attempts_now_wiping" product="tv" msgid="5045460916106267585">"ଆପଣ <xliff:g id="NUMBER">%d</xliff:g> ଥର ଆପଣଙ୍କର Android TV ଡିଭାଇସ୍‌କୁ ଭୁଲ ଭାବେ ଅନ୍‌ଲକ୍ କରିବାକୁ ଚେଷ୍ଟା କରିଛନ୍ତି। ବର୍ତ୍ତମାନ ଆପଣଙ୍କର 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_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 ଟିଭି ଡିଭାଇସ୍‌କୁ ଅନ୍‌ଲକ୍ କରିବା ପାଇଁ କୁହାଯିବ। \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_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"ବାହାର କରନ୍ତୁ"</string>
- <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"ପୃଷ୍ଠଭୂମିରେ <xliff:g id="PACKAGENAME">%1$s</xliff:g>ରୁ ଆରମ୍ଭ ହୋଇଥିବା ସମ୍ମୁଖଭାଗ ସେବା ପାଇଁ ଭବିଷ୍ୟତର R ବିଲ୍ଡଗୁଡ଼ିକରେ ବ୍ୟବହାର କରାଯିବା ସମୟରେ ଅନୁମତି ସୁବିଧା ରହିବ ନାହିଁ। ଦୟାକରି go/r-bg-fgs-restriction ଦେଖନ୍ତୁ ଏବଂ ଏକ ବଗରିପୋର୍ଟ ଫାଇଲ୍ କରନ୍ତୁ।"</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"ମାତ୍ରା ବଢ଼ାଇ ସୁପାରିଶ ସ୍ତର ବଢ଼ାଉଛନ୍ତି? \n\n ଲମ୍ବା ସମୟ ପର୍ଯ୍ୟନ୍ତ ଉଚ୍ଚ ଶବ୍ଦରେ ଶୁଣିଲେ ଆପଣଙ୍କ ଶ୍ରବଣ ଶକ୍ତି ଖରାପ ହୋଇପାରେ।"</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"ଆକ୍ସେସବିଲିଟି ଶର୍ଟକଟ୍‍ ବ୍ୟବହାର କରିବେ?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"ସର୍ଟକଟ୍ ଚାଲୁ ଥିବା ବେଳେ, ଉଭୟ ଭଲ୍ୟୁମ୍ ବଟନ୍ 3 ସେକେଣ୍ଡ ପାଇଁ ଦବାଇବା ଦ୍ୱାରା ଏକ ଆକ୍ସେସବିଲିଟି ଫିଚର୍ ଆରମ୍ଭ ହେବ।"</string>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 77341c677abe..9faa33785f1f 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -1619,7 +1619,6 @@
<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="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> ਤੋਂ ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਸ਼ੁਰੂ ਕੀਤੀ ਗਈ ਫੋਰਗ੍ਰਾਊਂਡ ਸੇਵਾ ਲਈ ਭਵਿੱਖੀ R ਬਿਲਡ ਵਿੱਚ \'ਵਰਤੋਂ ਵਿੱਚ ਹੋਣ \'ਤੇ ਇਜਾਜ਼ਤ\' ਵਿਸ਼ੇਸ਼ਤਾ ਨਹੀਂ ਹੋਵੇਗੀ। ਕਿਰਪਾ ਕਰਕੇ go/r-bg-fgs-restriction ਦੇਖੋ ਅਤੇ ਬੱਗ ਰਿਪੋਰਟ ਫ਼ਾਈਲ ਕਰੋ।"</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"ਕੀ ਵੌਲਿਊਮ ਸਿਫ਼ਾਰਸ਼ ਕੀਤੇ ਪੱਧਰ ਤੋਂ ਵਧਾਉਣੀ ਹੈ?\n\nਲੰਮੇ ਸਮੇਂ ਤੱਕ ਉੱਚ ਵੌਲਿਊਮ ਤੇ ਸੁਣਨ ਨਾਲ ਤੁਹਾਡੀ ਸੁਣਨ ਸ਼ਕਤੀ ਨੂੰ ਨੁਕਸਾਨ ਪਹੁੰਚ ਸਕਦਾ ਹੈ।"</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"ਕੀ ਪਹੁੰਚਯੋਗਤਾ ਸ਼ਾਰਟਕੱਟ ਵਰਤਣਾ ਹੈ?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"ਸ਼ਾਰਟਕੱਟ ਚਾਲੂ ਹੋਣ \'ਤੇ, ਕਿਸੇ ਪਹੁੰਚਯੋਗਤਾ ਵਿਸ਼ੇਸ਼ਤਾ ਨੂੰ ਸ਼ੁਰੂ ਕਰਨ ਲਈ ਦੋਵੇਂ ਅਵਾਜ਼ ਬਟਨਾਂ ਨੂੰ 3 ਸਕਿੰਟ ਲਈ ਦਬਾ ਕੇ ਰੱਖੋ।"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index f89189b3fa9e..254f1d04be87 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -1171,7 +1171,7 @@
<string name="whichOpenHostLinksWith" msgid="7645631470199397485">"Otwieraj linki z <xliff:g id="HOST">%1$s</xliff:g> w"</string>
<string name="whichOpenLinksWith" msgid="1120936181362907258">"Otwieraj linki w"</string>
<string name="whichOpenLinksWithApp" msgid="6917864367861910086">"Otwieraj linki w aplikacji <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
- <string name="whichOpenHostLinksWithApp" msgid="2401668560768463004">"Otwieraj linki z: <xliff:g id="HOST">%1$s</xliff:g> w aplikacji <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
+ <string name="whichOpenHostLinksWithApp" msgid="2401668560768463004">"Otwieraj linki z <xliff:g id="HOST">%1$s</xliff:g> w aplikacji <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
<string name="whichGiveAccessToApplicationLabel" msgid="7805857277166106236">"Udziel uprawnień"</string>
<string name="whichEditApplication" msgid="6191568491456092812">"Edytuj w aplikacji"</string>
<string name="whichEditApplicationNamed" msgid="8096494987978521514">"Edytuj w aplikacji %1$s"</string>
@@ -1663,7 +1663,6 @@
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"Po raz <xliff:g id="NUMBER_0">%1$d</xliff:g> nieprawidłowo narysowałeś wzór odblokowania. Po kolejnych <xliff:g id="NUMBER_1">%2$d</xliff:g> nieudanych próbach konieczne będzie odblokowanie telefonu przy użyciu danych logowania na konto Google.\n\n Spróbuj ponownie za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
<string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" – "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Usuń"</string>
- <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Uruchomiona w tle usługa działająca w pierwszym planie z pakietu <xliff:g id="PACKAGENAME">%1$s</xliff:g> nie będzie miała uprawnień obowiązujących podczas używania w przyszłych kompilacjach R. Zapoznaj się z ograniczeniem go/r-bg-fgs-restriction i zgłoś błąd."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Zwiększyć głośność ponad zalecany poziom?\n\nSłuchanie głośno przez długi czas może uszkodzić Twój słuch."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Użyć skrótu do ułatwień dostępu?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Gdy skrót jest włączony, jednoczesne naciskanie przez trzy sekundy obu przycisków głośności uruchamia funkcję ułatwień dostępu."</string>
@@ -1687,7 +1686,7 @@
<string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Odmów"</string>
<string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Wybierz funkcję, aby zacząć z niej korzystać:"</string>
<string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Wybierz funkcje, których chcesz używać z przyciskiem ułatwień dostępu"</string>
- <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Wybierz funkcje, których chcesz używać w przypadku skrótu z klawiszami głośności"</string>
+ <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Wybierz funkcje, do których chcesz używać skrótu z klawiszami głośności"</string>
<string name="accessibility_uncheck_legacy_item_warning" msgid="8047830891064817447">"Usługa <xliff:g id="SERVICE_NAME">%s</xliff:g> została wyłączona"</string>
<string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Edytuj skróty"</string>
<string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"OK"</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index 4858b42d8acf..bea530000b22 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -1311,7 +1311,7 @@
<string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"Selecione para desativar a depuração USB."</string>
<string name="adbwifi_active_notification_title" msgid="6147343659168302473">"Depuração por Wi-Fi conectada"</string>
<string name="adbwifi_active_notification_message" msgid="930987922852867972">"Toque para desativar a depuração por Wi-Fi"</string>
- <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Selecione para desativar a depuração sem fio."</string>
+ <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Selecione para desativar a depuração por Wi-Fi."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Modo Arcabouço de testes ativado"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Realize uma redefinição para configuração original para desativar o modo Arcabouço de testes."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"Console serial ativado"</string>
@@ -1619,7 +1619,6 @@
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas incorretas, será solicitado que você use o login do Google para desbloquear.\n\n Tente novamente em <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
<string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Remover"</string>
- <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"O serviço em primeiro plano iniciado em segundo plano por <xliff:g id="PACKAGENAME">%1$s</xliff:g> não receberá uma permissão durante o uso em futuras versões R. Consulte go/r-bg-fgs-restriction e crie um relatório de bug."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Aumentar o volume acima do nível recomendado?\n\nOuvir em volume alto por longos períodos pode danificar sua audição."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Usar atalho de Acessibilidade?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Quando o atalho estiver ativado, pressione os dois botões de volume por três segundos para iniciar um recurso de acessibilidade."</string>
@@ -1652,7 +1651,7 @@
<string name="color_inversion_feature_name" msgid="326050048927789012">"Inversão de cores"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Correção de cor"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Teclas de volume pressionadas. Serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ativado."</string>
- <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Teclas de volume pressionadas. Serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g> desativado."</string>
+ <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Teclas de volume pressionadas. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> desativado."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Toque nos dois botões de volume e os mantenha pressionados por três segundo para usar o <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Escolha um recurso a ser usado quando você toca no botão de acessibilidade:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Escolha um recurso para usar com o gesto de acessibilidade (deslizar de baixo para cima na tela com dois dedos):"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index a13c2d28f986..069dc64c0b79 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -237,7 +237,7 @@
<string name="global_actions" product="default" msgid="6410072189971495460">"Opções do telefone"</string>
<string name="global_action_lock" msgid="6949357274257655383">"Bloqueio de ecrã"</string>
<string name="global_action_power_off" msgid="4404936470711393203">"Desligar"</string>
- <string name="global_action_power_options" msgid="1185286119330160073">"Ligar/desligar"</string>
+ <string name="global_action_power_options" msgid="1185286119330160073">"Ligar"</string>
<string name="global_action_restart" msgid="4678451019561687074">"Reiniciar"</string>
<string name="global_action_emergency" msgid="1387617624177105088">"Emergência"</string>
<string name="global_action_bug_report" msgid="5127867163044170003">"Relatório de erros"</string>
@@ -264,7 +264,7 @@
<string name="global_action_settings" msgid="4671878836947494217">"Definições"</string>
<string name="global_action_assist" msgid="2517047220311505805">"Assistência"</string>
<string name="global_action_voice_assist" msgid="6655788068555086695">"Assist. de voz"</string>
- <string name="global_action_lockdown" msgid="2475471405907902963">"Bloqueio"</string>
+ <string name="global_action_lockdown" msgid="2475471405907902963">"Bloquear"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
<string name="notification_hidden_text" msgid="2835519769868187223">"Nova notificação"</string>
<string name="notification_channel_virtual_keyboard" msgid="6465975799223304567">"Teclado virtual"</string>
@@ -1619,7 +1619,6 @@
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"Desenhou o padrão de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Depois de mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas sem sucesso, ser-lhe-á pedido para desbloquear o telemóvel através de uma conta de email.\n\n Tente novamente dentro de <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
<string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" - "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Remover"</string>
- <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"O serviço em primeiro plano iniciado em segundo plano de <xliff:g id="PACKAGENAME">%1$s</xliff:g> não terá a autorização durante a utilização em compilações R futuras. Aceda a go/r-bg-fgs-restriction e envie um relatório de erros."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Aumentar o volume acima do nível recomendado?\n\nOuvir com um volume elevado durante longos períodos poderá ser prejudicial para a sua audição."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Pretende utilizar o atalho de acessibilidade?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Quando o atalho está ativado, premir ambos os botões de volume durante 3 segundos inicia uma funcionalidade de acessibilidade."</string>
@@ -1643,7 +1642,7 @@
<string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Recusar"</string>
<string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Toque numa funcionalidade para começar a utilizá-la:"</string>
<string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Escolha funcionalidades para utilizar com o botão Acessibilidade"</string>
- <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Escolha funcionalidades para utilizar com o atalho das teclas de volume"</string>
+ <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Escolha funcionalidades para usar com o atalho das teclas de volume"</string>
<string name="accessibility_uncheck_legacy_item_warning" msgid="8047830891064817447">"O serviço <xliff:g id="SERVICE_NAME">%s</xliff:g> foi desativado."</string>
<string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Editar atalhos"</string>
<string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Concluído"</string>
@@ -1652,7 +1651,7 @@
<string name="color_inversion_feature_name" msgid="326050048927789012">"Inversão de cores"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Correção da cor"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Teclas do volume premidas. Serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ativado."</string>
- <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Teclas do volume premidas. Serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g> desativado."</string>
+ <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Teclas de volume premidas. Serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g> desativado."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Prima sem soltar as teclas de volume durante três segundos para utilizar o serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Escolha uma funcionalidade para utilizar quando tocar no botão Acessibilidade:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Escolha a funcionalidade a utilizar com o gesto de acessibilidade (deslize rapidamente com dois dedos para cima a partir da parte inferior do ecrã):"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 4858b42d8acf..bea530000b22 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -1311,7 +1311,7 @@
<string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"Selecione para desativar a depuração USB."</string>
<string name="adbwifi_active_notification_title" msgid="6147343659168302473">"Depuração por Wi-Fi conectada"</string>
<string name="adbwifi_active_notification_message" msgid="930987922852867972">"Toque para desativar a depuração por Wi-Fi"</string>
- <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Selecione para desativar a depuração sem fio."</string>
+ <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Selecione para desativar a depuração por Wi-Fi."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Modo Arcabouço de testes ativado"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Realize uma redefinição para configuração original para desativar o modo Arcabouço de testes."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"Console serial ativado"</string>
@@ -1619,7 +1619,6 @@
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas incorretas, será solicitado que você use o login do Google para desbloquear.\n\n Tente novamente em <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
<string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Remover"</string>
- <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"O serviço em primeiro plano iniciado em segundo plano por <xliff:g id="PACKAGENAME">%1$s</xliff:g> não receberá uma permissão durante o uso em futuras versões R. Consulte go/r-bg-fgs-restriction e crie um relatório de bug."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Aumentar o volume acima do nível recomendado?\n\nOuvir em volume alto por longos períodos pode danificar sua audição."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Usar atalho de Acessibilidade?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Quando o atalho estiver ativado, pressione os dois botões de volume por três segundos para iniciar um recurso de acessibilidade."</string>
@@ -1652,7 +1651,7 @@
<string name="color_inversion_feature_name" msgid="326050048927789012">"Inversão de cores"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Correção de cor"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Teclas de volume pressionadas. Serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ativado."</string>
- <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Teclas de volume pressionadas. Serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g> desativado."</string>
+ <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Teclas de volume pressionadas. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> desativado."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Toque nos dois botões de volume e os mantenha pressionados por três segundo para usar o <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Escolha um recurso a ser usado quando você toca no botão de acessibilidade:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Escolha um recurso para usar com o gesto de acessibilidade (deslizar de baixo para cima na tela com dois dedos):"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index aeaceca65c65..4c5fbe6cec6f 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -1641,7 +1641,6 @@
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"Ați desenat incorect modelul pentru deblocare de <xliff:g id="NUMBER_0">%1$d</xliff:g> ori. După încă <xliff:g id="NUMBER_1">%2$d</xliff:g> încercări nereușite, vi se va solicita să deblocați telefonul cu ajutorul unui cont de e-mail.\n\n Încercați din nou peste <xliff:g id="NUMBER_2">%3$d</xliff:g> secunde."</string>
<string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Eliminați"</string>
- <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Serviciul în prim-plan inițializat în fundal din <xliff:g id="PACKAGENAME">%1$s</xliff:g> nu va avea permisiunea în timpul utilizării în versiunile R viitoare. Consultați go/r-bg-fgs-restriction și trimiteți un raport de eroare."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Ridicați volumul mai sus de nivelul recomandat?\n\nAscultarea la volum ridicat pe perioade lungi de timp vă poate afecta auzul."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Utilizați comanda rapidă pentru accesibilitate?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Atunci când comanda rapidă este activată, dacă apăsați ambele butoane de volum timp de trei secunde, veți lansa o funcție de accesibilitate."</string>
@@ -1665,7 +1664,7 @@
<string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Refuzați"</string>
<string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Atingeți o funcție ca să începeți să o folosiți:"</string>
<string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Alegeți funcțiile pe care să le folosiți cu butonul de accesibilitate"</string>
- <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Alegeți funcțiile pe care să le folosiți cu comanda rapidă pentru butonul de volum"</string>
+ <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Alegeți funcțiile pentru comanda rapidă a butonului de volum"</string>
<string name="accessibility_uncheck_legacy_item_warning" msgid="8047830891064817447">"<xliff:g id="SERVICE_NAME">%s</xliff:g> a fost dezactivat"</string>
<string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Editați comenzile rapide"</string>
<string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Gata"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 83dd3e23c702..38fcff144a56 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -242,7 +242,7 @@
<string name="global_action_lock" msgid="6949357274257655383">"Блокировка экрана"</string>
<string name="global_action_power_off" msgid="4404936470711393203">"Выключить"</string>
<string name="global_action_power_options" msgid="1185286119330160073">"Питание"</string>
- <string name="global_action_restart" msgid="4678451019561687074">"Перезапуск"</string>
+ <string name="global_action_restart" msgid="4678451019561687074">"Перезапустить"</string>
<string name="global_action_emergency" msgid="1387617624177105088">"Экстренный вызов"</string>
<string name="global_action_bug_report" msgid="5127867163044170003">"Отчет об ошибке"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Закончить сеанс"</string>
@@ -1663,7 +1663,6 @@
<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> неверных попыток для разблокировки телефона потребуется войти в аккаунт Google.\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="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Службы из пакета <xliff:g id="PACKAGENAME">%1$s</xliff:g>, переведенные из фонового режима в активный, не будут получать разрешение while-in-use в будущих сборках на языке R. Перейдите на страницу go/r-bg-fgs-restriction и отправьте отчет об ошибке."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Установить громкость выше рекомендуемого уровня?\n\nВоздействие громкого звука в течение долгого времени может привести к повреждению слуха."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Использовать быстрое включение?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Чтобы использовать функцию специальных возможностей, когда она включена, нажмите и удерживайте обе кнопки регулировки громкости в течение трех секунд."</string>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index e61b4e8696a3..b477be89b6dc 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -1619,7 +1619,6 @@
<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="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> වෙතින් පසුබිම ආරම්භ කරන ලද පෙරබිම් සේවාව අනාගත R තැනුම්වලදී භාවිතයේ අවසරය නැත. කරුණාකර go/r-bg-fgs-අවහිරතාව බලා දෝෂ වාර්තාවක් ගොනු කරන්න."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"නිර්දේශිතයි මට්ටමට වඩා ශබ්දය වැඩිද?\n\nදිගු කාලයක් සඳහා ඉහළ ශබ්දයක් ඇසීමෙන් ඇතැම් විට ඔබගේ ඇසීමට හානි විය හැක."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"ප්‍රවේශ්‍යතා කෙටිමඟ භාවිතා කරන්නද?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"කෙටිමග ක්‍රියාත්මක විට, හඬ පරිමා බොත්තම් දෙකම තත්පර 3ක් තිස්සේ එබීමෙන් ප්‍රවේශ්‍යතා විශේෂාංගය ආරම්භ වනු ඇත."</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index be1d8c1fef18..11c99a1f57d4 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -241,13 +241,13 @@
<string name="global_actions" product="default" msgid="6410072189971495460">"Možnosti telefónu"</string>
<string name="global_action_lock" msgid="6949357274257655383">"Zámka obrazovky"</string>
<string name="global_action_power_off" msgid="4404936470711393203">"Vypnúť"</string>
- <string name="global_action_power_options" msgid="1185286119330160073">"Vypnutie"</string>
+ <string name="global_action_power_options" msgid="1185286119330160073">"Vypnúť"</string>
<string name="global_action_restart" msgid="4678451019561687074">"Reštartovať"</string>
<string name="global_action_emergency" msgid="1387617624177105088">"Tieseň"</string>
<string name="global_action_bug_report" msgid="5127867163044170003">"Hlásenie o chybách"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Ukončiť reláciu"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Snímka obrazovky"</string>
- <string name="bugreport_title" msgid="8549990811777373050">"Hlásenie chyby"</string>
+ <string name="bugreport_title" msgid="8549990811777373050">"Nahlásiť chybu"</string>
<string name="bugreport_message" msgid="5212529146119624326">"Týmto zhromaždíte informácie o aktuálnom stave zariadenia. Informácie je potom možné odoslať e-mailom, chvíľu však potrvá, kým bude hlásenie chyby pripravené na odoslanie. Prosíme vás preto o trpezlivosť."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Interaktívne nahlásenie"</string>
<string name="bugreport_option_interactive_summary" msgid="8493795476325339542">"Táto možnosť je vhodná pre väčšinu prípadov. Umožňuje sledovať priebeh nahlásenia, zadávať ďalšie podrobnosti o probléme a vytvárať snímky obrazovky. Môžu byť vynechané niektoré menej používané sekcie, ktorých nahlásenie trvá dlho."</string>
@@ -1663,12 +1663,11 @@
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"<xliff:g id="NUMBER_0">%1$d</xliff:g>-krát ste nesprávne nakreslili svoj bezpečnostný vzor. Po <xliff:g id="NUMBER_1">%2$d</xliff:g> ďalších neúspešných pokusoch sa zobrazí výzva na odomknutie telefónu pomocou e-mailového účtu.\n\n Skúste to znova o <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
<string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Odstrániť"</string>
- <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Služba na popredí spustená na pozadí z balíka <xliff:g id="PACKAGENAME">%1$s</xliff:g> nebude mať v budúcich zostavách R povolenie Počas používania. Prejdite na go/r-bg-fgs-restriction a odošlite hlásenie chyby."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Zvýšiť hlasitosť nad odporúčanú úroveň?\n\nDlhodobé počúvanie pri vysokej hlasitosti môže poškodiť váš sluch."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Použiť skratku dostupnosti?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Keď je skratka zapnutá, stlačením obidvoch tlačidiel hlasitosti na tri sekundy spustíte funkciu dostupnosti."</string>
<string name="accessibility_shortcut_multiple_service_warning_title" msgid="8417489297036013065">"Chcete zapnúť funkcie dostupnosti?"</string>
- <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"Pridržaním oboch klávesov hlasitosti na niekoľko sekúnd zapnete funkcie dostupnosti. Môže sa tým zmeniť spôsob fungovania vášho zariadenia.\n\nAktuálne funkcie:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nVybrané funkcie môžete zmeniť v časti Nastavenia &gt; Dostupnosť."</string>
+ <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"Pridržaním oboch tlačidiel hlasitosti na niekoľko sekúnd zapnete funkcie dostupnosti. Môže sa tým zmeniť spôsob fungovania vášho zariadenia.\n\nAktuálne funkcie:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nVybrané funkcie môžete zmeniť v časti Nastavenia &gt; Dostupnosť."</string>
<string name="accessibility_shortcut_multiple_service_list" msgid="6935581470716541531">" • <xliff:g id="SERVICE">%1$s</xliff:g>\n"</string>
<string name="accessibility_shortcut_single_service_warning_title" msgid="2819109500943271385">"Chcete zapnúť <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
<string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Pridržaním oboch klávesov hlasitosti na niekoľko sekúnd zapnete funkciu dostupnosti <xliff:g id="SERVICE">%1$s</xliff:g>. Môže sa tým zmeniť spôsob fungovania vášho zariadenia.\n\nTúto skratku môžete zmeniť na inú funkciu v časti Nastavenia &gt; Dostupnosť."</string>
@@ -1695,8 +1694,8 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Použiť skratku"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Inverzia farieb"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Úprava farieb"</string>
- <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Pridržali ste klávesy hlasitosti. Služba <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je zapnutá."</string>
- <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Pridržali ste klávesy hlasitosti. Služba <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je vypnutá."</string>
+ <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Pridržali ste tlačidlá hlasitosti. Služba <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je zapnutá."</string>
+ <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Pridržali ste tlačidlá hlasitosti. Služba <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je vypnutá."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Ak chcete používať službu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, pridržte tri sekundy oba klávesy hlasitosti"</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Klepnutím na tlačidlo dostupnosti vyberte požadovanú funkciu:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Vyberte funkciu, ktorú chcete používať s daným gestom dostupnosti (potiahnutím dvoma prstami z dolnej časti obrazovky nahor):"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index ec8bf51890a0..e21cc58dfda5 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -1168,7 +1168,7 @@
<string name="whichViewApplication" msgid="5733194231473132945">"Odpiranje z aplikacijo"</string>
<string name="whichViewApplicationNamed" msgid="415164730629690105">"Odpiranje z aplikacijo %1$s"</string>
<string name="whichViewApplicationLabel" msgid="7367556735684742409">"Odpiranje"</string>
- <string name="whichOpenHostLinksWith" msgid="7645631470199397485">"Odpiranje povezav <xliff:g id="HOST">%1$s</xliff:g> z"</string>
+ <string name="whichOpenHostLinksWith" msgid="7645631470199397485">"Odpiranje povezav <xliff:g id="HOST">%1$s</xliff:g> z aplikacijo"</string>
<string name="whichOpenLinksWith" msgid="1120936181362907258">"Odpiranje povezav z"</string>
<string name="whichOpenLinksWithApp" msgid="6917864367861910086">"Odpiranje povezav z aplikacijo <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
<string name="whichOpenHostLinksWithApp" msgid="2401668560768463004">"Odpiranje povezav <xliff:g id="HOST">%1$s</xliff:g> z aplikacijo <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
@@ -1663,7 +1663,6 @@
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"Vzorec za odklepanje ste <xliff:g id="NUMBER_0">%1$d</xliff:g>-krat napačno vnesli. Po nadaljnjih <xliff:g id="NUMBER_1">%2$d</xliff:g> neuspešnih poskusih boste pozvani, da odklenete telefon z Googlovimi podatki za prijavo.\n\nPoskusite znova čez <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
<string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" – "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Odstrani"</string>
- <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"V prihodnjih različicah R storitev v ospredju z zagonom iz ozadja iz paketa <xliff:g id="PACKAGENAME">%1$s</xliff:g> ne bo imela dovoljenja med uporabo aplikacije. Oglejte si go/r-bg-fgs-restriction in pošljite poročilo o napakah."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Ali želite povečati glasnost nad priporočeno raven?\n\nDolgotrajno poslušanje pri veliki glasnosti lahko poškoduje sluh."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Želite uporabljati bližnjico funkcij za ljudi s posebnimi potrebami?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Ko je bližnjica vklopljena, pritisnite gumba za glasnost in ju pridržite tri sekunde, če želite zagnati funkcijo za ljudi s posebnimi potrebami."</string>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 16d7a7bb110c..156e82f56f89 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -1619,7 +1619,6 @@
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"Ke vizatuar <xliff:g id="NUMBER_0">%1$d</xliff:g> herë pa sukses motivin tënd. Pas <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativave të tjera të pasuksesshme, do të të duhet ta shkyçësh telefonin duke përdorur një llogari mail-i.\n\n Provo sërish për <xliff:g id="NUMBER_2">%3$d</xliff:g> sekonda."</string>
<string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" - "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Hiq"</string>
- <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Shërbimi në plan të parë i nisur në sfond nga <xliff:g id="PACKAGENAME">%1$s</xliff:g> nuk do të ketë lejen e nevojshme gjatë përdorimit në ndërtimet e ardhshme R. Shiko go/r-bg-fgs-restriction dhe dërgo një raport të defekteve në kod."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Të ngrihet volumi mbi nivelin e rekomanduar?\n\nDëgjimi me volum të lartë për periudha të gjata mund të dëmtojë dëgjimin."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Të përdoret shkurtorja e qasshmërisë?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Kur shkurtorja është e aktivizuar, shtypja e të dy butonave për 3 sekonda do të nisë një funksion qasshmërie."</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 269755a8cf76..6ca87a1fb926 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -1641,7 +1641,6 @@
<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="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Услуга у првом плану са <xliff:g id="PACKAGENAME">%1$s</xliff:g> која је покренута у позадини неће имати дозволу током коришћења у будућим R верзијама. Посетите go/r-bg-fgs-restriction и пошаљите извештај о грешци."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Желите да појачате звук изнад препорученог нивоа?\n\nСлушање гласне музике дуже време може да вам оштети слух."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Желите ли да користите пречицу за приступачност?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Када је пречица укључена, притисните оба дугмета за јачину звука да бисте покренули функцију приступачности."</string>
@@ -1665,7 +1664,7 @@
<string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Одбиј"</string>
<string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Додирните неку функцију да бисте почели да је користите:"</string>
<string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Одаберите функције које ћете користити са дугметом Приступачност"</string>
- <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Одаберите функције које ћете користити са тастером јачине звука као пречицом"</string>
+ <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="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Измените пречице"</string>
<string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Готово"</string>
@@ -1673,8 +1672,8 @@
<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>
- <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Задржали сте тастере за јачину звука. Услуга <xliff:g id="SERVICE_NAME">%1$s</xliff:g> је укључена."</string>
- <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Задржали сте тастере за јачину звука. Услуга <xliff:g id="SERVICE_NAME">%1$s</xliff:g> је искључена."</string>
+ <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Држали сте тастере за јачину звука. Услуга <xliff:g id="SERVICE_NAME">%1$s</xliff:g> је укључена."</string>
+ <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Држали сте тастере за јачину звука. Услуга <xliff:g id="SERVICE_NAME">%1$s</xliff:g> је искључена."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Притисните и задржите оба тастера за јачину звука три секунде да бисте користили <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Изаберите функцију која ће се користити када додирнете дугме Приступачност:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Одаберите функцију која ће се користити помоћу покрета за приступачност (помоћу два прста превуците нагоре од дна екрана):"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 566d85f24c08..8bbf7756b0d7 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -1619,12 +1619,11 @@
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"Du har ritat ditt grafiska lösenord fel <xliff:g id="NUMBER_0">%1$d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%2$d</xliff:g> försök ombeds du låsa upp mobilen med hjälp av ett e-postkonto.\n\n Försök igen om <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunder."</string>
<string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" – "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Ta bort"</string>
- <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Förgrundstjänsten från <xliff:g id="PACKAGENAME">%1$s</xliff:g> som startades i bakgrunden får inte behörighet som gäller vid användning i framtida R-versioner. Besök go/r-bg-fgs-restriction och skicka en felrapport."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Vill du höja volymen över den rekommenderade nivån?\n\nAtt lyssna med stark volym långa stunder åt gången kan skada hörseln."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Vill du använda Aktivera tillgänglighet snabbt?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"När kortkommandot har aktiverats startar du en tillgänglighetsfunktion genom att trycka ned båda volymknapparna i tre sekunder."</string>
<string name="accessibility_shortcut_multiple_service_warning_title" msgid="8417489297036013065">"Vill du aktivera tillgänglighetsfunktionerna?"</string>
- <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"Om du trycker ned båda volymknapparna i ett par sekunder aktiveras tillgänglighetsfunktionerna. Det kan leda till att enheten fungerar annorlunda.\n\nAktuella funktioner:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nDu kan ändra vilka funktioner som aktiveras under Inställningar &gt; Tillgänglighet."</string>
+ <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"Om du trycker ned båda volymknapparna i ett par sekunder aktiveras tillgänglighetsfunktionerna. Det kan få enheten ett fungera annorlunda.\n\nAktuella funktioner:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nDu kan ändra vilka funktioner som aktiveras under Inställningar &gt; Tillgänglighet."</string>
<string name="accessibility_shortcut_multiple_service_list" msgid="6935581470716541531">" • <xliff:g id="SERVICE">%1$s</xliff:g>\n"</string>
<string name="accessibility_shortcut_single_service_warning_title" msgid="2819109500943271385">"Vill du aktivera <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
<string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Om du trycker ned båda volymknapparna i ett par sekunder aktiveras <xliff:g id="SERVICE">%1$s</xliff:g>, en tillgänglighetsfunktion. Det kan leda till att enheten fungerar annorlunda.\n\nDu kan ändra vilken funktion som ska aktiveras med genvägen under Inställningar &gt; Tillgänglighet."</string>
@@ -1643,7 +1642,7 @@
<string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Neka"</string>
<string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Tryck på funktioner som du vill aktivera:"</string>
<string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Välj vilka funktioner du vill använda med hjälp av tillgänglighetsknappen"</string>
- <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Välj vilka funktioner du vill använda med hjälp av kortkommandot för volymknapparna"</string>
+ <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Välj att funktioner att använda med hjälp av volymknappskortkommandot"</string>
<string name="accessibility_uncheck_legacy_item_warning" msgid="8047830891064817447">"<xliff:g id="SERVICE_NAME">%s</xliff:g> har inaktiverats"</string>
<string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Redigera genvägar"</string>
<string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Klar"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index f4745c6c9bfd..7a5cdcffbefa 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -1619,7 +1619,6 @@
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"Umekosea kuchora mchoro wako wa kufungua mara <xliff:g id="NUMBER_0">%1$d</xliff:g>. Baada ya majaribio <xliff:g id="NUMBER_1">%2$d</xliff:g> yasiyofaulu, utaombwa kufungua simu yako kwa kutumia akaunti ya barua pepe.\n\n Jaribu tena baada ya sekunde <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">"Ondoa"</string>
- <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Huduma ya programu inayotumika iliyoanzishwa chinichini kwenye <xliff:g id="PACKAGENAME">%1$s</xliff:g> haitakuwa na ruhusa inapotumika katika miundo ijayo ya R. Tafadhali angalia go/r-bg-fgs-restriction na uwasilishe ripoti ya hitilafu."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Ungependa kupandisha sauti zaidi ya kiwango kinachopendekezwa?\n\nKusikiliza kwa sauti ya juu kwa muda mrefu kunaweza kuharibu uwezo wako wa kusikia."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Ungependa kutumia njia ya mkato ya ufikivu?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Unapowasha kipengele cha njia ya mkato, hatua ya kubonyeza vitufe vyote viwili vya sauti kwa sekunde tatu itafungua kipengele cha ufikivu."</string>
@@ -1652,7 +1651,7 @@
<string name="color_inversion_feature_name" msgid="326050048927789012">"Ugeuzaji rangi"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Usahihishaji wa rangi"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Vitufe vya sauti vilivyoshikiliwa. Umewasha <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
- <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Vitufe vya sauti vilivyoshikiliwa. Umezima <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
+ <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Vitufe vya sauti vimeshikiliwa. Umezima <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Bonyeza na ushikilie vitufe vyote viwili vya sauti kwa sekunde tatu ili utumie <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Chagua kipengele utakachotumia ukigusa kitufe cha ufikivu:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Chagua kipengele cha kutumia pamoja na ishara ya ufikivu (telezesha vidole viwili kutoka chini kwenda juu kwenye skrini):"</string>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 2eb8c87e68e1..32ea9795ed9d 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -1619,7 +1619,6 @@
<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="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> இல் இருந்து பின்னணியில் தொடங்கப்பட்ட முன்புலச் சேவைக்கு, வரவுள்ள R பதிப்புகளில் உபயோகத்தின்போது மட்டுமான அனுமதி இருக்காது. go/r-bg-fgs-restriction என்பதைப் பார்த்து பிழை அறிக்கை ஒன்றைச் சமர்ப்பிக்கவும்."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"பரிந்துரைத்த அளவை விட ஒலியை அதிகரிக்கவா?\n\nநீண்ட நேரத்திற்கு அதிகளவில் ஒலி கேட்பது கேட்கும் திறனைப் பாதிக்கலாம்."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"அணுகல்தன்மை ஷார்ட்கட்டைப் பயன்படுத்தவா?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"ஷார்ட்கட் இயக்கத்தில் இருக்கும்போது ஒலியளவு பட்டன்கள் இரண்டையும் 3 வினாடிகளுக்கு அழுத்தினால் அணுகல்தன்மை அம்சம் இயக்கப்படும்."</string>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index 0251d721492a..fe392d461eba 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -1311,7 +1311,7 @@
<string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"డీబగ్గింగ్‌ని నిలిపివేయడానికి ఎంచుకోండి."</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>
+ <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"వైర్‌లెస్ డీబగ్గింగ్‌ను డిజేబుల్ చేయడానికి ఎంచుకోండి."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"పరీక్ష నియంత్రణ మోడ్ ప్రారంభించబడింది"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"పరీక్ష నియంత్రణ మోడ్‌ను నిలిపివేయడానికి ఫ్యాక్టరీ రీసెట్‍‌ను అమలు చేయండి."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"సీరియల్ కన్సోల్ ప్రారంభించబడింది"</string>
@@ -1619,12 +1619,11 @@
<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="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> నుండి, బ్యాక్‌గ్రౌండ్‌లో ప్రారంభమైన ఫోర్ గ్రౌండ్ సేవకు భవిష్యత్తు R బిల్డ్స్‌లో \'ఉపయోగంలో వున్నప్పుడు\' అనుమతి ఉండదు. దయచేసి go/r-bg-fgs-restrictionను చూసి బగ్ నివేదికను ఫైల్ చేయండి."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"వాల్యూమ్‌ను సిఫార్సు చేయబడిన స్థాయి కంటే ఎక్కువగా పెంచాలా?\n\nసుదీర్ఘ వ్యవధుల పాటు అధిక వాల్యూమ్‌లో వినడం వలన మీ వినికిడి శక్తి దెబ్బ తినవచ్చు."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"యాక్సెస్ సామర్థ్యం షార్ట్‌కట్‌ను ఉపయోగించాలా?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"షార్ట్‌కట్ ఆన్ చేసి ఉన్నప్పుడు, రెండు వాల్యూమ్ బటన్‌లను 3 సెకన్ల పాటు నొక్కి ఉంచితే యాక్సెస్ సౌలభ్య ఫీచర్ ప్రారంభం అవుతుంది."</string>
<string name="accessibility_shortcut_multiple_service_warning_title" msgid="8417489297036013065">"యాక్సెసిబిలిటీ‌లను ఆన్ చేయాలా?"</string>
- <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"రెండు వాల్యూమ్ కీలను కొంత సేపు నొక్కి పట్టుకోవడం ద్వారా యాక్సెసిబిలిటీలు ఆన్ అవుతాయి. ఇది మీ పరికరం పనిచేసే విధానాన్ని మార్చవచ్చు.\n\nప్రస్తుత ఫీచర్లు:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nఎంపిక చేసిన ఫీచర్లను మీరు సెట్టింగ్‌లు&gt;యాక్సెసిబిలిటీలో మార్చవచ్చు."</string>
+ <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"రెండు వాల్యూమ్ కీలను కొంత సేపు నొక్కి పట్టుకుంటే యాక్సెసిబిలిటీలు ఆన్ అవుతాయి. ఇది మీ పరికరం పనిచేసే విధానాన్ని మార్చవచ్చు.\n\nప్రస్తుత ఫీచర్లు:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nఎంపిక చేసిన ఫీచర్లను మీరు సెట్టింగ్‌లు&gt;యాక్సెసిబిలిటీలో మార్చవచ్చు."</string>
<string name="accessibility_shortcut_multiple_service_list" msgid="6935581470716541531">" • <xliff:g id="SERVICE">%1$s</xliff:g>\n"</string>
<string name="accessibility_shortcut_single_service_warning_title" msgid="2819109500943271385">"<xliff:g id="SERVICE">%1$s</xliff:g> ఆన్ చేయాాలా?"</string>
<string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"రెండు వాల్యూమ్ కీలను కొన్ని సెకన్ల పాటు నొక్కి పట్టుకోవడం ద్వారా యాక్సెసిబిలిటీ అయిన <xliff:g id="SERVICE">%1$s</xliff:g> ఆన్ అవుతుంది. ఇది మీ పరికరం పని చేసే విధానాన్ని మార్చవచ్చు.\n\nసెట్టింగ్‌లు &gt; యాక్సెసిబిలిటీలో, వేరొక ఫీచర్‌ను ప్రారంభించేలా ఈ షార్ట్ కట్‌ను మీరు మార్చవచ్చు."</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 683b22fa7396..000ad10827a4 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -1309,7 +1309,7 @@
<string name="adb_active_notification_title" msgid="408390247354560331">"เชื่อมต่อการแก้ไขข้อบกพร่อง USB แล้ว"</string>
<string name="adb_active_notification_message" msgid="5617264033476778211">"แตะเพื่อปิดการแก้ไขข้อบกพร่อง USB"</string>
<string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"เลือกเพื่อปิดใช้งานการแก้ไขข้อบกพร่อง USB"</string>
- <string name="adbwifi_active_notification_title" msgid="6147343659168302473">"เชื่อมต่อการแก้ไขข้อบกพร่องผ่าน Wi-Fi"</string>
+ <string name="adbwifi_active_notification_title" msgid="6147343659168302473">"เชื่อมต่อการแก้ไขข้อบกพร่องผ่าน Wi-Fi แล้ว"</string>
<string name="adbwifi_active_notification_message" msgid="930987922852867972">"แตะเพื่อปิดการแก้ไขข้อบกพร่องผ่าน Wi-Fi"</string>
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"เลือกเพื่อปิดใช้การแก้ไขข้อบกพร่องผ่าน Wi-Fi"</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"โหมดโปรแกรมทดสอบอัตโนมัติเปิดใช้อยู่"</string>
@@ -1619,7 +1619,6 @@
<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="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"บริการที่ทำงานอยู่เบื้องหน้าซึ่งเริ่มขึ้นในเบื้องหลังจาก <xliff:g id="PACKAGENAME">%1$s</xliff:g> จะไม่มีสิทธิ์ขณะใช้งานใน R บิลด์ต่อๆ ไป โปรดดู go/r-bg-fgs-restriction และส่งรายงานข้อบกพร่อง"</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"นี่เป็นการเพิ่มระดับเสียงเกินระดับที่แนะนำ\n\nการฟังเสียงดังเป็นเวลานานอาจทำให้การได้ยินของคุณบกพร่องได้"</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"ใช้ทางลัดการช่วยเหลือพิเศษไหม"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"เมื่อทางลัดเปิดอยู่ การกดปุ่มปรับระดับเสียงทั้ง 2 ปุ่มนาน 3 วินาทีจะเริ่มฟีเจอร์การช่วยเหลือพิเศษ"</string>
@@ -1650,7 +1649,7 @@
<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>
+ <string name="color_correction_feature_name" msgid="3655077237805422597">"การแก้สี"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"กดปุ่มปรับระดับเสียงค้างไว้แล้ว เปิด <xliff:g id="SERVICE_NAME">%1$s</xliff:g> แล้ว"</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"กดปุ่มปรับระดับเสียงค้างไว้แล้ว ปิด <xliff:g id="SERVICE_NAME">%1$s</xliff:g> แล้ว"</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"กดปุ่มปรับระดับเสียงทั้ง 2 ปุ่มค้างไว้ 3 วินาทีเพื่อใช้ <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 45c8e349e5f0..f2ee40453df8 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -1417,7 +1417,7 @@
<string name="forward_intent_to_work" msgid="3620262405636021151">"Ginagamit mo ang app na ito sa iyong profile sa trabaho"</string>
<string name="input_method_binding_label" msgid="1166731601721983656">"Pamamaraan ng pag-input"</string>
<string name="sync_binding_label" msgid="469249309424662147">"I-sync"</string>
- <string name="accessibility_binding_label" msgid="1974602776545801715">"Pagiging Accessible"</string>
+ <string name="accessibility_binding_label" msgid="1974602776545801715">"Accessibility"</string>
<string name="wallpaper_binding_label" msgid="1197440498000786738">"Wallpaper"</string>
<string name="chooser_wallpaper" msgid="3082405680079923708">"Baguhin ang wallpaper"</string>
<string name="notification_listener_binding_label" msgid="2702165274471499713">"Notification listener"</string>
@@ -1619,15 +1619,14 @@
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"Naguhit mo nang hindi tama ang iyong pattern sa pag-unlock nang <xliff:g id="NUMBER_0">%1$d</xliff:g> (na) beses. Pagkatapos ng <xliff:g id="NUMBER_1">%2$d</xliff:g> pang hindi matagumpay na pagtatangka, hihilingin sa iyong i-unlock ang telepono mo gamit ang isang email account.\n\n Subukang muli sa loob ng <xliff:g id="NUMBER_2">%3$d</xliff:g> (na) segundo."</string>
<string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Alisin"</string>
- <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Ang sinimulan sa background na serbisyo sa foreground mula sa <xliff:g id="PACKAGENAME">%1$s</xliff:g> ay hindi magkakaroon ng pahintulot habang ginagamit sa mga R build sa hinaharap. Pakipuntahan ang go/r-bg-fgs-restriction at maghain ng bugreport."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Lakasan ang volume nang lagpas sa inirerekomendang antas?\n\nMaaaring mapinsala ng pakikinig sa malakas na volume sa loob ng mahahabang panahon ang iyong pandinig."</string>
- <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Gagamitin ang Shortcut sa Pagiging Accessible?"</string>
+ <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Gagamitin ang Shortcut sa Accessibility?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Kapag naka-on ang shortcut, magsisimula ang isang feature ng pagiging naa-access kapag pinindot ang parehong button ng volume."</string>
- <string name="accessibility_shortcut_multiple_service_warning_title" msgid="8417489297036013065">"I-on ang mga feature ng pagiging accessible?"</string>
- <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"Mao-on ang mga feature ng pagiging accessible kapag pinindot nang matagal ang parehong volume key nang ilang segundo. Posibleng mabago nito ang paggana ng iyong device.\n\nMga kasalukuyang feature:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nPuwede mong baguhin ang mga napiling feature sa Mga Setting &gt; Pagiging Accessible."</string>
+ <string name="accessibility_shortcut_multiple_service_warning_title" msgid="8417489297036013065">"I-on ang mga feature ng accessibility?"</string>
+ <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"Mao-on ang mga feature ng accessibility kapag pinindot nang matagal ang parehong volume key nang ilang segundo. Posibleng mabago nito ang paggana ng iyong device.\n\nMga kasalukuyang feature:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nPuwede mong baguhin ang mga napiling feature sa Mga Setting &gt; Accessibility."</string>
<string name="accessibility_shortcut_multiple_service_list" msgid="6935581470716541531">" • <xliff:g id="SERVICE">%1$s</xliff:g>\n"</string>
<string name="accessibility_shortcut_single_service_warning_title" msgid="2819109500943271385">"I-on ang <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
- <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Mao-on ang feature ng pagiging accessible na <xliff:g id="SERVICE">%1$s</xliff:g> kapag pinindot nang matagal ang parehong volume key nang ilang segundo. Posibleng mabago nito ang paggana ng iyong device.\n\nPuwede mong palitan ng ibang feature ang shortcut na ito sa Mga Setting &gt; Pagiging Accessible."</string>
+ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Mao-on ang feature ng accessibility na <xliff:g id="SERVICE">%1$s</xliff:g> kapag pinindot nang matagal ang parehong volume key nang ilang segundo. Posibleng mabago nito ang paggana ng iyong device.\n\nPuwede mong palitan ng ibang feature ang shortcut na ito sa Mga Setting &gt; Accessibility."</string>
<string name="accessibility_shortcut_on" msgid="5463618449556111344">"I-on"</string>
<string name="accessibility_shortcut_off" msgid="3651336255403648739">"Huwag i-on"</string>
<string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"NAKA-ON"</string>
@@ -1651,12 +1650,12 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Gamitin ang Shortcut"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Pag-invert ng Kulay"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Pagwawasto ng Kulay"</string>
- <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Mga volume key na pinipindot nang matagal. Na-on ang <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
+ <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Pinindot nang matagal ang volume keys. Na-on ang <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Mga volume key na pinipindot nang matagal. Na-off ang <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Pindutin nang matagal ang parehong volume key sa loob ng tatlong segundo para magamit ang <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Pumili ng feature na gagana sa pamamagitan ng pag-tap mo sa button ng accessibility:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Pumili ng feature na gagana sa pamamagitan ng galaw ng pagiging accessible (pag-swipe pataas mula sa ibaba ng screen gamit ang dalawang daliri):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Pumili ng feature na gagana sa pamamagitan ng galaw ng pagiging accessible (pag-swipe pataas mula sa ibaba ng screen gamit ang tatlong daliri):"</string>
+ <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Pumili ng feature na gagana sa pamamagitan ng galaw ng accessibility (pag-swipe pataas mula sa ibaba ng screen gamit ang dalawang daliri):"</string>
+ <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Pumili ng feature na gagana sa pamamagitan ng galaw ng accessibility (pag-swipe pataas mula sa ibaba ng screen gamit ang tatlong daliri):"</string>
<string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Para magpalipat-lipat sa mga feature, pindutin nang matagal ang button ng accessibility."</string>
<string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Para magpalipat-lipat sa mga feature, mag-swipe pataas gamit ang dalawang daliri at i-hold ito."</string>
<string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Para magpalipat-lipat sa mga feature, mag-swipe pataas gamit ang tatlong daliri at i-hold ito."</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index bb9ffc066917..19bdba898eb9 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -1619,7 +1619,6 @@
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"Kilit açma deseninizi <xliff:g id="NUMBER_0">%1$d</xliff:g> kez yanlış çizdiniz. <xliff:g id="NUMBER_1">%2$d</xliff:g> başarısız denemeden sonra telefonunuzu bir e-posta hesabı kullanarak açmanız istenir.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> saniye içinde tekrar deneyin."</string>
<string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Kaldır"</string>
- <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> paketinden ön plan hizmetini başlatan arka plan, sonraki R derlemelerinde kullanım sırasında iznine sahip olmayacak. Lütfen go/r-bg-fgs-restriction sayfasına bakıp hata raporu girin."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Ses seviyesi önerilen düzeyin üzerine yükseltilsin mi?\n\nUzun süre yüksek ses seviyesinde dinlemek işitme duyunuza zarar verebilir."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Erişilebilirlik Kısayolu Kullanılsın mı?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Kısayol açıkken ses düğmelerinin ikisini birden 3 saniyeliğine basılı tutmanız bir erişilebilirlik özelliğini başlatır."</string>
@@ -1651,8 +1650,8 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Kısayolu Kullan"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Rengi Ters Çevirme"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Renk Düzeltme"</string>
- <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Ses tuşlarını basılı tutun. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> açıldı."</string>
- <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Ses tuşlarını basılı tutun. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> kapatıldı."</string>
+ <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Ses tuşlarını basılı tuttunuz. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> açıldı."</string>
+ <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Ses tuşlarını basılı tuttunuz. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> kapatıldı."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> hizmetini kullanmak için her iki ses tuşunu basılı tutun"</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Erişilebilirlik düğmesine dokunduğunuzda kullanmak için bir özellik seçin:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Erişilebilirlik hareketiyle (iki parmakla ekranın altından yukarı kaydırma) kullanılacak bir özellik seçin:"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 6b24d83e7038..04bb1cc33c61 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -1349,9 +1349,9 @@
<string name="adb_active_notification_title" msgid="408390247354560331">"Налагодження USB підключено"</string>
<string name="adb_active_notification_message" msgid="5617264033476778211">"Торкніться, щоб вимкнути налагодження через USB"</string>
<string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"Виберіть, щоб вимкнути налагодження за USB"</string>
- <string name="adbwifi_active_notification_title" msgid="6147343659168302473">"Налагодження через Wi-Fi активне"</string>
+ <string name="adbwifi_active_notification_title" msgid="6147343659168302473">"Активне налагодження через Wi-Fi"</string>
<string name="adbwifi_active_notification_message" msgid="930987922852867972">"Натисніть, щоб вимкнути налагодження через Wi-Fi"</string>
- <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Виберіть, щоб вимкнути налагодження через Wi-Fi."</string>
+ <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Натисніть, щоб вимкнути налагодження."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Увімкнено режим автоматизованого тестування"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Щоб вимкнути режим автоматизованого тестування, відновіть заводські налаштування."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"Послідовну консоль увімкнено"</string>
@@ -1663,12 +1663,11 @@
<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="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Активний сервіс пакета <xliff:g id="PACKAGENAME">%1$s</xliff:g>, запущений у фоновому режимі, не матиме дозволу \"Коли додаток використовується\" в майбутніх складаннях R. Перегляньте go/r-bg-fgs-restriction і надішліть звіт про помилки."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Збільшити гучність понад рекомендований рівень?\n\nЯкщо слухати надто гучну музику тривалий час, можна пошкодити слух."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Використовувати швидке ввімкнення?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Якщо цей засіб увімкнено, ви можете активувати спеціальні можливості, утримуючи обидві кнопки гучності протягом трьох секунд."</string>
<string name="accessibility_shortcut_multiple_service_warning_title" msgid="8417489297036013065">"Увімкнути спеціальні можливості?"</string>
- <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"Якщо втримувати обидві клавіші гучності впродовж кількох секунд, буде ввімкнено спеціальні можливості. Це може вплинути на роботу пристрою.\n\nПоточні функції:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nВибрані функції можна змінити в меню \"Налаштування &gt; Спеціальні можливості\"."</string>
+ <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"Якщо втримувати обидві клавіші гучності впродовж кількох секунд, вмикаються спеціальні можливості. Це впливає на роботу пристрою.\n\nПоточні функції:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nВибрані функції можна змінити в налаштуваннях у меню спеціальних можливостей."</string>
<string name="accessibility_shortcut_multiple_service_list" msgid="6935581470716541531">" • <xliff:g id="SERVICE">%1$s</xliff:g>\n"</string>
<string name="accessibility_shortcut_single_service_warning_title" msgid="2819109500943271385">"Увімкнути <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
<string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Якщо втримувати обидві клавіші гучності впродовж кількох секунд, буде ввімкнено спеціальні можливості – <xliff:g id="SERVICE">%1$s</xliff:g>. Це може вплинути на роботу пристрою.\n\nДля цієї комбінації клавіш можна вибрати іншу функцію в меню \"Налаштування &gt; Спеціальні можливості\"."</string>
@@ -1820,7 +1819,7 @@
<string name="restr_pin_try_later" msgid="5897719962541636727">"Спробуйте пізніше"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"Перегляд на весь екран"</string>
<string name="immersive_cling_description" msgid="7092737175345204832">"Щоб вийти, проведіть пальцем зверху вниз."</string>
- <string name="immersive_cling_positive" msgid="7047498036346489883">"Зрозуміло"</string>
+ <string name="immersive_cling_positive" msgid="7047498036346489883">"OK"</string>
<string name="done_label" msgid="7283767013231718521">"Готово"</string>
<string name="hour_picker_description" msgid="5153757582093524635">"Вибір годин на циферблаті"</string>
<string name="minute_picker_description" msgid="9029797023621927294">"Вибір хвилин на циферблаті"</string>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index b432f80fce0e..0b44c5236f32 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -1128,7 +1128,7 @@
<string name="whichViewApplication" msgid="5733194231473132945">"اس کے ساتھ کھولیں"</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="whichOpenHostLinksWith" msgid="7645631470199397485">"‫‫<xliff:g id="HOST">%1$s</xliff:g> لنکس اس کے ساتھ کھولیں"</string>
<string name="whichOpenLinksWith" msgid="1120936181362907258">"اس کے ساتھ لنکس کھولیں"</string>
<string name="whichOpenLinksWithApp" msgid="6917864367861910086">"<xliff:g id="APPLICATION">%1$s</xliff:g> کے ذریعے لنکس کھولیں"</string>
<string name="whichOpenHostLinksWithApp" msgid="2401668560768463004">"<xliff:g id="HOST">%1$s</xliff:g> لنکس کو <xliff:g id="APPLICATION">%2$s</xliff:g> کے ذریعے کھولیں"</string>
@@ -1311,7 +1311,7 @@
<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>
+ <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"وائرلیس ڈیبگنگ کو غیر فعال کرنے کے ليے منتخب کریں۔"</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"ٹیسٹ ہارنیس موڈ فعال ہے"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"ٹیسٹ ہارنیس موڈ غیر فعال کرنے کے لیے فیکٹری ری سیٹ کریں۔"</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"شمار کونسول فعال ہے"</string>
@@ -1619,7 +1619,6 @@
<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="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"‏پس منظر <xliff:g id="PACKAGENAME">%1$s</xliff:g> سے شروع کی گئی پیش منظر کی سروس کو مستقبل کے R بلڈز میں استعمال کے دوران اجازت نہیں ہوگی۔ براہ کرم go/r-bg-fgs-restriction دیکھیں اور بگ رپورٹ دائر کریں۔"</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"والیوم کو تجویز کردہ سطح سے زیادہ کریں؟\n\nزیادہ وقت تک اونچی آواز میں سننے سے آپ کی سماعت کو نقصان پہنچ سکتا ہے۔"</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"ایکسیسبیلٹی شارٹ کٹ استعمال کریں؟"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"شارٹ کٹ آن ہونے پر، 3 سیکنڈ تک دونوں والیوم بٹنز کو دبانے سے ایک ایکسیسبیلٹی خصوصیت شروع ہو جائے گی۔"</string>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index fffa26553312..89550ae0f145 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -1619,7 +1619,6 @@
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"Siz grafik kalitni <xliff:g id="NUMBER_0">%1$d</xliff:g> marta noto‘g‘ri chizdingiz. <xliff:g id="NUMBER_1">%2$d</xliff:g> marta muvaffaqiyatsiz urinishdan so‘ng, sizdan e-pochtangizdan foydalanib, telefon qulfini ochishingiz so‘raladi.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> soniyadan so‘ng yana urinib ko‘ring."</string>
<string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Olib tashlash"</string>
- <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Fonda faol <xliff:g id="PACKAGENAME">%1$s</xliff:g> xizmatini ishga tushirish uchun kelgusi R nashrlarida ishlatilayotganda ruxsat berish imkoniyati boʻlmaydi. go/r-bg-fgs-restriction sahifasiga kiring va xatolik hisobotini yuboring."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Tovush balandligi tavsiya etilgan darajadan ham yuqori qilinsinmi?\n\nUzoq vaqt davomida baland ovozda tinglash eshitish qobiliyatingizga salbiy ta’sir ko‘rsatishi mumkin."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Tezkor ishga tushirishdan foydalanilsinmi?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Maxsus imkoniyatlar funksiyasidan foydalanish uchun u yoniqligida ikkala tovush tugmasini 3 soniya bosib turing."</string>
@@ -1641,9 +1640,9 @@
<string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Ilova yoki qurilma sensori bilan munosabatlaringizni kuzatishi hamda sizning nomingizdan ilovalar bilan ishlashi mumkin."</string>
<string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Ruxsat"</string>
<string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Rad etish"</string>
- <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Funksiyadan foydalanish uchun ustiga bosing:"</string>
+ <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Kerakli funksiyani tanlang"</string>
<string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Maxsus imkoniyatlar tugmasi bilan foydalanish uchun funksiyalarni tanlang"</string>
- <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Tovush balandligi tugmasi bilan foydalanish uchun funksiyalarni tanlang"</string>
+ <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Tovush tugmasi bilan ishga tushiriladigan funksiyalarni tanlang"</string>
<string name="accessibility_uncheck_legacy_item_warning" msgid="8047830891064817447">"<xliff:g id="SERVICE_NAME">%s</xliff:g> faolsizlantirildi"</string>
<string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Tezkor tugmalarni tahrirlash"</string>
<string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"OK"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 7ecad59d4162..f53c161cbd0c 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -1619,7 +1619,6 @@
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"Bạn đã <xliff:g id="NUMBER_0">%1$d</xliff:g> lần vẽ không chính xác hình mở khóa của mình. Sau <xliff:g id="NUMBER_1">%2$d</xliff:g> lần thử không thành công nữa, bạn sẽ được yêu cầu mở khóa điện thoại bằng tài khoản email.\n\n Vui lòng thử lại sau <xliff:g id="NUMBER_2">%3$d</xliff:g> giây."</string>
<string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Xóa"</string>
- <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Dịch vụ trên nền trước đã bắt đầu ở nền từ <xliff:g id="PACKAGENAME">%1$s</xliff:g> sẽ không có quyền khi đang sử dụng trong các bản dựng R trong tương lai. Vui lòng xem go/r-bg-fgs-restriction và gửi báo cáo lỗi."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Bạn tăng âm lượng lên quá mức khuyên dùng?\n\nViệc nghe ở mức âm lượng cao trong thời gian dài có thể gây tổn thương thính giác của bạn."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Sử dụng phím tắt Hỗ trợ tiếp cận?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Khi phím tắt này đang bật, thao tác nhấn cả hai nút âm lượng trong 3 giây sẽ mở tính năng hỗ trợ tiếp cận."</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 6e2b78b0de93..d04c6187d6c6 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -92,7 +92,7 @@
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"紧急回拨模式"</string>
<string name="notification_channel_mobile_data_status" msgid="1941911162076442474">"移动数据状态"</string>
<string name="notification_channel_sms" msgid="1243384981025535724">"短信"</string>
- <string name="notification_channel_voice_mail" msgid="8457433203106654172">"语音邮件"</string>
+ <string name="notification_channel_voice_mail" msgid="8457433203106654172">"语音信息"</string>
<string name="notification_channel_wfc" msgid="9048240466765169038">"WLAN 通话"</string>
<string name="notification_channel_sim" msgid="5098802350325677490">"SIM 卡状态"</string>
<string name="notification_channel_sim_high_prio" msgid="642361929452850928">"高优先顺序 SIM 卡状态"</string>
@@ -958,7 +958,7 @@
<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="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>
@@ -1619,7 +1619,6 @@
<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="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"在未来的 R 版本中,在后台启动的 <xliff:g id="PACKAGENAME">%1$s</xliff:g> 中的前台服务将不具有仅在使用时授予的权限。请访问 go/r-bg-fgs-restriction 并提交错误报告。"</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"要将音量调高到建议的音量以上吗?\n\n长时间保持高音量可能会损伤听力。"</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"要使用无障碍快捷方式吗?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"启用这项快捷方式后,同时按下两个音量按钮 3 秒钟即可启动无障碍功能。"</string>
@@ -1651,8 +1650,8 @@
<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>
- <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"按住音量键。<xliff:g id="SERVICE_NAME">%1$s</xliff:g>已开启。"</string>
- <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"按住音量键。<xliff:g id="SERVICE_NAME">%1$s</xliff:g>已关闭。"</string>
+ <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"已按住音量键。<xliff:g id="SERVICE_NAME">%1$s</xliff:g>已开启。"</string>
+ <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"已按住音量键。<xliff:g id="SERVICE_NAME">%1$s</xliff:g>已关闭。"</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"同时按住两个音量键 3 秒钟即可使用 <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"选择点按“无障碍”按钮后要使用的功能:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"选择要搭配无障碍手势(用两根手指从屏幕底部向上滑动)使用的功能:"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index f808f900cdc0..458c3619c02f 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -1619,11 +1619,10 @@
<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="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"從「<xliff:g id="PACKAGENAME">%1$s</xliff:g>」啟動前景服務的背景將不會在未來的 R 版本中提供「僅在使用此應用程式時允許」權限。請參閱 go/r-bg-fgs-restriction,提交錯誤報告。"</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"要調高音量 (比建議的音量更大聲) 嗎?\n\n長時間聆聽高分貝音量可能會導致您的聽力受損。"</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"要使用無障礙功能快速鍵嗎?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"啟用快速鍵後,同時按住音量按鈕 3 秒便可啟用無障礙功能。"</string>
- <string name="accessibility_shortcut_multiple_service_warning_title" msgid="8417489297036013065">"要啟用無障礙功能嗎?"</string>
+ <string name="accessibility_shortcut_multiple_service_warning_title" msgid="8417489297036013065">"要開啟無障礙功能嗎?"</string>
<string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"同時按下兩個音量鍵幾秒,以開啟無障礙功能。這可能會變更裝置的運作。\n\n目前功能:\n<xliff:g id="SERVICE">%1$s</xliff:g>\n您可在「設定」&gt;「無障礙功能」中變更所選功能。"</string>
<string name="accessibility_shortcut_multiple_service_list" msgid="6935581470716541531">" • <xliff:g id="SERVICE">%1$s</xliff:g>\n"</string>
<string name="accessibility_shortcut_single_service_warning_title" msgid="2819109500943271385">"要啟用 <xliff:g id="SERVICE">%1$s</xliff:g> 嗎?"</string>
@@ -1643,7 +1642,7 @@
<string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"拒絕"</string>
<string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"輕按即可開始使用所需功能:"</string>
<string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"選擇要配搭無障礙功能按鈕使用的功能"</string>
- <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"選擇要配搭音量快速鍵使用的功能"</string>
+ <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="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"編輯捷徑"</string>
<string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"完成"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 559e681b178c..69358d44d737 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -1619,12 +1619,11 @@
<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="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"來自「<xliff:g id="PACKAGENAME">%1$s</xliff:g>」的背景啟動前景服務不會具備未來 R 版本的使用狀態權限。請前往 go/r-bg-fgs-restriction 並提交錯誤報告。"</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"要調高音量,比建議的音量更大聲嗎?\n\n長時間聆聽高分貝音量可能會使你的聽力受損。"</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"要使用無障礙捷徑嗎?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"啟用捷徑功能,只要同時按下兩個音量按鈕 3 秒,就能啟動無障礙功能。"</string>
<string name="accessibility_shortcut_multiple_service_warning_title" msgid="8417489297036013065">"要開啟無障礙功能嗎?"</string>
- <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"同時按住音量調高鍵和調低鍵數秒,即可開啟無障礙功能。這麼做可能會改變裝置的運作方式。\n\n目前的功能:\n<xliff:g id="SERVICE">%1$s</xliff:g>\n你可以在 [設定] &gt; [無障礙設定] 中變更所選功能。"</string>
+ <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"同時按住音量調高鍵和調低鍵數秒,即可開啟無障礙功能。這麼做可能會改變裝置的運作方式。\n\n目前的功能:\n<xliff:g id="SERVICE">%1$s</xliff:g>\n你可以在 [設定] &gt; [無障礙設定] 中變更選取的功能。"</string>
<string name="accessibility_shortcut_multiple_service_list" msgid="6935581470716541531">" • <xliff:g id="SERVICE">%1$s</xliff:g>\n"</string>
<string name="accessibility_shortcut_single_service_warning_title" msgid="2819109500943271385">"要開啟「<xliff:g id="SERVICE">%1$s</xliff:g>」嗎?"</string>
<string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"同時按住音量調高鍵和調低鍵數秒,即可開啟「<xliff:g id="SERVICE">%1$s</xliff:g>」無障礙功能。這麼做可能會改變裝置的運作方式。\n\n你可以在 [設定] &gt; [無障礙設定] 中變更這個快速鍵觸發的功能。"</string>
@@ -1919,7 +1918,7 @@
<string name="app_category_social" msgid="2278269325488344054">"社交和通訊"</string>
<string name="app_category_news" msgid="1172762719574964544">"新聞和雜誌"</string>
<string name="app_category_maps" msgid="6395725487922533156">"地圖和導航"</string>
- <string name="app_category_productivity" msgid="1844422703029557883">"生產應用"</string>
+ <string name="app_category_productivity" msgid="1844422703029557883">"工作效率"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"裝置儲存空間"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB 偵錯"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"點"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 3b95ffb497ba..4abd4404842c 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -1619,7 +1619,6 @@
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"Ukulayisha ungenisa iphathini yakho yokuvula ngendlela engalungile izikhathi ezi-<xliff:g id="NUMBER_0">%1$d</xliff:g> Emva kweminye imizamo engu-<xliff:g id="NUMBER_1">%2$d</xliff:g>, uzocelwa ukuvula ifoni yakho usebenzisa ukungena ngemvume ku-Google\n\n Zame futhi emumva kwengu- <xliff:g id="NUMBER_2">%3$d</xliff:g> amasekhondi."</string>
<string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Susa"</string>
- <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Ingemuva eqalise isevisi yasemuva kusuka ku-<xliff:g id="PACKAGENAME">%1$s</xliff:g> ngeke ithole imvume yokusebenzisa yesikhathi ekwakheni kwe-R ezayo. Sicela ubone i-go/r-bg-fgs-restriction bese ufayele umbiko wesiphazamiso."</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Khuphukisa ivolumu ngaphezu kweleveli enconyiwe?\n\nUkulalela ngevolumu ephezulu izikhathi ezide kungahle kulimaze ukuzwa kwakho."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Sebenzisa isinqamuleli sokufinyelela?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Uma isinqamuleli sivuliwe, ukucindezela zombili izinkinobho zevolumu amasekhondi angu-3 kuzoqalisa isici sokufinyelela."</string>
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index c413f8b036d7..1242c6dc8217 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -230,6 +230,7 @@
<color name="resolver_text_color_secondary_dark">#ffC4C6C6</color>
<color name="resolver_empty_state_text">#FF202124</color>
<color name="resolver_empty_state_icon">#FF5F6368</color>
+ <color name="chooser_chip_icon">#FF1A73E8</color> <!-- Blue 600 -->
<!-- Color for personal app suspension notification button text and icon tint. -->
<color name="personal_apps_suspension_notification_color">#1A73E8</color>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 0e11d49c93e5..39d20bbff3ba 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -403,33 +403,18 @@
<!-- Allowed unprivileged keepalive slots per uid. -->
<integer translatable="false" name="config_allowedUnprivilegedKeepalivePerUid">2</integer>
- <!-- List of regexpressions describing the interface (if any) that represent tetherable
- USB interfaces. If the device doesn't want to support tethering over USB this should
- be empty. An example would be "usb.*" -->
+ <!-- This setting is deprecated, please use
+ com.android.networkstack.tethering.R.array.config_tether_usb_regexs instead. -->
<string-array translatable="false" name="config_tether_usb_regexs">
</string-array>
- <!-- List of regexpressions describing the interface (if any) that represent tetherable
- Wifi interfaces. If the device doesn't want to support tethering over Wifi this
- should be empty. An example would be "softap.*" -->
+ <!-- This setting is deprecated, please use
+ com.android.networkstack.tethering.R.array.config_tether_wifi_regexs instead. -->
<string-array translatable="false" name="config_tether_wifi_regexs">
</string-array>
- <!-- List of regexpressions describing the interface (if any) that represent tetherable
- Wifi P2P interfaces. If the device doesn't want to support tethering over Wifi P2p this
- should be empty. An example would be "p2p-p2p.*" -->
- <string-array translatable="false" name="config_tether_wifi_p2p_regexs">
- </string-array>
-
- <!-- List of regexpressions describing the interface (if any) that represent tetherable
- WiMAX interfaces. If the device doesn't want to support tethering over Wifi this
- should be empty. An example would be "softap.*" -->
- <string-array translatable="false" name="config_tether_wimax_regexs">
- </string-array>
-
- <!-- List of regexpressions describing the interface (if any) that represent tetherable
- bluetooth interfaces. If the device doesn't want to support tethering over bluetooth this
- should be empty. -->
+ <!-- This setting is deprecated, please use
+ com.android.networkstack.tethering.R.array.config_tether_bluetooth_regexs instead. -->
<string-array translatable="false" name="config_tether_bluetooth_regexs">
</string-array>
@@ -437,7 +422,8 @@
updated config_tether_dhcp_range has to be updated appropriately. -->
<integer translatable="false" name="config_max_pan_devices">5</integer>
- <!-- Dhcp range (min, max) to use for tethering purposes -->
+ <!-- This setting is deprecated, please use
+ com.android.networkstack.tethering.R.array.config_dhcp_range instead. -->
<string-array translatable="false" name="config_tether_dhcp_range">
</string-array>
@@ -477,31 +463,8 @@
-->
</string-array>
- <!-- If the mobile hotspot feature requires provisioning, a package name and class name
- can be provided to launch a supported application that provisions the devices.
-
- Example Usage:
-
- String[] appDetails = getStringArray(R.array.config_mobile_hotspot_provision_app);
- Intent intent = new Intent(Intent.ACTION_MAIN);
- intent.setClassName(appDetails[0], appDetails[1]);
- startActivityForResult(intent, 0);
-
- public void onActivityResult(int requestCode, int resultCode, Intent intent) {
- super.onActivityResult(requestCode, resultCode, intent);
- if (requestCode == 0) {
- if (resultCode == Activity.RESULT_OK) {
- //Mobile hotspot provisioning successful
- } else {
- //Mobile hotspot provisioning failed
- }
- }
-
- See src/com/android/settings/TetherSettings.java for more details.
- For ui-less/periodic recheck support see config_mobile_hotspot_provision_app_no_ui
- -->
- <!-- The first element is the package name and the second element is the class name
- of the provisioning app -->
+ <!-- This setting is deprecated, please use
+ com.android.networkstack.tethering.R.array.config_mobile_hotspot_provision_app instead. -->
<string-array translatable="false" name="config_mobile_hotspot_provision_app">
<!--
<item>com.example.provisioning</item>
@@ -509,86 +472,33 @@
-->
</string-array>
- <!-- If the mobile hotspot feature requires provisioning, an action can be provided
- that will be broadcast in non-ui cases for checking the provisioning status.
-
- A second broadcast, action defined by config_mobile_hotspot_provision_response,
- will be sent back to notify if provisioning succeeded or not. The response will
- match that of the activity in config_mobile_hotspot_provision_app, but instead
- contained within the int extra "EntitlementResult".
-
- Example Usage:
- String provisionAction = getString(R.string.config_mobile_hotspot_provision_check);
- sendBroadcast(new Intent(provisionAction));
-
- public void onReceive(Context context, Intent intent) {
- String provisionResponse =
- getString(R.string.config_mobile_hotspot_provision_response);
- if (provisionResponse.equals(intent.getAction())
- && intent.getIntExtra("EntitlementResult") == Activity.RESULT_OK) {
- //Mobile hotspot provisioning successful
- } else {
- //Mobile hotspot provisioning failed
- }
- }
- -->
+ <!-- This setting is deprecated, please use
+ com.android.networkstack.tethering.R.string.config_mobile_hotspot_provision_app_no_ui
+ instead. -->
<string translatable="false" name="config_mobile_hotspot_provision_app_no_ui"></string>
- <!-- Sent in response to a provisioning check. The caller must hold the
- permission android.permission.TETHER_PRIVILEGED for Settings to
- receive this response.
- See config_mobile_hotspot_provision_response
- -->
+ <!-- This setting is deprecated, please use
+ com.android.networkstack.tethering.R.string.config_mobile_hotspot_provision_response
+ instead. -->
<string translatable="false" name="config_mobile_hotspot_provision_response"></string>
- <!-- Number of hours between each background provisioning call -->
+
+ <!-- This setting is deprecated, please use
+ com.android.networkstack.tethering.R.integer.config_mobile_hotspot_provision_check_period
+ instead. -->
<integer translatable="false" name="config_mobile_hotspot_provision_check_period">24</integer>
- <!-- Activity name to enable wifi tethering after provisioning app succeeds -->
+ <!-- This setting is deprecated, please use
+ com.android.networkstack.tethering.R.string.config_wifi_tether_enable instead. -->
<string translatable="false" name="config_wifi_tether_enable">com.android.settings/.wifi.tether.TetherService</string>
- <!-- Array of ConnectivityManager.TYPE_xxxx values allowable for tethering.
-
- Common options are [1, 4] for TYPE_WIFI and TYPE_MOBILE_DUN or
- [1,7,0] for TYPE_WIFI, TYPE_BLUETOOTH, and TYPE_MOBILE.
-
- This list is also modified by code within the framework, including:
-
- - TYPE_ETHERNET (9) is prepended to this list, and
-
- - the return value of TelephonyManager.isTetheringApnRequired()
- determines how the array is further modified:
-
- * TRUE (DUN REQUIRED).
- TYPE_MOBILE is removed (if present).
- TYPE_MOBILE_HIPRI is removed (if present).
- TYPE_MOBILE_DUN is appended (if not already present).
-
- * FALSE (DUN NOT REQUIRED).
- TYPE_MOBILE_DUN is removed (if present).
- If both of TYPE_MOBILE{,_HIPRI} are not present:
- TYPE_MOBILE is appended.
- TYPE_MOBILE_HIPRI is appended.
-
- For other changes applied to this list, now and in the future, see
- com.android.server.connectivity.tethering.TetheringConfiguration.
-
- Note also: the order of this is important. The first upstream type
- for which a satisfying network exists is used.
- -->
+ <!-- This setting is deprecated, please use
+ com.android.networkstack.tethering.R.array.config_tether_upstream_types. -->
<integer-array translatable="false" name="config_tether_upstream_types">
<item>1</item>
<item>7</item>
<item>0</item>
</integer-array>
- <!-- When true, the tethering upstream network follows the current default
- Internet network (except when the current default network is mobile,
- in which case a DUN network will be used if required).
-
- When true, overrides the config_tether_upstream_types setting above.
- -->
- <bool translatable="false" name="config_tether_upstream_automatic">true</bool>
-
<!-- If the DUN connection for this CDMA device supports more than just DUN -->
<!-- traffic you should list them here. -->
<!-- If this device is not CDMA this is ignored. If this list is empty on -->
@@ -2860,9 +2770,9 @@
-->
<string-array translatable="false" name="config_globalActionsList">
<item>emergency</item>
+ <item>lockdown</item>
<item>power</item>
<item>restart</item>
- <item>lockdown</item>
<item>logout</item>
<item>bugreport</item>
</string-array>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 2869021a8a72..e2fbbf46608f 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -3022,6 +3022,8 @@
<public type="id" name="accessibilitySystemActionTakeScreenshot" id="0x01020053" />
<public type="id" name="accessibilityActionImeEnter" id="0x01020054" />
+ <!-- @hide @TestApi -->
+ <public type="bool" name="config_assistantOnTopOfDream" id="0x01110005" />
<!-- ===============================================================
Resources added in version S of the platform
@@ -3054,7 +3056,7 @@
<!-- dimension definitions go here -->
</public-group>
- <public-group type="bool" first-id="0x01110005">
+ <public-group type="bool" first-id="0x01110006">
<!-- boolean definitions go here -->
</public-group>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index a1c2450be153..0c8745392f5e 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -4363,9 +4363,6 @@
<!-- The delete-widget drop target button text -->
<string name="kg_reordering_delete_drop_target_text">Remove</string>
- <!-- Toast message for background started foreground service while-in-use permission restriction feature -->
- <string name="allow_while_in_use_permission_in_fgs">The background started foreground service from <xliff:g id="packageName" example="com.example">%1$s</xliff:g> will not have while-in-use permission in future R builds. Please see go/r-bg-fgs-restriction and file a bugreport.</string>
-
<!-- Message shown in dialog when user is attempting to set the music volume above the
recommended maximum level for headphones -->
<string name="safe_media_volume_warning" product="default">
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 8e1dc8950155..871924255e66 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1851,10 +1851,8 @@
<java-symbol type="array" name="config_tether_bluetooth_regexs" />
<java-symbol type="array" name="config_tether_dhcp_range" />
<java-symbol type="array" name="config_tether_upstream_types" />
- <java-symbol type="bool" name="config_tether_upstream_automatic" />
<java-symbol type="array" name="config_tether_usb_regexs" />
<java-symbol type="array" name="config_tether_wifi_regexs" />
- <java-symbol type="array" name="config_tether_wifi_p2p_regexs" />
<java-symbol type="array" name="config_usbHostBlacklist" />
<java-symbol type="array" name="config_serialPorts" />
<java-symbol type="array" name="radioAttributes" />
@@ -4008,9 +4006,6 @@
<java-symbol type="dimen" name="resolver_empty_state_container_padding_top" />
<java-symbol type="dimen" name="resolver_empty_state_container_padding_bottom" />
- <!-- Toast message for background started foreground service while-in-use permission restriction feature -->
- <java-symbol type="string" name="allow_while_in_use_permission_in_fgs" />
-
<java-symbol type="string" name="config_deviceSpecificDisplayAreaPolicyProvider" />
<!-- Whether to expand the lock screen user switcher by default -->
diff --git a/core/tests/coretests/assets/SourceStampVerifierTest/stamp-apk-hash-mismatch.apk b/core/tests/coretests/assets/SourceStampVerifierTest/stamp-apk-hash-mismatch-v1.apk
index 1dc1e998f1ee..add4aa038708 100644
--- a/core/tests/coretests/assets/SourceStampVerifierTest/stamp-apk-hash-mismatch.apk
+++ b/core/tests/coretests/assets/SourceStampVerifierTest/stamp-apk-hash-mismatch-v1.apk
Binary files differ
diff --git a/core/tests/coretests/assets/SourceStampVerifierTest/stamp-apk-hash-mismatch-v2.apk b/core/tests/coretests/assets/SourceStampVerifierTest/stamp-apk-hash-mismatch-v2.apk
new file mode 100644
index 000000000000..e55eb903c68b
--- /dev/null
+++ b/core/tests/coretests/assets/SourceStampVerifierTest/stamp-apk-hash-mismatch-v2.apk
Binary files differ
diff --git a/core/tests/coretests/assets/SourceStampVerifierTest/stamp-apk-hash-mismatch-v3.apk b/core/tests/coretests/assets/SourceStampVerifierTest/stamp-apk-hash-mismatch-v3.apk
new file mode 100644
index 000000000000..de2355822093
--- /dev/null
+++ b/core/tests/coretests/assets/SourceStampVerifierTest/stamp-apk-hash-mismatch-v3.apk
Binary files differ
diff --git a/core/tests/coretests/assets/SourceStampVerifierTest/stamp-certificate-mismatch.apk b/core/tests/coretests/assets/SourceStampVerifierTest/stamp-certificate-mismatch.apk
index 562805cf67eb..f1105f96664c 100644
--- a/core/tests/coretests/assets/SourceStampVerifierTest/stamp-certificate-mismatch.apk
+++ b/core/tests/coretests/assets/SourceStampVerifierTest/stamp-certificate-mismatch.apk
Binary files differ
diff --git a/core/tests/coretests/assets/SourceStampVerifierTest/stamp-malformed-signature.apk b/core/tests/coretests/assets/SourceStampVerifierTest/stamp-malformed-signature.apk
index 2723cc8fdbeb..d28774aa2b14 100644
--- a/core/tests/coretests/assets/SourceStampVerifierTest/stamp-malformed-signature.apk
+++ b/core/tests/coretests/assets/SourceStampVerifierTest/stamp-malformed-signature.apk
Binary files differ
diff --git a/core/tests/coretests/assets/SourceStampVerifierTest/stamp-without-block.apk b/core/tests/coretests/assets/SourceStampVerifierTest/stamp-without-block.apk
index 9dec2f591133..604fe6f43523 100644
--- a/core/tests/coretests/assets/SourceStampVerifierTest/stamp-without-block.apk
+++ b/core/tests/coretests/assets/SourceStampVerifierTest/stamp-without-block.apk
Binary files differ
diff --git a/core/tests/coretests/assets/SourceStampVerifierTest/valid-stamp.apk b/core/tests/coretests/assets/SourceStampVerifierTest/valid-stamp.apk
index 8056e0bf6e50..2f2a5923d24a 100644
--- a/core/tests/coretests/assets/SourceStampVerifierTest/valid-stamp.apk
+++ b/core/tests/coretests/assets/SourceStampVerifierTest/valid-stamp.apk
Binary files differ
diff --git a/core/tests/coretests/src/android/util/apk/SourceStampVerifierTest.java b/core/tests/coretests/src/android/util/apk/SourceStampVerifierTest.java
index 37b2817928aa..81d54b57486c 100644
--- a/core/tests/coretests/src/android/util/apk/SourceStampVerifierTest.java
+++ b/core/tests/coretests/src/android/util/apk/SourceStampVerifierTest.java
@@ -26,8 +26,11 @@ import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
import android.content.Context;
-import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.core.app.ApplicationProvider;
+import libcore.io.Streams;
+
+import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@@ -46,8 +49,20 @@ import java.util.zip.ZipFile;
@RunWith(JUnit4.class)
public class SourceStampVerifierTest {
- private final Context mContext =
- InstrumentationRegistry.getInstrumentation().getTargetContext();
+ private final Context mContext = ApplicationProvider.getApplicationContext();
+
+ private File mPrimaryApk;
+ private File mSecondaryApk;
+
+ @After
+ public void tearDown() throws Exception {
+ if (mPrimaryApk != null) {
+ mPrimaryApk.delete();
+ }
+ if (mSecondaryApk != null) {
+ mSecondaryApk.delete();
+ }
+ }
@Test
public void testSourceStamp_noStamp() throws Exception {
@@ -63,17 +78,11 @@ public class SourceStampVerifierTest {
@Test
public void testSourceStamp_correctSignature() throws Exception {
- File testApk = getApk("SourceStampVerifierTest/valid-stamp.apk");
- ZipFile apkZipFile = new ZipFile(testApk);
- ZipEntry stampCertZipEntry = apkZipFile.getEntry("stamp-cert-sha256");
- int size = (int) stampCertZipEntry.getSize();
- byte[] expectedStampCertHash = new byte[size];
- try (InputStream inputStream = apkZipFile.getInputStream(stampCertZipEntry)) {
- inputStream.read(expectedStampCertHash);
- }
+ mPrimaryApk = getApk("SourceStampVerifierTest/valid-stamp.apk");
+ byte[] expectedStampCertHash = getSourceStampCertificateHashFromApk(mPrimaryApk);
SourceStampVerificationResult result =
- SourceStampVerifier.verify(testApk.getAbsolutePath());
+ SourceStampVerifier.verify(mPrimaryApk.getAbsolutePath());
assertTrue(result.isPresent());
assertTrue(result.isVerified());
@@ -85,10 +94,10 @@ public class SourceStampVerifierTest {
@Test
public void testSourceStamp_signatureMissing() throws Exception {
- File testApk = getApk("SourceStampVerifierTest/stamp-without-block.apk");
+ mPrimaryApk = getApk("SourceStampVerifierTest/stamp-without-block.apk");
SourceStampVerificationResult result =
- SourceStampVerifier.verify(testApk.getAbsolutePath());
+ SourceStampVerifier.verify(mPrimaryApk.getAbsolutePath());
assertTrue(result.isPresent());
assertFalse(result.isVerified());
@@ -97,10 +106,10 @@ public class SourceStampVerifierTest {
@Test
public void testSourceStamp_certificateMismatch() throws Exception {
- File testApk = getApk("SourceStampVerifierTest/stamp-certificate-mismatch.apk");
+ mPrimaryApk = getApk("SourceStampVerifierTest/stamp-certificate-mismatch.apk");
SourceStampVerificationResult result =
- SourceStampVerifier.verify(testApk.getAbsolutePath());
+ SourceStampVerifier.verify(mPrimaryApk.getAbsolutePath());
assertTrue(result.isPresent());
assertFalse(result.isVerified());
@@ -108,11 +117,35 @@ public class SourceStampVerifierTest {
}
@Test
- public void testSourceStamp_apkHashMismatch() throws Exception {
- File testApk = getApk("SourceStampVerifierTest/stamp-apk-hash-mismatch.apk");
+ public void testSourceStamp_apkHashMismatch_v1SignatureScheme() throws Exception {
+ mPrimaryApk = getApk("SourceStampVerifierTest/stamp-apk-hash-mismatch-v1.apk");
SourceStampVerificationResult result =
- SourceStampVerifier.verify(testApk.getAbsolutePath());
+ SourceStampVerifier.verify(mPrimaryApk.getAbsolutePath());
+
+ assertTrue(result.isPresent());
+ assertFalse(result.isVerified());
+ assertNull(result.getCertificate());
+ }
+
+ @Test
+ public void testSourceStamp_apkHashMismatch_v2SignatureScheme() throws Exception {
+ mPrimaryApk = getApk("SourceStampVerifierTest/stamp-apk-hash-mismatch-v2.apk");
+
+ SourceStampVerificationResult result =
+ SourceStampVerifier.verify(mPrimaryApk.getAbsolutePath());
+
+ assertTrue(result.isPresent());
+ assertFalse(result.isVerified());
+ assertNull(result.getCertificate());
+ }
+
+ @Test
+ public void testSourceStamp_apkHashMismatch_v3SignatureScheme() throws Exception {
+ mPrimaryApk = getApk("SourceStampVerifierTest/stamp-apk-hash-mismatch-v3.apk");
+
+ SourceStampVerificationResult result =
+ SourceStampVerifier.verify(mPrimaryApk.getAbsolutePath());
assertTrue(result.isPresent());
assertFalse(result.isVerified());
@@ -121,10 +154,10 @@ public class SourceStampVerifierTest {
@Test
public void testSourceStamp_malformedSignature() throws Exception {
- File testApk = getApk("SourceStampVerifierTest/stamp-malformed-signature.apk");
+ mPrimaryApk = getApk("SourceStampVerifierTest/stamp-malformed-signature.apk");
SourceStampVerificationResult result =
- SourceStampVerifier.verify(testApk.getAbsolutePath());
+ SourceStampVerifier.verify(mPrimaryApk.getAbsolutePath());
assertTrue(result.isPresent());
assertFalse(result.isVerified());
@@ -133,21 +166,14 @@ public class SourceStampVerifierTest {
@Test
public void testSourceStamp_multiApk_validStamps() throws Exception {
- File testApk1 = getApk("SourceStampVerifierTest/valid-stamp.apk");
- File testApk2 = getApk("SourceStampVerifierTest/valid-stamp.apk");
- ZipFile apkZipFile = new ZipFile(testApk1);
- ZipEntry stampCertZipEntry = apkZipFile.getEntry("stamp-cert-sha256");
- int size = (int) stampCertZipEntry.getSize();
- byte[] expectedStampCertHash = new byte[size];
- try (InputStream inputStream = apkZipFile.getInputStream(stampCertZipEntry)) {
- inputStream.read(expectedStampCertHash);
- }
+ mPrimaryApk = getApk("SourceStampVerifierTest/valid-stamp.apk");
+ mSecondaryApk = getApk("SourceStampVerifierTest/valid-stamp.apk");
+ byte[] expectedStampCertHash = getSourceStampCertificateHashFromApk(mPrimaryApk);
List<String> apkFiles = new ArrayList<>();
- apkFiles.add(testApk1.getAbsolutePath());
- apkFiles.add(testApk2.getAbsolutePath());
+ apkFiles.add(mPrimaryApk.getAbsolutePath());
+ apkFiles.add(mSecondaryApk.getAbsolutePath());
- SourceStampVerificationResult result =
- SourceStampVerifier.verify(apkFiles);
+ SourceStampVerificationResult result = SourceStampVerifier.verify(apkFiles);
assertTrue(result.isPresent());
assertTrue(result.isVerified());
@@ -159,14 +185,13 @@ public class SourceStampVerifierTest {
@Test
public void testSourceStamp_multiApk_invalidStamps() throws Exception {
- File testApk1 = getApk("SourceStampVerifierTest/valid-stamp.apk");
- File testApk2 = getApk("SourceStampVerifierTest/stamp-apk-hash-mismatch.apk");
+ mPrimaryApk = getApk("SourceStampVerifierTest/valid-stamp.apk");
+ mSecondaryApk = getApk("SourceStampVerifierTest/stamp-apk-hash-mismatch-v3.apk");
List<String> apkFiles = new ArrayList<>();
- apkFiles.add(testApk1.getAbsolutePath());
- apkFiles.add(testApk2.getAbsolutePath());
+ apkFiles.add(mPrimaryApk.getAbsolutePath());
+ apkFiles.add(mSecondaryApk.getAbsolutePath());
- SourceStampVerificationResult result =
- SourceStampVerifier.verify(apkFiles);
+ SourceStampVerificationResult result = SourceStampVerifier.verify(apkFiles);
assertTrue(result.isPresent());
assertFalse(result.isVerified());
@@ -174,10 +199,16 @@ public class SourceStampVerifierTest {
}
private File getApk(String apkPath) throws IOException {
- File testApk = File.createTempFile("SourceStampApk", ".apk");
+ File apk = File.createTempFile("SourceStampApk", ".apk");
try (InputStream inputStream = mContext.getAssets().open(apkPath)) {
- Files.copy(inputStream, testApk.toPath(), REPLACE_EXISTING);
+ Files.copy(inputStream, apk.toPath(), REPLACE_EXISTING);
}
- return testApk;
+ return apk;
+ }
+
+ private byte[] getSourceStampCertificateHashFromApk(File apk) throws IOException {
+ ZipFile apkZipFile = new ZipFile(apk);
+ ZipEntry stampCertZipEntry = apkZipFile.getEntry("stamp-cert-sha256");
+ return Streams.readFully(apkZipFile.getInputStream(stampCertZipEntry));
}
}
diff --git a/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java b/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java
index 8eca650398bf..a2b1e3d69cd2 100644
--- a/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java
+++ b/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java
@@ -234,6 +234,24 @@ public class InsetsAnimationControlImplTest {
verify(mMockListener).onFinished(mController);
}
+ @Test
+ public void testPerceptible_insets() {
+ mController.setInsetsAndAlpha(mController.getHiddenStateInsets(), 1f, 1f);
+ verify(mMockController).reportPerceptible(systemBars(), false);
+
+ mController.setInsetsAndAlpha(mController.getShownStateInsets(), 1f, 1f);
+ verify(mMockController).reportPerceptible(systemBars(), true);
+ }
+
+ @Test
+ public void testPerceptible_alpha() {
+ mController.setInsetsAndAlpha(mController.getShownStateInsets(), 0f, 1f);
+ verify(mMockController).reportPerceptible(systemBars(), false);
+
+ mController.setInsetsAndAlpha(mController.getShownStateInsets(), 1f, 1f);
+ verify(mMockController).reportPerceptible(systemBars(), true);
+ }
+
private void assertPosition(Matrix m, Rect original, Rect transformed) {
RectF rect = new RectF(original);
rect.offsetTo(0, 0);
diff --git a/data/etc/car/Android.bp b/data/etc/car/Android.bp
index d6542de91e08..e5492714b29f 100644
--- a/data/etc/car/Android.bp
+++ b/data/etc/car/Android.bp
@@ -129,6 +129,13 @@ prebuilt_etc {
}
prebuilt_etc {
+ name: "privapp_whitelist_com.android.car.companiondevicesupport",
+ sub_dir: "permissions",
+ src: "com.android.car.companiondevicesupport.xml",
+ filename_from_src: true,
+}
+
+prebuilt_etc {
name: "privapp_whitelist_com.google.android.car.kitchensink",
sub_dir: "permissions",
src: "com.google.android.car.kitchensink.xml",
diff --git a/data/etc/car/com.android.car.companiondevicesupport.xml b/data/etc/car/com.android.car.companiondevicesupport.xml
new file mode 100644
index 000000000000..2067bab20d3d
--- /dev/null
+++ b/data/etc/car/com.android.car.companiondevicesupport.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2019 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+<permissions>
+ <privapp-permissions package="com.android.car.companiondevicesupport">
+ <permission name="android.permission.INTERACT_ACROSS_USERS"/>
+ <permission name="android.permission.MANAGE_USERS"/>
+ <permission name="android.permission.PROVIDE_TRUST_AGENT"/>
+ <permission name="android.permission.SUBSTITUTE_NOTIFICATION_APP_NAME"/>
+ </privapp-permissions>
+</permissions>
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 9b503eba5c68..8520fffb3444 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -233,6 +233,7 @@ applications that come with the platform
<!-- Permissions required for reading and logging compat changes -->
<permission name="android.permission.LOG_COMPAT_CHANGE" />
<permission name="android.permission.READ_COMPAT_CHANGE_CONFIG" />
+ <permission name="android.permission.REGISTER_STATS_PULL_ATOM" />
</privapp-permissions>
<privapp-permissions package="com.android.providers.telephony">
diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java
index 9d0fe11be46b..88b614dc7eef 100644
--- a/keystore/java/android/security/KeyStore.java
+++ b/keystore/java/android/security/KeyStore.java
@@ -483,14 +483,14 @@ public class KeyStore {
mBinder.asBinder().linkToDeath(promise, 0);
int errorCode = mBinder.addRngEntropy(promise, data, flags);
if (errorCode == NO_ERROR) {
- return promise.getFuture().get().getErrorCode() == 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 | InterruptedException e) {
+ } catch (ExecutionException e) {
Log.e(TAG, "AddRngEntropy completed with exception", e);
return false;
} finally {
@@ -548,7 +548,7 @@ public class KeyStore {
private int generateKeyInternal(String alias, KeymasterArguments args, byte[] entropy, int uid,
int flags, KeyCharacteristics outCharacteristics)
- throws RemoteException, ExecutionException, InterruptedException {
+ throws RemoteException, ExecutionException {
KeyCharacteristicsPromise promise = new KeyCharacteristicsPromise();
int error = NO_ERROR;
KeyCharacteristicsCallbackResult result = null;
@@ -559,7 +559,7 @@ public class KeyStore {
Log.e(TAG, "generateKeyInternal failed on request " + error);
return error;
}
- result = promise.getFuture().get();
+ result = interruptedPreservingGet(promise.getFuture());
} finally {
mBinder.asBinder().unlinkToDeath(promise, 0);
}
@@ -592,7 +592,7 @@ public class KeyStore {
} catch (RemoteException e) {
Log.w(TAG, "Cannot connect to keystore", e);
return SYSTEM_ERROR;
- } catch (ExecutionException | InterruptedException e) {
+ } catch (ExecutionException e) {
Log.e(TAG, "generateKey completed with exception", e);
return SYSTEM_ERROR;
}
@@ -614,7 +614,7 @@ public class KeyStore {
int error = mBinder.getKeyCharacteristics(promise, alias, clientId, appId, uid);
if (error != NO_ERROR) return error;
- KeyCharacteristicsCallbackResult result = promise.getFuture().get();
+ KeyCharacteristicsCallbackResult result = interruptedPreservingGet(promise.getFuture());
error = result.getKeystoreResponse().getErrorCode();
if (error != NO_ERROR) return error;
@@ -625,7 +625,7 @@ public class KeyStore {
} catch (RemoteException e) {
Log.w(TAG, "Cannot connect to keystore", e);
return SYSTEM_ERROR;
- } catch (ExecutionException | InterruptedException e) {
+ } catch (ExecutionException e) {
Log.e(TAG, "GetKeyCharacteristics completed with exception", e);
return SYSTEM_ERROR;
} finally {
@@ -640,14 +640,14 @@ public class KeyStore {
private int importKeyInternal(String alias, KeymasterArguments args, int format, byte[] keyData,
int uid, int flags, KeyCharacteristics outCharacteristics)
- throws RemoteException, ExecutionException, InterruptedException {
+ 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 = promise.getFuture().get();
+ KeyCharacteristicsCallbackResult result = interruptedPreservingGet(promise.getFuture());
error = result.getKeystoreResponse().getErrorCode();
if (error != NO_ERROR) return error;
@@ -675,7 +675,7 @@ public class KeyStore {
} catch (RemoteException e) {
Log.w(TAG, "Cannot connect to keystore", e);
return SYSTEM_ERROR;
- } catch (ExecutionException | InterruptedException e) {
+ } catch (ExecutionException e) {
Log.e(TAG, "ImportKey completed with exception", e);
return SYSTEM_ERROR;
}
@@ -747,7 +747,7 @@ public class KeyStore {
String wrappingKeyAlias,
byte[] maskingKey, KeymasterArguments args, long rootSid, long fingerprintSid,
KeyCharacteristics outCharacteristics)
- throws RemoteException, ExecutionException, InterruptedException {
+ throws RemoteException, ExecutionException {
KeyCharacteristicsPromise promise = new KeyCharacteristicsPromise();
mBinder.asBinder().linkToDeath(promise, 0);
try {
@@ -755,7 +755,7 @@ public class KeyStore {
wrappingKeyAlias, maskingKey, args, rootSid, fingerprintSid);
if (error != NO_ERROR) return error;
- KeyCharacteristicsCallbackResult result = promise.getFuture().get();
+ KeyCharacteristicsCallbackResult result = interruptedPreservingGet(promise.getFuture());
error = result.getKeystoreResponse().getErrorCode();
if (error != NO_ERROR) return error;
@@ -786,7 +786,7 @@ public class KeyStore {
} catch (RemoteException e) {
Log.w(TAG, "Cannot connect to keystore", e);
return SYSTEM_ERROR;
- } catch (ExecutionException | InterruptedException e) {
+ } catch (ExecutionException e) {
Log.e(TAG, "ImportWrappedKey completed with exception", e);
return SYSTEM_ERROR;
}
@@ -818,14 +818,14 @@ public class KeyStore {
appId = appId != null ? appId : new KeymasterBlob(new byte[0]);
int error = mBinder.exportKey(promise, alias, format, clientId, appId, uid);
if (error == NO_ERROR) {
- return promise.getFuture().get();
+ return interruptedPreservingGet(promise.getFuture());
} else {
return new ExportResult(error);
}
} catch (RemoteException e) {
Log.w(TAG, "Cannot connect to keystore", e);
return null;
- } catch (ExecutionException | InterruptedException e) {
+ } catch (ExecutionException e) {
Log.e(TAG, "ExportKey completed with exception", e);
return null;
} finally {
@@ -864,14 +864,14 @@ public class KeyStore {
int errorCode = mBinder.begin(promise, getToken(), alias, purpose, pruneable, args,
entropy, uid);
if (errorCode == NO_ERROR) {
- return promise.getFuture().get();
+ return interruptedPreservingGet(promise.getFuture());
} else {
return new OperationResult(errorCode);
}
} catch (RemoteException e) {
Log.w(TAG, "Cannot connect to keystore", e);
return null;
- } catch (ExecutionException | InterruptedException e) {
+ } catch (ExecutionException e) {
Log.e(TAG, "Begin completed with exception", e);
return null;
} finally {
@@ -894,14 +894,14 @@ public class KeyStore {
input = input != null ? input : new byte[0];
int errorCode = mBinder.update(promise, token, arguments, input);
if (errorCode == NO_ERROR) {
- return promise.getFuture().get();
+ return interruptedPreservingGet(promise.getFuture());
} else {
return new OperationResult(errorCode);
}
} catch (RemoteException e) {
Log.w(TAG, "Cannot connect to keystore", e);
return null;
- } catch (ExecutionException | InterruptedException e) {
+ } catch (ExecutionException e) {
Log.e(TAG, "Update completed with exception", e);
return null;
} finally {
@@ -930,14 +930,14 @@ public class KeyStore {
signature = signature != null ? signature : new byte[0];
int errorCode = mBinder.finish(promise, token, arguments, input, signature, entropy);
if (errorCode == NO_ERROR) {
- return promise.getFuture().get();
+ return interruptedPreservingGet(promise.getFuture());
} else {
return new OperationResult(errorCode);
}
} catch (RemoteException e) {
Log.w(TAG, "Cannot connect to keystore", e);
return null;
- } catch (ExecutionException | InterruptedException e) {
+ } catch (ExecutionException e) {
Log.e(TAG, "Finish completed with exception", e);
return null;
} finally {
@@ -972,14 +972,14 @@ public class KeyStore {
mBinder.asBinder().linkToDeath(promise, 0);
int errorCode = mBinder.abort(promise, token);
if (errorCode == NO_ERROR) {
- return promise.getFuture().get().getErrorCode();
+ return interruptedPreservingGet(promise.getFuture()).getErrorCode();
} else {
return errorCode;
}
} catch (RemoteException e) {
Log.w(TAG, "Cannot connect to keystore", e);
return SYSTEM_ERROR;
- } catch (ExecutionException | InterruptedException e) {
+ } catch (ExecutionException e) {
Log.e(TAG, "Abort completed with exception", e);
return SYSTEM_ERROR;
} finally {
@@ -1135,7 +1135,7 @@ public class KeyStore {
}
int error = mBinder.attestKey(promise, alias, params);
if (error != NO_ERROR) return error;
- KeyAttestationCallbackResult result = promise.getFuture().get();
+ KeyAttestationCallbackResult result = interruptedPreservingGet(promise.getFuture());
error = result.getKeystoreResponse().getErrorCode();
if (error == NO_ERROR) {
outChain.shallowCopyFrom(result.getCertificateChain());
@@ -1144,7 +1144,7 @@ public class KeyStore {
} catch (RemoteException e) {
Log.w(TAG, "Cannot connect to keystore", e);
return SYSTEM_ERROR;
- } catch (ExecutionException | InterruptedException e) {
+ } catch (ExecutionException e) {
Log.e(TAG, "AttestKey completed with exception", e);
return SYSTEM_ERROR;
} finally {
@@ -1164,7 +1164,7 @@ public class KeyStore {
}
int error = mBinder.attestDeviceIds(promise, params);
if (error != NO_ERROR) return error;
- KeyAttestationCallbackResult result = promise.getFuture().get();
+ KeyAttestationCallbackResult result = interruptedPreservingGet(promise.getFuture());
error = result.getKeystoreResponse().getErrorCode();
if (error == NO_ERROR) {
outChain.shallowCopyFrom(result.getCertificateChain());
@@ -1173,7 +1173,7 @@ public class KeyStore {
} catch (RemoteException e) {
Log.w(TAG, "Cannot connect to keystore", e);
return SYSTEM_ERROR;
- } catch (ExecutionException | InterruptedException e) {
+ } catch (ExecutionException e) {
Log.e(TAG, "AttestDevicdeIds completed with exception", e);
return SYSTEM_ERROR;
} finally {
@@ -1387,4 +1387,20 @@ public class KeyStore {
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;
+ }
+ }
+ }
}
diff --git a/libs/WindowManager/Jetpack/Android.bp b/libs/WindowManager/Jetpack/Android.bp
index 308c1a59a7aa..4f4364f72fef 100644
--- a/libs/WindowManager/Jetpack/Android.bp
+++ b/libs/WindowManager/Jetpack/Android.bp
@@ -13,26 +13,26 @@
// limitations under the License.
android_library_import {
- name: "window-extensions",
- aars: ["window-extensions-release.aar"],
+ name: "window-sidecar",
+ aars: ["window-sidecar-release.aar"],
sdk_version: "current",
}
java_library {
- name: "androidx.window.extensions",
+ name: "androidx.window.sidecar",
srcs: ["src/**/*.java"],
- static_libs: ["window-extensions"],
+ static_libs: ["window-sidecar"],
installable: true,
sdk_version: "core_platform",
vendor: true,
libs: ["framework", "androidx.annotation_annotation",],
- required: ["androidx.window.extensions.xml",],
+ required: ["androidx.window.sidecar.xml",],
}
prebuilt_etc {
- name: "androidx.window.extensions.xml",
+ name: "androidx.window.sidecar.xml",
vendor: true,
sub_dir: "permissions",
- src: "androidx.window.extensions.xml",
+ src: "androidx.window.sidecar.xml",
filename_from_src: true,
}
diff --git a/libs/WindowManager/Jetpack/androidx.window.extensions.xml b/libs/WindowManager/Jetpack/androidx.window.extensions.xml
deleted file mode 100644
index 1f0ff6656de0..000000000000
--- a/libs/WindowManager/Jetpack/androidx.window.extensions.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 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.
- -->
-<permissions>
- <library
- name="androidx.window.extensions"
- file="/vendor/framework/androidx.window.extensions.jar"/>
-</permissions>
diff --git a/libs/WindowManager/Jetpack/androidx.window.sidecar.xml b/libs/WindowManager/Jetpack/androidx.window.sidecar.xml
new file mode 100644
index 000000000000..f88a5f4ae039
--- /dev/null
+++ b/libs/WindowManager/Jetpack/androidx.window.sidecar.xml
@@ -0,0 +1,21 @@
+<?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.
+ -->
+<permissions>
+ <library
+ name="androidx.window.sidecar"
+ file="/vendor/framework/androidx.window.sidecar.jar"/>
+</permissions>
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/SettingsExtensionImpl.java b/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SettingsSidecarImpl.java
index 7a3fbf3ad9b8..92e575804bbe 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/SettingsExtensionImpl.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SettingsSidecarImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 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.
@@ -14,14 +14,14 @@
* limitations under the License.
*/
-package androidx.window.extensions;
+package androidx.window.sidecar;
import static android.view.Display.DEFAULT_DISPLAY;
-import static androidx.window.extensions.ExtensionHelper.getWindowDisplay;
-import static androidx.window.extensions.ExtensionHelper.isInMultiWindow;
-import static androidx.window.extensions.ExtensionHelper.rotateRectToDisplayRotation;
-import static androidx.window.extensions.ExtensionHelper.transformToWindowSpaceRect;
+import static androidx.window.sidecar.SidecarHelper.getWindowDisplay;
+import static androidx.window.sidecar.SidecarHelper.isInMultiWindow;
+import static androidx.window.sidecar.SidecarHelper.rotateRectToDisplayRotation;
+import static androidx.window.sidecar.SidecarHelper.transformToWindowSpaceRect;
import android.content.ContentResolver;
import android.content.Context;
@@ -42,8 +42,8 @@ import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-class SettingsExtensionImpl extends StubExtension {
- private static final String TAG = "SettingsExtension";
+class SettingsSidecarImpl extends StubSidecar {
+ private static final String TAG = "SettingsSidecar";
private static final String DEVICE_POSTURE = "device_posture";
private static final String DISPLAY_FEATURES = "display_features";
@@ -106,7 +106,7 @@ class SettingsExtensionImpl extends StubExtension {
}
}
- SettingsExtensionImpl(Context context) {
+ SettingsSidecarImpl(Context context) {
mContext = context;
mSettingsObserver = new SettingsObserver();
}
@@ -118,29 +118,33 @@ class SettingsExtensionImpl extends StubExtension {
/** Update display features with values read from settings. */
private void updateDisplayFeatures() {
for (IBinder windowToken : getWindowsListeningForLayoutChanges()) {
- ExtensionWindowLayoutInfo newLayout = getWindowLayoutInfo(windowToken);
+ SidecarWindowLayoutInfo newLayout = getWindowLayoutInfo(windowToken);
updateWindowLayout(windowToken, newLayout);
}
}
@NonNull
@Override
- public ExtensionDeviceState getDeviceState() {
+ public SidecarDeviceState getDeviceState() {
ContentResolver resolver = mContext.getContentResolver();
int posture = Settings.Global.getInt(resolver, DEVICE_POSTURE,
- ExtensionDeviceState.POSTURE_UNKNOWN);
- return new ExtensionDeviceState(posture);
+ SidecarDeviceState.POSTURE_UNKNOWN);
+ SidecarDeviceState deviceState = new SidecarDeviceState();
+ deviceState.posture = posture;
+ return deviceState;
}
@NonNull
@Override
- public ExtensionWindowLayoutInfo getWindowLayoutInfo(@NonNull IBinder windowToken) {
- List<ExtensionDisplayFeature> displayFeatures = readDisplayFeatures(windowToken);
- return new ExtensionWindowLayoutInfo(displayFeatures);
+ public SidecarWindowLayoutInfo getWindowLayoutInfo(@NonNull IBinder windowToken) {
+ List<SidecarDisplayFeature> displayFeatures = readDisplayFeatures(windowToken);
+ SidecarWindowLayoutInfo windowLayoutInfo = new SidecarWindowLayoutInfo();
+ windowLayoutInfo.displayFeatures = displayFeatures;
+ return windowLayoutInfo;
}
- private List<ExtensionDisplayFeature> readDisplayFeatures(IBinder windowToken) {
- List<ExtensionDisplayFeature> features = new ArrayList<ExtensionDisplayFeature>();
+ private List<SidecarDisplayFeature> readDisplayFeatures(IBinder windowToken) {
+ List<SidecarDisplayFeature> features = new ArrayList<SidecarDisplayFeature>();
int displayId = getWindowDisplay(windowToken);
if (displayId != DEFAULT_DISPLAY) {
Log.w(TAG, "This sample doesn't support display features on secondary displays");
@@ -170,10 +174,10 @@ class SettingsExtensionImpl extends StubExtension {
int type;
switch (featureType) {
case FEATURE_TYPE_FOLD:
- type = ExtensionDisplayFeature.TYPE_FOLD;
+ type = SidecarDisplayFeature.TYPE_FOLD;
break;
case FEATURE_TYPE_HINGE:
- type = ExtensionDisplayFeature.TYPE_HINGE;
+ type = SidecarDisplayFeature.TYPE_HINGE;
break;
default: {
Log.e(TAG, "Malformed feature type: " + featureType);
@@ -189,8 +193,9 @@ class SettingsExtensionImpl extends StubExtension {
rotateRectToDisplayRotation(featureRect, displayId);
transformToWindowSpaceRect(featureRect, windowToken);
if (!featureRect.isEmpty()) {
- ExtensionDisplayFeature feature =
- new ExtensionDisplayFeature(featureRect, type);
+ SidecarDisplayFeature feature = new SidecarDisplayFeature();
+ feature.setRect(featureRect);
+ feature.setType(type);
features.add(feature);
} else {
Log.w(TAG, "Failed to adjust feature to window");
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/ExtensionHelper.java b/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SidecarHelper.java
index c61f1ed2d179..e5b6cff17b26 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/ExtensionHelper.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SidecarHelper.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package androidx.window.extensions;
+package androidx.window.sidecar;
import static android.view.Display.INVALID_DISPLAY;
import static android.view.Surface.ROTATION_0;
@@ -32,12 +32,7 @@ import android.view.Surface;
import androidx.annotation.Nullable;
-/**
- * Toolkit class for calculation of the display feature bounds within the window.
- * NOTE: This sample implementation only works for Activity windows, because there is no public APIs
- * to obtain layout params or bounds for arbitrary windows.
- */
-class ExtensionHelper {
+class SidecarHelper {
/**
* Rotate the input rectangle specified in default display orientation to the current display
* rotation.
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/ExtensionProvider.java b/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SidecarProvider.java
index 47349f11fb93..0b4915ed5dac 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/ExtensionProvider.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SidecarProvider.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package androidx.window.extensions;
+package androidx.window.sidecar;
import android.content.Context;
@@ -22,14 +22,13 @@ import android.content.Context;
* Provider class that will instantiate the library implementation. It must be included in the
* vendor library, and the vendor implementation must match the signature of this class.
*/
-public class ExtensionProvider {
-
+public class SidecarProvider {
/**
- * The support library will instantiate the vendor implementation using this interface.
- * @return An implementation of {@link ExtensionInterface}.
+ * Provide a simple implementation of {@link SidecarInterface} that can be replaced by
+ * an OEM by overriding this method.
*/
- public static ExtensionInterface getExtensionImpl(Context context) {
- return new SettingsExtensionImpl(context);
+ public static SidecarInterface getSidecarImpl(Context context) {
+ return new SettingsSidecarImpl(context);
}
/**
@@ -37,6 +36,6 @@ public class ExtensionProvider {
* @return API version string in MAJOR.MINOR.PATCH-description format.
*/
public static String getApiVersion() {
- return "1.0.0-settings_sample";
+ return "0.1.0-settings_sample";
}
}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/sidecar/StubSidecar.java b/libs/WindowManager/Jetpack/src/androidx/window/sidecar/StubSidecar.java
new file mode 100644
index 000000000000..199c37315c07
--- /dev/null
+++ b/libs/WindowManager/Jetpack/src/androidx/window/sidecar/StubSidecar.java
@@ -0,0 +1,85 @@
+/*
+ * 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 androidx.window.sidecar;
+
+import android.os.IBinder;
+
+import androidx.annotation.NonNull;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Basic implementation of the {@link SidecarInterface}. An OEM can choose to use it as the base
+ * class for their implementation.
+ */
+abstract class StubSidecar implements SidecarInterface {
+
+ private SidecarCallback mSidecarCallback;
+ private final Set<IBinder> mWindowLayoutChangeListenerTokens = new HashSet<>();
+ private boolean mDeviceStateChangeListenerRegistered;
+
+ StubSidecar() {
+ }
+
+ @Override
+ public void setSidecarCallback(@NonNull SidecarCallback sidecarCallback) {
+ this.mSidecarCallback = sidecarCallback;
+ }
+
+ @Override
+ public void onWindowLayoutChangeListenerAdded(@NonNull IBinder iBinder) {
+ this.mWindowLayoutChangeListenerTokens.add(iBinder);
+ this.onListenersChanged();
+ }
+
+ @Override
+ public void onWindowLayoutChangeListenerRemoved(@NonNull IBinder iBinder) {
+ this.mWindowLayoutChangeListenerTokens.remove(iBinder);
+ this.onListenersChanged();
+ }
+
+ @Override
+ public void onDeviceStateListenersChanged(boolean isEmpty) {
+ this.mDeviceStateChangeListenerRegistered = !isEmpty;
+ this.onListenersChanged();
+ }
+
+ void updateDeviceState(SidecarDeviceState newState) {
+ if (this.mSidecarCallback != null) {
+ mSidecarCallback.onDeviceStateChanged(newState);
+ }
+ }
+
+ void updateWindowLayout(@NonNull IBinder windowToken,
+ @NonNull SidecarWindowLayoutInfo newLayout) {
+ if (this.mSidecarCallback != null) {
+ mSidecarCallback.onWindowLayoutChanged(windowToken, newLayout);
+ }
+ }
+
+ @NonNull
+ Set<IBinder> getWindowsListeningForLayoutChanges() {
+ return mWindowLayoutChangeListenerTokens;
+ }
+
+ protected boolean hasListeners() {
+ return !mWindowLayoutChangeListenerTokens.isEmpty() || mDeviceStateChangeListenerRegistered;
+ }
+
+ protected abstract void onListenersChanged();
+}
diff --git a/libs/WindowManager/Jetpack/window-extensions-release.aar b/libs/WindowManager/Jetpack/window-extensions-release.aar
deleted file mode 100644
index 0ebbb86daf82..000000000000
--- a/libs/WindowManager/Jetpack/window-extensions-release.aar
+++ /dev/null
Binary files differ
diff --git a/libs/WindowManager/Jetpack/window-sidecar-release.aar b/libs/WindowManager/Jetpack/window-sidecar-release.aar
new file mode 100644
index 000000000000..50f101d7d181
--- /dev/null
+++ b/libs/WindowManager/Jetpack/window-sidecar-release.aar
Binary files differ
diff --git a/libs/androidfw/Idmap.cpp b/libs/androidfw/Idmap.cpp
index eb6ee9525bb9..5f231ffe4786 100644
--- a/libs/androidfw/Idmap.cpp
+++ b/libs/androidfw/Idmap.cpp
@@ -157,7 +157,7 @@ IdmapResMap::Result IdmapResMap::Lookup(uint32_t target_res_id) const {
table_value->dataType = entry->type;
table_value->data = entry->value;
- return Result(ResTable_entry_handle::managed(table_entry));
+ return Result(ResTable_entry_handle::managed(table_entry, [](auto p) { free(p); }));
}
static bool is_word_aligned(const void* data) {
diff --git a/libs/androidfw/include/androidfw/ResourceTypes.h b/libs/androidfw/include/androidfw/ResourceTypes.h
index 21be81cb85bd..e351a46d633a 100644
--- a/libs/androidfw/include/androidfw/ResourceTypes.h
+++ b/libs/androidfw/include/androidfw/ResourceTypes.h
@@ -1601,8 +1601,8 @@ class ResTable_entry_handle {
entry_ = handle.entry_;
}
- inline static ResTable_entry_handle managed(ResTable_entry* entry) {
- return ResTable_entry_handle(std::shared_ptr<const ResTable_entry>(entry));
+ inline static ResTable_entry_handle managed(ResTable_entry* entry, void (*deleter)(void *)) {
+ return ResTable_entry_handle(std::shared_ptr<const ResTable_entry>(entry, deleter));
}
inline static ResTable_entry_handle unmanaged(const ResTable_entry* entry) {
diff --git a/libs/hwui/renderthread/CacheManager.cpp b/libs/hwui/renderthread/CacheManager.cpp
index d177855e5a7d..1e5877356e8d 100644
--- a/libs/hwui/renderthread/CacheManager.cpp
+++ b/libs/hwui/renderthread/CacheManager.cpp
@@ -42,7 +42,7 @@ namespace renderthread {
// to the screen resolution. This is meant to be a conservative default based on
// that analysis. The 4.0f is used because the default pixel format is assumed to
// be ARGB_8888.
-#define SURFACE_SIZE_MULTIPLIER (5.0f * 4.0f)
+#define SURFACE_SIZE_MULTIPLIER (12.0f * 4.0f)
#define BACKGROUND_RETENTION_PERCENTAGE (0.5f)
CacheManager::CacheManager()
diff --git a/location/java/android/location/AbstractListenerManager.java b/location/java/android/location/AbstractListenerManager.java
index 36b86899f2d8..f5595e89b807 100644
--- a/location/java/android/location/AbstractListenerManager.java
+++ b/location/java/android/location/AbstractListenerManager.java
@@ -29,6 +29,8 @@ import android.util.ArrayMap;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.Preconditions;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Objects;
import java.util.concurrent.Executor;
import java.util.function.Consumer;
@@ -193,7 +195,7 @@ abstract class AbstractListenerManager<TRequest, TListener> {
protected abstract void unregisterService() throws RemoteException;
@Nullable
- protected TRequest merge(@NonNull TRequest[] requests) {
+ protected TRequest merge(@NonNull List<TRequest> requests) {
for (TRequest request : requests) {
Preconditions.checkArgument(request == null,
"merge() has to be overridden for non-null requests.");
@@ -221,9 +223,9 @@ abstract class AbstractListenerManager<TRequest, TListener> {
return mListeners.valueAt(0).getRequest();
}
- TRequest[] requests = (TRequest[]) new Object[mListeners.size()];
+ ArrayList<TRequest> requests = new ArrayList<>(mListeners.size());
for (int index = 0; index < mListeners.size(); index++) {
- requests[index] = mListeners.valueAt(index).getRequest();
+ requests.add(mListeners.valueAt(index).getRequest());
}
return merge(requests);
}
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index 7d15bbd46697..f3c9e9435417 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -3030,14 +3030,14 @@ public class LocationManager {
@Override
@Nullable
- protected GnssRequest merge(@NonNull GnssRequest[] requests) {
- Preconditions.checkArgument(requests.length > 0);
+ protected GnssRequest merge(@NonNull List<GnssRequest> requests) {
+ Preconditions.checkArgument(!requests.isEmpty());
for (GnssRequest request : requests) {
if (request.isFullTracking()) {
return request;
}
}
- return requests[0];
+ return requests.get(0);
}
private class GnssMeasurementsListener extends IGnssMeasurementsListener.Stub {
diff --git a/media/java/android/media/AudioDeviceInfo.java b/media/java/android/media/AudioDeviceInfo.java
index 2cca669a592b..00a4c7e19f34 100644
--- a/media/java/android/media/AudioDeviceInfo.java
+++ b/media/java/android/media/AudioDeviceInfo.java
@@ -448,8 +448,7 @@ public final class AudioDeviceInfo {
* Returns an array of supported encapsulation modes for the device.
*
* The array can include any of the {@code AudioTrack} encapsulation modes,
- * e.g. {@link AudioTrack#ENCAPSULATION_MODE_NONE},
- * or {@link AudioTrack#ENCAPSULATION_MODE_ELEMENTARY_STREAM}.
+ * e.g. {@link AudioTrack#ENCAPSULATION_MODE_ELEMENTARY_STREAM}.
*
* @return An array of supported encapsulation modes for the device. This
* may be an empty array if no encapsulation modes are supported.
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index ea7a556f835b..3ac71b2cff1d 100755
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -4599,6 +4599,12 @@ public class AudioManager {
/**
* @hide
+ * Volume behavior for an audio device that has no particular volume behavior set. Invalid as
+ * an argument to {@link #setDeviceVolumeBehavior(int, String, int)}.
+ */
+ public static final int DEVICE_VOLUME_BEHAVIOR_UNSET = -1;
+ /**
+ * @hide
* Volume behavior for an audio device where a software attenuation is applied
* @see #setDeviceVolumeBehavior(int, String, int)
*/
@@ -4647,6 +4653,18 @@ public class AudioManager {
@Retention(RetentionPolicy.SOURCE)
public @interface DeviceVolumeBehavior {}
+ /** @hide */
+ @IntDef({
+ DEVICE_VOLUME_BEHAVIOR_UNSET,
+ DEVICE_VOLUME_BEHAVIOR_VARIABLE,
+ DEVICE_VOLUME_BEHAVIOR_FULL,
+ DEVICE_VOLUME_BEHAVIOR_FIXED,
+ DEVICE_VOLUME_BEHAVIOR_ABSOLUTE,
+ DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface DeviceVolumeBehaviorState {}
+
/**
* @hide
* Throws IAE on an invalid volume behavior value
@@ -4713,7 +4731,7 @@ public class AudioManager {
* @return the volume behavior for the device
*/
@RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
- public @DeviceVolumeBehavior int getDeviceVolumeBehavior(int deviceType,
+ public @DeviceVolumeBehaviorState int getDeviceVolumeBehavior(int deviceType,
@Nullable String deviceAddress) {
// verify arguments
AudioDeviceInfo.enforceValidAudioDeviceTypeOut(deviceType);
@@ -4728,8 +4746,8 @@ public class AudioManager {
* @return the volume behavior for the device
*/
@RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
- public @DeviceVolumeBehavior int getDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device)
- {
+ public @DeviceVolumeBehaviorState int getDeviceVolumeBehavior(
+ @NonNull AudioDeviceAttributes device) {
// verify arguments (validity of device type is enforced in server)
Objects.requireNonNull(device);
// communicate with service
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index 9f3fc5d94a98..1c0a526f536c 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -280,7 +280,7 @@ public class AudioTrack extends PlayerBase
/**
* Encapsulation metadata type for framework tuner information.
*
- * TODO(b/147778408) Link: Fill in Tuner API info.
+ * Refer to the Android Media TV Tuner API for details.
*/
public static final int ENCAPSULATION_METADATA_TYPE_FRAMEWORK_TUNER = 1;
diff --git a/media/java/android/media/MediaRoute2Info.java b/media/java/android/media/MediaRoute2Info.java
index 54c0bc94c2d0..fad25e071f90 100644
--- a/media/java/android/media/MediaRoute2Info.java
+++ b/media/java/android/media/MediaRoute2Info.java
@@ -226,7 +226,7 @@ public final class MediaRoute2Info implements Parcelable {
public static final int TYPE_GROUP = 2000;
/**
- * Media feature: Live audio.
+ * Route feature: Live audio.
* <p>
* A route that supports live audio routing will allow the media audio stream
* to be sent to supported destinations. This can include internal speakers or
@@ -241,7 +241,7 @@ public final class MediaRoute2Info implements Parcelable {
public static final String FEATURE_LIVE_AUDIO = "android.media.route.feature.LIVE_AUDIO";
/**
- * Media feature: Live video.
+ * Route feature: Live video.
* <p>
* A route that supports live video routing will allow a mirrored version
* of the device's primary display or a customized
@@ -262,7 +262,14 @@ public final class MediaRoute2Info implements Parcelable {
public static final String FEATURE_LIVE_VIDEO = "android.media.route.feature.LIVE_VIDEO";
/**
- * Media feature: Remote playback.
+ * Route feature: Local playback.
+ * @hide
+ */
+ public static final String FEATURE_LOCAL_PLAYBACK =
+ "android.media.route.feature.LOCAL_PLAYBACK";
+
+ /**
+ * Route feature: Remote playback.
* <p>
* A route that supports remote playback routing will allow an application to send
* requests to play content remotely to supported destinations.
@@ -283,7 +290,7 @@ public final class MediaRoute2Info implements Parcelable {
"android.media.route.feature.REMOTE_PLAYBACK";
/**
- * Media feature: Remote audio playback.
+ * Route feature: Remote audio playback.
* <p>
* A route that supports remote audio playback routing will allow an application to send
* requests to play audio content remotely to supported destinations.
@@ -295,7 +302,7 @@ public final class MediaRoute2Info implements Parcelable {
"android.media.route.feature.REMOTE_AUDIO_PLAYBACK";
/**
- * Media feature: Remote video playback.
+ * Route feature: Remote video playback.
* <p>
* A route that supports remote video playback routing will allow an application to send
* requests to play video content remotely to supported destinations.
diff --git a/media/java/android/media/MediaRoute2ProviderService.java b/media/java/android/media/MediaRoute2ProviderService.java
index e199cf49db9a..93fe06ac99aa 100644
--- a/media/java/android/media/MediaRoute2ProviderService.java
+++ b/media/java/android/media/MediaRoute2ProviderService.java
@@ -71,6 +71,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
*/
public abstract class MediaRoute2ProviderService extends Service {
private static final String TAG = "MR2ProviderService";
+ private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
/**
* The {@link Intent} action that must be declared as handled by the service.
@@ -238,6 +239,11 @@ public abstract class MediaRoute2ProviderService extends Service {
@NonNull RoutingSessionInfo sessionInfo) {
Objects.requireNonNull(sessionInfo, "sessionInfo must not be null");
+ if (DEBUG) {
+ Log.d(TAG, "notifySessionCreated: Creating a session. requestId=" + requestId
+ + ", sessionInfo=" + sessionInfo);
+ }
+
if (requestId != REQUEST_ID_NONE && !removeRequestId(requestId)) {
Log.w(TAG, "notifySessionCreated: The requestId doesn't exist. requestId=" + requestId);
return;
@@ -269,6 +275,10 @@ public abstract class MediaRoute2ProviderService extends Service {
public final void notifySessionUpdated(@NonNull RoutingSessionInfo sessionInfo) {
Objects.requireNonNull(sessionInfo, "sessionInfo must not be null");
+ if (DEBUG) {
+ Log.d(TAG, "notifySessionUpdated: Updating session id=" + sessionInfo);
+ }
+
String sessionId = sessionInfo.getId();
synchronized (mSessionLock) {
if (mSessionInfo.containsKey(sessionId)) {
@@ -299,6 +309,10 @@ public abstract class MediaRoute2ProviderService extends Service {
if (TextUtils.isEmpty(sessionId)) {
throw new IllegalArgumentException("sessionId must not be empty");
}
+ if (DEBUG) {
+ Log.d(TAG, "notifySessionReleased: Releasing session id=" + sessionId);
+ }
+
RoutingSessionInfo sessionInfo;
synchronized (mSessionLock) {
sessionInfo = mSessionInfo.remove(sessionId);
diff --git a/media/java/android/media/MediaRouter.java b/media/java/android/media/MediaRouter.java
index 7ae2949e6074..6fa378724240 100644
--- a/media/java/android/media/MediaRouter.java
+++ b/media/java/android/media/MediaRouter.java
@@ -221,12 +221,11 @@ public class MediaRouter {
if (!TextUtils.equals(newRoutes.bluetoothName, mCurAudioRoutesInfo.bluetoothName)) {
forceUseDefaultRoute = false;
- mCurAudioRoutesInfo.bluetoothName = newRoutes.bluetoothName;
- if (mCurAudioRoutesInfo.bluetoothName != null) {
+ if (newRoutes.bluetoothName != null) {
if (mBluetoothA2dpRoute == null) {
// BT connected
final RouteInfo info = new RouteInfo(mSystemCategory);
- info.mName = mCurAudioRoutesInfo.bluetoothName;
+ info.mName = newRoutes.bluetoothName;
info.mDescription = mResources.getText(
com.android.internal.R.string.bluetooth_a2dp_audio_route_name);
info.mSupportedTypes = ROUTE_TYPE_LIVE_AUDIO;
@@ -234,13 +233,14 @@ public class MediaRouter {
mBluetoothA2dpRoute = info;
addRouteStatic(mBluetoothA2dpRoute);
} else {
- mBluetoothA2dpRoute.mName = mCurAudioRoutesInfo.bluetoothName;
+ mBluetoothA2dpRoute.mName = newRoutes.bluetoothName;
dispatchRouteChanged(mBluetoothA2dpRoute);
}
} else if (mBluetoothA2dpRoute != null) {
// BT disconnected
- removeRouteStatic(mBluetoothA2dpRoute);
+ RouteInfo btRoute = mBluetoothA2dpRoute;
mBluetoothA2dpRoute = null;
+ removeRouteStatic(btRoute);
}
audioRoutesChanged = true;
}
@@ -256,6 +256,7 @@ public class MediaRouter {
}
}
}
+ mCurAudioRoutesInfo.bluetoothName = newRoutes.bluetoothName;
}
boolean isBluetoothA2dpOn() {
diff --git a/media/java/android/media/MediaRouter2.java b/media/java/android/media/MediaRouter2.java
index 0f538a57a5ee..8e95239a73f8 100644
--- a/media/java/android/media/MediaRouter2.java
+++ b/media/java/android/media/MediaRouter2.java
@@ -151,7 +151,7 @@ public final class MediaRouter2 {
*
* @hide
*/
- public static boolean checkRouteListContainsRouteId(@NonNull List<MediaRoute2Info> routeList,
+ static boolean checkRouteListContainsRouteId(@NonNull List<MediaRoute2Info> routeList,
@NonNull String routeId) {
for (MediaRoute2Info info : routeList) {
if (TextUtils.equals(routeId, info.getId())) {
@@ -258,8 +258,6 @@ public final class MediaRouter2 {
* Gets the unmodifiable list of {@link MediaRoute2Info routes} currently
* known to the media router.
* <p>
- * {@link MediaRoute2Info#isSystemRoute() System routes} such as phone speaker,
- * Bluetooth devices are always included in the list.
* Please note that the list can be changed before callbacks are invoked.
* </p>
*
@@ -274,8 +272,7 @@ public final class MediaRouter2 {
List<MediaRoute2Info> filteredRoutes = new ArrayList<>();
for (MediaRoute2Info route : mRoutes.values()) {
- if (route.isSystemRoute()
- || route.hasAnyFeatures(mDiscoveryPreference.getPreferredFeatures())) {
+ if (route.hasAnyFeatures(mDiscoveryPreference.getPreferredFeatures())) {
filteredRoutes.add(route);
}
}
@@ -378,6 +375,7 @@ public final class MediaRouter2 {
*/
public void transferTo(@NonNull MediaRoute2Info route) {
Objects.requireNonNull(route, "route must not be null");
+ Log.v(TAG, "Transferring to route: " + route);
transfer(getCurrentController(), route);
}
@@ -525,8 +523,7 @@ public final class MediaRouter2 {
if (!currentRoutesIds.contains(routeId)) {
// This route is removed while the callback is unregistered.
MediaRoute2Info route = mRoutes.get(routeId);
- if (route.isSystemRoute()
- || route.hasAnyFeatures(mDiscoveryPreference.getPreferredFeatures())) {
+ if (route.hasAnyFeatures(mDiscoveryPreference.getPreferredFeatures())) {
removedRoutes.add(mRoutes.get(routeId));
}
}
@@ -536,16 +533,14 @@ public final class MediaRouter2 {
if (mRoutes.containsKey(route.getId())) {
if (!route.equals(mRoutes.get(route.getId()))) {
// This route is changed while the callback is unregistered.
- if (route.isSystemRoute()
- || route.hasAnyFeatures(
+ if (route.hasAnyFeatures(
mDiscoveryPreference.getPreferredFeatures())) {
changedRoutes.add(route);
}
}
} else {
// This route is added while the callback is unregistered.
- if (route.isSystemRoute()
- || route.hasAnyFeatures(mDiscoveryPreference.getPreferredFeatures())) {
+ if (route.hasAnyFeatures(mDiscoveryPreference.getPreferredFeatures())) {
addedRoutes.add(route);
}
}
@@ -581,8 +576,7 @@ public final class MediaRouter2 {
synchronized (sRouterLock) {
for (MediaRoute2Info route : routes) {
mRoutes.put(route.getId(), route);
- if (route.isSystemRoute()
- || route.hasAnyFeatures(mDiscoveryPreference.getPreferredFeatures())) {
+ if (route.hasAnyFeatures(mDiscoveryPreference.getPreferredFeatures())) {
addedRoutes.add(route);
}
}
@@ -598,8 +592,7 @@ public final class MediaRouter2 {
synchronized (sRouterLock) {
for (MediaRoute2Info route : routes) {
mRoutes.remove(route.getId());
- if (route.isSystemRoute()
- || route.hasAnyFeatures(mDiscoveryPreference.getPreferredFeatures())) {
+ if (route.hasAnyFeatures(mDiscoveryPreference.getPreferredFeatures())) {
removedRoutes.add(route);
}
}
@@ -615,11 +608,11 @@ public final class MediaRouter2 {
synchronized (sRouterLock) {
for (MediaRoute2Info route : routes) {
mRoutes.put(route.getId(), route);
- if (route.isSystemRoute()
- || route.hasAnyFeatures(mDiscoveryPreference.getPreferredFeatures())) {
+ if (route.hasAnyFeatures(mDiscoveryPreference.getPreferredFeatures())) {
changedRoutes.add(route);
}
}
+ mShouldUpdateRoutes = true;
}
if (changedRoutes.size() > 0) {
notifyRoutesChanged(changedRoutes);
@@ -797,8 +790,7 @@ public final class MediaRouter2 {
private List<MediaRoute2Info> filterRoutes(List<MediaRoute2Info> routes,
RouteDiscoveryPreference discoveryRequest) {
return routes.stream()
- .filter(route -> route.isSystemRoute()
- || route.hasAnyFeatures(discoveryRequest.getPreferredFeatures()))
+ .filter(route -> route.hasAnyFeatures(discoveryRequest.getPreferredFeatures()))
.collect(Collectors.toList());
}
diff --git a/media/java/android/media/MediaRouter2Manager.java b/media/java/android/media/MediaRouter2Manager.java
index a18cfccb6cb2..dad7859db622 100644
--- a/media/java/android/media/MediaRouter2Manager.java
+++ b/media/java/android/media/MediaRouter2Manager.java
@@ -165,20 +165,8 @@ public final class MediaRouter2Manager {
public List<MediaRoute2Info> getAvailableRoutes(@NonNull String packageName) {
Objects.requireNonNull(packageName, "packageName must not be null");
- List<MediaRoute2Info> routes = new ArrayList<>();
-
- List<String> preferredFeatures = mPreferredFeaturesMap.get(packageName);
- if (preferredFeatures == null) {
- preferredFeatures = Collections.emptyList();
- }
- synchronized (mRoutesLock) {
- for (MediaRoute2Info route : mRoutes.values()) {
- if (route.isSystemRoute() || route.hasAnyFeatures(preferredFeatures)) {
- routes.add(route);
- }
- }
- }
- return routes;
+ List<RoutingSessionInfo> sessions = getRoutingSessions(packageName);
+ return getAvailableRoutesForRoutingSession(sessions.get(sessions.size() - 1));
}
/**
@@ -202,7 +190,7 @@ public final class MediaRouter2Manager {
}
synchronized (mRoutesLock) {
for (MediaRoute2Info route : mRoutes.values()) {
- if (route.isSystemRoute() || route.hasAnyFeatures(preferredFeatures)
+ if (route.hasAnyFeatures(preferredFeatures)
|| sessionInfo.getSelectedRoutes().contains(route.getId())
|| sessionInfo.getTransferableRoutes().contains(route.getId())) {
routes.add(route);
@@ -303,7 +291,7 @@ public final class MediaRouter2Manager {
}
/**
- * Gets the list of all discovered routes
+ * Gets the list of all discovered routes.
*/
@NonNull
public List<MediaRoute2Info> getAllRoutes() {
@@ -321,6 +309,8 @@ public final class MediaRouter2Manager {
Objects.requireNonNull(packageName, "packageName must not be null");
Objects.requireNonNull(route, "route must not be null");
+ Log.v(TAG, "Selecting route. packageName= " + packageName + ", route=" + route);
+
List<RoutingSessionInfo> sessionInfos = getRoutingSessions(packageName);
RoutingSessionInfo targetSession = sessionInfos.get(sessionInfos.size() - 1);
transfer(targetSession, route);
@@ -342,6 +332,8 @@ public final class MediaRouter2Manager {
Objects.requireNonNull(sessionInfo, "sessionInfo must not be null");
Objects.requireNonNull(route, "route must not be null");
+ Log.v(TAG, "Transferring routing session. session= " + sessionInfo + ", route=" + route);
+
synchronized (mRoutesLock) {
if (!mRoutes.containsKey(route.getId())) {
Log.w(TAG, "transfer: Ignoring an unknown route id=" + route.getId());
@@ -576,6 +568,10 @@ public final class MediaRouter2Manager {
}
void updatePreferredFeatures(String packageName, List<String> preferredFeatures) {
+ if (preferredFeatures == null) {
+ mPreferredFeaturesMap.remove(packageName);
+ return;
+ }
List<String> prevFeatures = mPreferredFeaturesMap.put(packageName, preferredFeatures);
if ((prevFeatures == null && preferredFeatures.size() == 0)
|| Objects.equals(preferredFeatures, prevFeatures)) {
diff --git a/media/java/android/media/tv/tuner/filter/MediaEvent.java b/media/java/android/media/tv/tuner/filter/MediaEvent.java
index af63070027a2..57a04fd70a0b 100644
--- a/media/java/android/media/tv/tuner/filter/MediaEvent.java
+++ b/media/java/android/media/tv/tuner/filter/MediaEvent.java
@@ -29,6 +29,7 @@ import android.media.MediaCodec.LinearBlock;
@SystemApi
public class MediaEvent extends FilterEvent {
private long mNativeContext;
+ private boolean mReleased = false;
private final Object mLock = new Object();
private native Long nativeGetAudioHandle();
@@ -181,7 +182,21 @@ public class MediaEvent extends FilterEvent {
*/
@Override
protected void finalize() {
- nativeFinalize();
- mNativeContext = 0;
+ release();
+ }
+
+ /**
+ * Releases the MediaEvent object.
+ * @hide
+ */
+ public void release() {
+ synchronized (mLock) {
+ if (mReleased) {
+ return;
+ }
+ nativeFinalize();
+ mNativeContext = 0;
+ mReleased = true;
+ }
}
}
diff --git a/media/jni/android_media_MediaCodec.cpp b/media/jni/android_media_MediaCodec.cpp
index f970b598d6f8..0b0e162d4faf 100644
--- a/media/jni/android_media_MediaCodec.cpp
+++ b/media/jni/android_media_MediaCodec.cpp
@@ -235,7 +235,10 @@ void JMediaCodec::release() {
void JMediaCodec::releaseAsync() {
std::call_once(mAsyncReleaseFlag, [this] {
if (mCodec != NULL) {
- mCodec->releaseAsync(new AMessage(kWhatAsyncReleaseComplete, this));
+ sp<AMessage> notify = new AMessage(kWhatAsyncReleaseComplete, this);
+ // Hold strong reference to this until async release is complete
+ notify->setObject("this", this);
+ mCodec->releaseAsync(notify);
}
mInitStatus = NO_INIT;
});
@@ -1088,8 +1091,11 @@ void JMediaCodec::onMessageReceived(const sp<AMessage> &msg) {
}
case kWhatAsyncReleaseComplete:
{
- mCodec.clear();
- mLooper->stop();
+ if (mLooper != NULL) {
+ mLooper->unregisterHandler(id());
+ mLooper->stop();
+ mLooper.clear();
+ }
break;
}
default:
@@ -1104,7 +1110,7 @@ void JMediaCodec::onMessageReceived(const sp<AMessage> &msg) {
using namespace android;
static sp<JMediaCodec> setMediaCodec(
- JNIEnv *env, jobject thiz, const sp<JMediaCodec> &codec) {
+ JNIEnv *env, jobject thiz, const sp<JMediaCodec> &codec, bool release = true) {
sp<JMediaCodec> old = (JMediaCodec *)env->CallLongMethod(thiz, gFields.lockAndGetContextID);
if (codec != NULL) {
codec->incStrong(thiz);
@@ -1115,7 +1121,9 @@ static sp<JMediaCodec> setMediaCodec(
* its message handler, doing release() from there will deadlock
* (as MediaCodec::release() post synchronous message to the same looper)
*/
- old->release();
+ if (release) {
+ old->release();
+ }
old->decStrong(thiz);
}
env->CallVoidMethod(thiz, gFields.setAndUnlockContextID, (jlong)codec.get());
@@ -1130,7 +1138,8 @@ static sp<JMediaCodec> getMediaCodec(JNIEnv *env, jobject thiz) {
}
static void android_media_MediaCodec_release(JNIEnv *env, jobject thiz) {
- sp<JMediaCodec> codec = getMediaCodec(env, thiz);
+ // Clear Java native reference.
+ sp<JMediaCodec> codec = setMediaCodec(env, thiz, nullptr, false /* release */);
if (codec != NULL) {
codec->releaseAsync();
}
diff --git a/media/jni/android_media_tv_Tuner.cpp b/media/jni/android_media_tv_Tuner.cpp
index 7e721406a300..e8f18a59049e 100644
--- a/media/jni/android_media_tv_Tuner.cpp
+++ b/media/jni/android_media_tv_Tuner.cpp
@@ -314,8 +314,9 @@ MediaEvent::~MediaEvent() {
if (mIonHandle != NULL) {
delete mIonHandle;
}
- if (mC2Buffer != NULL) {
- mC2Buffer->unregisterOnDestroyNotify(&DestroyCallback, this);
+ std::shared_ptr<C2Buffer> pC2Buffer = mC2Buffer.lock();
+ if (pC2Buffer != NULL) {
+ pC2Buffer->unregisterOnDestroyNotify(&DestroyCallback, this);
}
}
@@ -340,15 +341,17 @@ jobject MediaEvent::getLinearBlock() {
JNIEnv *env = AndroidRuntime::getJNIEnv();
std::unique_ptr<JMediaCodecLinearBlock> context{new JMediaCodecLinearBlock};
context->mBlock = block;
- mC2Buffer = context->toC2Buffer(0, mDataLength);
+ std::shared_ptr<C2Buffer> pC2Buffer = context->toC2Buffer(0, mDataLength);
+ context->mBuffer = pC2Buffer;
+ mC2Buffer = pC2Buffer;
if (mAvHandle->numInts > 0) {
// use first int in the native_handle as the index
int index = mAvHandle->data[mAvHandle->numFds];
std::shared_ptr<C2Param> c2param = std::make_shared<C2DataIdInfo>(index, mDataId);
std::shared_ptr<C2Info> info(std::static_pointer_cast<C2Info>(c2param));
- mC2Buffer->setInfo(info);
+ pC2Buffer->setInfo(info);
}
- mC2Buffer->registerOnDestroyNotify(&DestroyCallback, this);
+ pC2Buffer->registerOnDestroyNotify(&DestroyCallback, this);
jobject linearBlock =
env->NewObject(
env->FindClass("android/media/MediaCodec$LinearBlock"),
diff --git a/media/jni/android_media_tv_Tuner.h b/media/jni/android_media_tv_Tuner.h
index c469a3ad8b76..83e9db796363 100644
--- a/media/jni/android_media_tv_Tuner.h
+++ b/media/jni/android_media_tv_Tuner.h
@@ -130,7 +130,7 @@ struct MediaEvent : public RefBase {
jweak mMediaEventObj;
jweak mLinearBlockObj;
C2HandleIon* mIonHandle;
- std::shared_ptr<C2Buffer> mC2Buffer;
+ std::weak_ptr<C2Buffer> mC2Buffer;
};
struct Filter : public RefBase {
diff --git a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2ManagerTest.java b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2ManagerTest.java
index 638a842e4e5f..0979627e5e8d 100644
--- a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2ManagerTest.java
+++ b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2ManagerTest.java
@@ -97,7 +97,6 @@ public class MediaRouter2ManagerTest {
public static final List<String> FEATURES_ALL = new ArrayList();
public static final List<String> FEATURES_SPECIAL = new ArrayList();
- private static final List<String> FEATURES_LIVE_AUDIO = new ArrayList<>();
static {
FEATURES_ALL.add(FEATURE_SAMPLE);
@@ -105,8 +104,6 @@ public class MediaRouter2ManagerTest {
FEATURES_ALL.add(FEATURE_LIVE_AUDIO);
FEATURES_SPECIAL.add(FEATURE_SPECIAL);
-
- FEATURES_LIVE_AUDIO.add(FEATURE_LIVE_AUDIO);
}
@Before
diff --git a/mime/java-res/android.mime.types b/mime/java-res/android.mime.types
index 05a2e92ca080..f3730f2756d2 100644
--- a/mime/java-res/android.mime.types
+++ b/mime/java-res/android.mime.types
@@ -84,6 +84,7 @@
?audio/sp-midi smf
?audio/x-matroska mka
?audio/x-pn-realaudio ra
+?audio/x-mpeg mp3
?image/bmp bmp
?image/heic heic
diff --git a/packages/CarSystemUI/res/xml/overlayable.xml b/packages/CarSystemUI/res/xml/overlayable.xml
deleted file mode 100644
index 2b6e66e28b5f..000000000000
--- a/packages/CarSystemUI/res/xml/overlayable.xml
+++ /dev/null
@@ -1,23 +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.
--->
-
-<resources>
- <overlayable name="SystemBarsLayouts">
- <policy type="product|signature">
- <item type="layout" name="car_navigation_bar" />
- </policy>
- </overlayable>
-</resources> \ No newline at end of file
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBar.java b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBar.java
index 4c720abb4c74..37dfce4e16ce 100644
--- a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBar.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBar.java
@@ -16,10 +16,10 @@
package com.android.systemui.car.navigationbar;
-import static android.view.InsetsState.ITYPE_BOTTOM_GESTURES;
+import static android.view.InsetsState.ITYPE_CLIMATE_BAR;
+import static android.view.InsetsState.ITYPE_EXTRA_NAVIGATION_BAR;
import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
import static android.view.InsetsState.ITYPE_STATUS_BAR;
-import static android.view.InsetsState.ITYPE_TOP_GESTURES;
import static android.view.InsetsState.containsType;
import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS;
@@ -368,15 +368,13 @@ public class CarNavigationBar extends SystemUI implements CommandQueue.Callbacks
WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
height,
- WindowManager.LayoutParams.TYPE_STATUS_BAR_ADDITIONAL,
+ WindowManager.LayoutParams.TYPE_STATUS_BAR,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
| WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
PixelFormat.TRANSLUCENT);
lp.setTitle("TopCarNavigationBar");
- lp.providesInsetsTypes = new int[]{ITYPE_STATUS_BAR, ITYPE_TOP_GESTURES};
- lp.setFitInsetsTypes(0);
lp.windowAnimations = 0;
lp.gravity = Gravity.TOP;
mWindowManager.addView(mTopNavigationBarWindow, lp);
@@ -390,14 +388,13 @@ public class CarNavigationBar extends SystemUI implements CommandQueue.Callbacks
WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
height,
- WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
+ WindowManager.LayoutParams.TYPE_NAVIGATION_BAR,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
| WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
PixelFormat.TRANSLUCENT);
lp.setTitle("BottomCarNavigationBar");
- lp.providesInsetsTypes = new int[]{ITYPE_NAVIGATION_BAR, ITYPE_BOTTOM_GESTURES};
lp.windowAnimations = 0;
lp.gravity = Gravity.BOTTOM;
mWindowManager.addView(mBottomNavigationBarWindow, lp);
@@ -415,6 +412,8 @@ public class CarNavigationBar extends SystemUI implements CommandQueue.Callbacks
| WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
PixelFormat.TRANSLUCENT);
leftlp.setTitle("LeftCarNavigationBar");
+ leftlp.providesInsetsTypes = new int[]{ITYPE_CLIMATE_BAR};
+ leftlp.setFitInsetsTypes(0);
leftlp.windowAnimations = 0;
leftlp.gravity = Gravity.LEFT;
mWindowManager.addView(mLeftNavigationBarWindow, leftlp);
@@ -432,6 +431,8 @@ public class CarNavigationBar extends SystemUI implements CommandQueue.Callbacks
| WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
PixelFormat.TRANSLUCENT);
rightlp.setTitle("RightCarNavigationBar");
+ rightlp.providesInsetsTypes = new int[]{ITYPE_EXTRA_NAVIGATION_BAR};
+ rightlp.setFitInsetsTypes(0);
rightlp.windowAnimations = 0;
rightlp.gravity = Gravity.RIGHT;
mWindowManager.addView(mRightNavigationBarWindow, rightlp);
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarView.java b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarView.java
index 0ced4021ce38..029d4c7fa2fb 100644
--- a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarView.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarView.java
@@ -16,10 +16,7 @@
package com.android.systemui.car.navigationbar;
-import static android.view.WindowInsets.Type.systemBars;
-
import android.content.Context;
-import android.graphics.Insets;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
@@ -82,28 +79,9 @@ public class CarNavigationBarView extends LinearLayout {
@Override
public WindowInsets onApplyWindowInsets(WindowInsets windowInsets) {
- applyMargins(windowInsets.getInsets(systemBars()));
return windowInsets;
}
- private void applyMargins(Insets insets) {
- final int count = getChildCount();
- for (int i = 0; i < count; i++) {
- View child = getChildAt(i);
- if (child.getLayoutParams() instanceof LayoutParams) {
- LayoutParams lp = (LayoutParams) child.getLayoutParams();
- if (lp.rightMargin != insets.right || lp.leftMargin != insets.left
- || lp.topMargin != insets.top || lp.bottomMargin != insets.bottom) {
- lp.rightMargin = insets.right;
- lp.leftMargin = insets.left;
- lp.topMargin = insets.top;
- lp.bottomMargin = insets.bottom;
- child.requestLayout();
- }
- }
- }
- }
-
// Used to forward touch events even if the touch was initiated from a child component
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewController.java b/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewController.java
index 1738091d14c9..1eead62c042a 100644
--- a/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewController.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewController.java
@@ -48,17 +48,21 @@ import com.android.systemui.car.CarServiceProvider;
import com.android.systemui.car.window.OverlayPanelViewController;
import com.android.systemui.car.window.OverlayViewGlobalStateController;
import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.dagger.qualifiers.UiBackground;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.FlingAnimationUtils;
import com.android.systemui.statusbar.StatusBarState;
+import java.util.concurrent.Executor;
+
import javax.inject.Inject;
import javax.inject.Singleton;
/** View controller for the notification panel. */
@Singleton
-public class NotificationPanelViewController extends OverlayPanelViewController {
+public class NotificationPanelViewController extends OverlayPanelViewController
+ implements CommandQueue.Callbacks {
private static final boolean DEBUG = true;
private static final String TAG = "NotificationPanelViewController";
@@ -68,12 +72,14 @@ public class NotificationPanelViewController extends OverlayPanelViewController
private final CarServiceProvider mCarServiceProvider;
private final IStatusBarService mBarService;
private final CommandQueue mCommandQueue;
+ private final Executor mUiBgExecutor;
private final NotificationDataManager mNotificationDataManager;
private final CarUxRestrictionManagerWrapper mCarUxRestrictionManagerWrapper;
private final CarNotificationListener mCarNotificationListener;
private final NotificationClickHandlerFactory mNotificationClickHandlerFactory;
private final StatusBarStateController mStatusBarStateController;
private final boolean mEnableHeadsUpNotificationWhenNotificationShadeOpen;
+ private final NotificationVisibilityLogger mNotificationVisibilityLogger;
private float mInitialBackgroundAlpha;
private float mBackgroundAlphaDiff;
@@ -98,6 +104,7 @@ public class NotificationPanelViewController extends OverlayPanelViewController
@Main Resources resources,
OverlayViewGlobalStateController overlayViewGlobalStateController,
FlingAnimationUtils.Builder flingAnimationUtilsBuilder,
+ @UiBackground Executor uiBgExecutor,
/* Other things */
CarServiceProvider carServiceProvider,
@@ -110,6 +117,7 @@ public class NotificationPanelViewController extends OverlayPanelViewController
CarUxRestrictionManagerWrapper carUxRestrictionManagerWrapper,
CarNotificationListener carNotificationListener,
NotificationClickHandlerFactory notificationClickHandlerFactory,
+ NotificationVisibilityLogger notificationVisibilityLogger,
/* Things that need to be replaced */
StatusBarStateController statusBarStateController
@@ -121,12 +129,15 @@ public class NotificationPanelViewController extends OverlayPanelViewController
mCarServiceProvider = carServiceProvider;
mBarService = barService;
mCommandQueue = commandQueue;
+ mUiBgExecutor = uiBgExecutor;
mNotificationDataManager = notificationDataManager;
mCarUxRestrictionManagerWrapper = carUxRestrictionManagerWrapper;
mCarNotificationListener = carNotificationListener;
mNotificationClickHandlerFactory = notificationClickHandlerFactory;
mStatusBarStateController = statusBarStateController;
+ mNotificationVisibilityLogger = notificationVisibilityLogger;
+ mCommandQueue.addCallback(this);
// Notification background setup.
mInitialBackgroundAlpha = (float) mResources.getInteger(
R.integer.config_initialNotificationBackgroundAlpha) / 100;
@@ -151,12 +162,36 @@ public class NotificationPanelViewController extends OverlayPanelViewController
.config_enableHeadsUpNotificationWhenNotificationShadeOpen);
}
+ // CommandQueue.Callbacks
+
+ @Override
+ public void animateExpandNotificationsPanel() {
+ if (!isPanelExpanded()) {
+ toggle();
+ }
+ }
+
+ @Override
+ public void animateCollapsePanels(int flags, boolean force) {
+ if (isPanelExpanded()) {
+ toggle();
+ }
+ }
+
+ // OverlayViewController
+
@Override
protected void onFinishInflate() {
reinflate();
}
@Override
+ protected void hideInternal() {
+ super.hideInternal();
+ mNotificationVisibilityLogger.stop();
+ }
+
+ @Override
protected boolean shouldShowNavigationBar() {
return true;
}
@@ -197,6 +232,11 @@ public class NotificationPanelViewController extends OverlayPanelViewController
mUnseenCountUpdateListener.onUnseenCountUpdate(
mNotificationDataManager.getUnseenNotificationCount());
}
+ mCarNotificationListener.setNotificationsShown(
+ mNotificationDataManager.getSeenNotifications());
+ // This logs both when the notification panel is expanded and when the notification
+ // panel is scrolled.
+ mNotificationVisibilityLogger.log(isPanelExpanded());
});
mNotificationClickHandlerFactory.setNotificationDataManager(mNotificationDataManager);
@@ -332,6 +372,8 @@ public class NotificationPanelViewController extends OverlayPanelViewController
mNotificationDataManager.clearAll();
}
+ // OverlayPanelViewController
+
@Override
protected boolean shouldAnimateCollapsePanel() {
return true;
@@ -364,6 +406,30 @@ public class NotificationPanelViewController extends OverlayPanelViewController
}
@Override
+ protected void onPanelVisible(boolean visible) {
+ super.onPanelVisible(visible);
+ mUiBgExecutor.execute(() -> {
+ try {
+ if (visible) {
+ // When notification panel is open even just a bit, we want to clear
+ // notification effects.
+ boolean clearNotificationEffects =
+ mStatusBarStateController.getState() != StatusBarState.KEYGUARD;
+ mBarService.onPanelRevealed(clearNotificationEffects,
+ mNotificationDataManager.getVisibleNotifications().size());
+ } else {
+ mBarService.onPanelHidden();
+ }
+ } catch (RemoteException ex) {
+ // Won't fail unless the world has ended.
+ Log.e(TAG, String.format(
+ "Unable to notify StatusBarService of panel visibility: %s", visible));
+ }
+ });
+
+ }
+
+ @Override
protected void onPanelExpanded(boolean expand) {
super.onPanelExpanded(expand);
@@ -373,6 +439,9 @@ public class NotificationPanelViewController extends OverlayPanelViewController
}
clearNotificationEffects();
}
+ if (!expand) {
+ mNotificationVisibilityLogger.log(isPanelExpanded());
+ }
}
/**
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationVisibilityLogger.java b/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationVisibilityLogger.java
new file mode 100644
index 000000000000..44c819711bd2
--- /dev/null
+++ b/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationVisibilityLogger.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.car.notification;
+
+import android.os.RemoteException;
+import android.util.ArraySet;
+import android.util.Log;
+
+import com.android.car.notification.AlertEntry;
+import com.android.car.notification.NotificationDataManager;
+import com.android.internal.statusbar.IStatusBarService;
+import com.android.internal.statusbar.NotificationVisibility;
+import com.android.systemui.dagger.qualifiers.UiBackground;
+
+import java.util.Set;
+import java.util.concurrent.Executor;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+/**
+ * Handles notification logging, in particular, logging which notifications are visible and which
+ * are not.
+ */
+@Singleton
+public class NotificationVisibilityLogger {
+
+ private static final String TAG = "NotificationVisibilityLogger";
+
+ private final ArraySet<NotificationVisibility> mCurrentlyVisible = new ArraySet<>();
+ private final ArraySet<NotificationVisibility> mNewlyVisible = new ArraySet<>();
+ private final ArraySet<NotificationVisibility> mPreviouslyVisible = new ArraySet<>();
+ private final ArraySet<NotificationVisibility> mTmpCurrentlyVisible = new ArraySet<>();
+
+ private final IStatusBarService mBarService;
+ private final Executor mUiBgExecutor;
+ private final NotificationDataManager mNotificationDataManager;
+
+ private boolean mIsVisible;
+
+ private final Runnable mVisibilityReporter = new Runnable() {
+
+ @Override
+ public void run() {
+ if (mIsVisible) {
+ int count = mNotificationDataManager.getVisibleNotifications().size();
+ for (AlertEntry alertEntry : mNotificationDataManager.getVisibleNotifications()) {
+ NotificationVisibility visObj = NotificationVisibility.obtain(
+ alertEntry.getKey(),
+ /* rank= */ -1,
+ count,
+ mIsVisible,
+ NotificationVisibility.NotificationLocation.LOCATION_MAIN_AREA);
+ mTmpCurrentlyVisible.add(visObj);
+ if (!mCurrentlyVisible.contains(visObj)) {
+ mNewlyVisible.add(visObj);
+ }
+ }
+ }
+ mPreviouslyVisible.addAll(mCurrentlyVisible);
+ mPreviouslyVisible.removeAll(mTmpCurrentlyVisible);
+ onNotificationVisibilityChanged(mNewlyVisible, mPreviouslyVisible);
+
+ recycleAllVisibilityObjects(mCurrentlyVisible);
+ mCurrentlyVisible.addAll(mTmpCurrentlyVisible);
+
+ recycleAllVisibilityObjects(mPreviouslyVisible);
+ recycleAllVisibilityObjects(mNewlyVisible);
+ recycleAllVisibilityObjects(mTmpCurrentlyVisible);
+ }
+ };
+
+ @Inject
+ public NotificationVisibilityLogger(
+ @UiBackground Executor uiBgExecutor,
+ IStatusBarService barService,
+ NotificationDataManager notificationDataManager) {
+ mUiBgExecutor = uiBgExecutor;
+ mBarService = barService;
+ mNotificationDataManager = notificationDataManager;
+ }
+
+ /** Triggers a visibility report update to be sent to StatusBarService. */
+ public void log(boolean isVisible) {
+ mIsVisible = isVisible;
+ mUiBgExecutor.execute(mVisibilityReporter);
+ }
+
+ /** Stops logging, clearing all visibility objects. */
+ public void stop() {
+ recycleAllVisibilityObjects(mCurrentlyVisible);
+ }
+
+ /**
+ * Notify StatusBarService of change in notifications' visibility.
+ */
+ private void onNotificationVisibilityChanged(
+ Set<NotificationVisibility> newlyVisible, Set<NotificationVisibility> noLongerVisible) {
+ if (newlyVisible.isEmpty() && noLongerVisible.isEmpty()) {
+ return;
+ }
+
+ try {
+ mBarService.onNotificationVisibilityChanged(
+ cloneVisibilitiesAsArr(newlyVisible), cloneVisibilitiesAsArr(noLongerVisible));
+ } catch (RemoteException e) {
+ // Won't fail unless the world has ended.
+ Log.e(TAG, "Failed to notify StatusBarService of notification visibility change");
+ }
+ }
+
+ /**
+ * Clears array and recycles NotificationVisibility objects for reuse.
+ */
+ private static void recycleAllVisibilityObjects(ArraySet<NotificationVisibility> array) {
+ for (int i = 0; i < array.size(); i++) {
+ array.valueAt(i).recycle();
+ }
+ array.clear();
+ }
+
+ /**
+ * Converts Set of NotificationVisibility objects to primitive array.
+ */
+ private static NotificationVisibility[] cloneVisibilitiesAsArr(Set<NotificationVisibility> c) {
+ NotificationVisibility[] array = new NotificationVisibility[c.size()];
+ int i = 0;
+ for (NotificationVisibility nv : c) {
+ if (nv != null) {
+ array[i] = nv.clone();
+ }
+ i++;
+ }
+ return array;
+ }
+}
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/notification/NotificationVisibilityLoggerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/notification/NotificationVisibilityLoggerTest.java
new file mode 100644
index 000000000000..89dac58cd2a7
--- /dev/null
+++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/notification/NotificationVisibilityLoggerTest.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.car.notification;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.Notification;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.service.notification.StatusBarNotification;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.car.notification.AlertEntry;
+import com.android.car.notification.NotificationDataManager;
+import com.android.internal.statusbar.IStatusBarService;
+import com.android.internal.statusbar.NotificationVisibility;
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.util.concurrency.FakeExecutor;
+import com.android.systemui.util.time.FakeSystemClock;
+
+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 java.util.Collections;
+
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+@SmallTest
+public class NotificationVisibilityLoggerTest extends SysuiTestCase {
+
+ private static final String PKG = "package_1";
+ private static final String OP_PKG = "OpPackage";
+ private static final int ID = 1;
+ private static final String TAG = "Tag";
+ private static final int UID = 2;
+ private static final int INITIAL_PID = 3;
+ private static final String CHANNEL_ID = "CHANNEL_ID";
+ private static final String CONTENT_TITLE = "CONTENT_TITLE";
+ private static final String OVERRIDE_GROUP_KEY = "OVERRIDE_GROUP_KEY";
+ private static final long POST_TIME = 12345L;
+ private static final UserHandle USER_HANDLE = new UserHandle(12);
+
+ @Mock
+ private IStatusBarService mBarService;
+ @Mock
+ private NotificationDataManager mNotificationDataManager;
+
+ private NotificationVisibilityLogger mNotificationVisibilityLogger;
+ private FakeExecutor mUiBgExecutor;
+ private AlertEntry mMessageNotification;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(/* testClass= */this);
+
+ mUiBgExecutor = new FakeExecutor(new FakeSystemClock());
+ Notification.Builder mNotificationBuilder1 = new Notification.Builder(mContext, CHANNEL_ID)
+ .setContentTitle(CONTENT_TITLE);
+ mMessageNotification = new AlertEntry(new StatusBarNotification(PKG, OP_PKG,
+ ID, TAG, UID, INITIAL_PID, mNotificationBuilder1.build(), USER_HANDLE,
+ OVERRIDE_GROUP_KEY, POST_TIME));
+
+ when(mNotificationDataManager.getVisibleNotifications()).thenReturn(
+ Collections.singletonList(mMessageNotification));
+
+ mNotificationVisibilityLogger = new NotificationVisibilityLogger(
+ mUiBgExecutor, mBarService, mNotificationDataManager);
+ }
+
+ @Test
+ public void log_notifiesStatusBarService() throws RemoteException {
+ mNotificationVisibilityLogger.log(/* isVisible= */ true);
+ mUiBgExecutor.runNextReady();
+
+ verify(mBarService).onNotificationVisibilityChanged(
+ any(NotificationVisibility[].class), any(NotificationVisibility[].class));
+ }
+
+ @Test
+ public void log_isVisibleIsTrue_notifiesOfNewlyVisibleItems() throws RemoteException {
+ ArgumentCaptor<NotificationVisibility[]> newlyVisibleCaptor =
+ ArgumentCaptor.forClass(NotificationVisibility[].class);
+ ArgumentCaptor<NotificationVisibility[]> previouslyVisibleCaptor =
+ ArgumentCaptor.forClass(NotificationVisibility[].class);
+
+ mNotificationVisibilityLogger.log(/* isVisible= */ true);
+ mUiBgExecutor.runNextReady();
+
+ verify(mBarService).onNotificationVisibilityChanged(
+ newlyVisibleCaptor.capture(), previouslyVisibleCaptor.capture());
+ assertThat(newlyVisibleCaptor.getValue().length).isEqualTo(1);
+ assertThat(previouslyVisibleCaptor.getValue().length).isEqualTo(0);
+ }
+
+ @Test
+ public void log_isVisibleIsFalse_notifiesOfPreviouslyVisibleItems() throws RemoteException {
+ ArgumentCaptor<NotificationVisibility[]> newlyVisibleCaptor =
+ ArgumentCaptor.forClass(NotificationVisibility[].class);
+ ArgumentCaptor<NotificationVisibility[]> previouslyVisibleCaptor =
+ ArgumentCaptor.forClass(NotificationVisibility[].class);
+ mNotificationVisibilityLogger.log(/* isVisible= */ true);
+ mUiBgExecutor.runNextReady();
+ reset(mBarService);
+
+ mNotificationVisibilityLogger.log(/* isVisible= */ false);
+ mUiBgExecutor.runNextReady();
+
+ verify(mBarService).onNotificationVisibilityChanged(
+ newlyVisibleCaptor.capture(), previouslyVisibleCaptor.capture());
+ assertThat(previouslyVisibleCaptor.getValue().length).isEqualTo(1);
+ assertThat(newlyVisibleCaptor.getValue().length).isEqualTo(0);
+ }
+}
diff --git a/packages/OsuLogin/res/values-af/strings.xml b/packages/OsuLogin/res/values-af/strings.xml
deleted file mode 100644
index bfeee10622ae..000000000000
--- a/packages/OsuLogin/res/values-af/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Sluit aanlyn aan"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Kon nie aanmeld nie"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-am/strings.xml b/packages/OsuLogin/res/values-am/strings.xml
deleted file mode 100644
index e27c578343ef..000000000000
--- a/packages/OsuLogin/res/values-am/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"የመስመር ላይ ምዝገባ"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"ምዝገባ አልተሳካም"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-ar/strings.xml b/packages/OsuLogin/res/values-ar/strings.xml
deleted file mode 100644
index b72d7c1b45f8..000000000000
--- a/packages/OsuLogin/res/values-ar/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"الاشتراك على الإنترنت"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"تعذّر الاشتراك."</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-as/strings.xml b/packages/OsuLogin/res/values-as/strings.xml
deleted file mode 100644
index 422de3222871..000000000000
--- a/packages/OsuLogin/res/values-as/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"অনলাইনত ছাই আপ কৰক"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"ছাইন আপ কৰিব পৰা নগ’ল"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-az/strings.xml b/packages/OsuLogin/res/values-az/strings.xml
deleted file mode 100644
index 977f93982619..000000000000
--- a/packages/OsuLogin/res/values-az/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Onlayn Qeydiyyat"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Qeydiyyat alınmadı"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-b+sr+Latn/strings.xml b/packages/OsuLogin/res/values-b+sr+Latn/strings.xml
deleted file mode 100644
index 6eb2cc119ef9..000000000000
--- a/packages/OsuLogin/res/values-b+sr+Latn/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Onlajn registracija"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Registracija nije uspela"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-be/strings.xml b/packages/OsuLogin/res/values-be/strings.xml
deleted file mode 100644
index 158c3f22ce21..000000000000
--- a/packages/OsuLogin/res/values-be/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Зарэгістравацца ў інтэрнэце"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Не ўдалося зарэгістравацца"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-bg/strings.xml b/packages/OsuLogin/res/values-bg/strings.xml
deleted file mode 100644
index ea3145dcb87f..000000000000
--- a/packages/OsuLogin/res/values-bg/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Онлайн регистрация"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Регистрацията не бе успешна"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-bn/strings.xml b/packages/OsuLogin/res/values-bn/strings.xml
deleted file mode 100644
index c9f615e2d017..000000000000
--- a/packages/OsuLogin/res/values-bn/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"অনলাইনে সাইন-আপ করুন"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"সাইন-আপ করা যায়নি"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-bs/strings.xml b/packages/OsuLogin/res/values-bs/strings.xml
deleted file mode 100644
index e9b9751c95cf..000000000000
--- a/packages/OsuLogin/res/values-bs/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Online registracija"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Registracija nije uspjela"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-ca/strings.xml b/packages/OsuLogin/res/values-ca/strings.xml
deleted file mode 100644
index 7d9309616592..000000000000
--- a/packages/OsuLogin/res/values-ca/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Registre en línia"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Ha fallat el registre"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-cs/strings.xml b/packages/OsuLogin/res/values-cs/strings.xml
deleted file mode 100644
index b9cb7942bc79..000000000000
--- a/packages/OsuLogin/res/values-cs/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Online registrace"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Registrace selhala"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-da/strings.xml b/packages/OsuLogin/res/values-da/strings.xml
deleted file mode 100644
index 68c93b78a46d..000000000000
--- a/packages/OsuLogin/res/values-da/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Online registrering"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Registrering mislykkedes"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-de/strings.xml b/packages/OsuLogin/res/values-de/strings.xml
deleted file mode 100644
index 7e5a3106db4a..000000000000
--- a/packages/OsuLogin/res/values-de/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Online-Registrierung"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Registrierung fehlgeschlagen"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-el/strings.xml b/packages/OsuLogin/res/values-el/strings.xml
deleted file mode 100644
index a58e4817a3cb..000000000000
--- a/packages/OsuLogin/res/values-el/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Εγγραφή στο διαδίκτυο"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Αποτυχία εγγραφής"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-en-rAU/strings.xml b/packages/OsuLogin/res/values-en-rAU/strings.xml
deleted file mode 100644
index fbbcab17c412..000000000000
--- a/packages/OsuLogin/res/values-en-rAU/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Online sign-up"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Sign-up failed"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-en-rCA/strings.xml b/packages/OsuLogin/res/values-en-rCA/strings.xml
deleted file mode 100644
index fbbcab17c412..000000000000
--- a/packages/OsuLogin/res/values-en-rCA/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Online sign-up"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Sign-up failed"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-en-rGB/strings.xml b/packages/OsuLogin/res/values-en-rGB/strings.xml
deleted file mode 100644
index fbbcab17c412..000000000000
--- a/packages/OsuLogin/res/values-en-rGB/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Online sign-up"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Sign-up failed"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-en-rIN/strings.xml b/packages/OsuLogin/res/values-en-rIN/strings.xml
deleted file mode 100644
index fbbcab17c412..000000000000
--- a/packages/OsuLogin/res/values-en-rIN/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Online sign-up"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Sign-up failed"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-en-rXC/strings.xml b/packages/OsuLogin/res/values-en-rXC/strings.xml
deleted file mode 100644
index af7ff67c86b2..000000000000
--- a/packages/OsuLogin/res/values-en-rXC/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‎‎‎‎‎‏‎‏‏‏‎‏‏‎‏‎‏‏‏‏‎‎‏‏‏‎‏‎‏‎‏‏‎‎‎‏‎‏‎‏‏‎‎‎‎‏‎‏‏‎‏‎‎‏‎‏‎OsuLogin‎‏‎‎‏‎"</string>
- <string name="action_bar_label" msgid="550995560341508693">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‏‏‎‏‎‎‏‎‏‏‎‎‎‎‏‏‏‏‎‎‎‏‎‏‎‏‏‏‏‎‏‏‎‏‏‏‏‏‎‎‏‎‎‎‏‎‎‏‎‎‏‎‏‎‏‎‏‎Online Sign Up‎‏‎‎‏‎"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‏‏‎‎‏‏‏‏‎‎‏‏‎‎‎‏‏‏‎‏‏‏‏‎‏‎‎‎‏‏‎‏‏‏‏‎‎‏‏‎‎‏‏‎‏‎‎‎‏‏‎‏‏‎‎‎‎‎Sign-up failed‎‏‎‎‏‎"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-es-rUS/strings.xml b/packages/OsuLogin/res/values-es-rUS/strings.xml
deleted file mode 100644
index 144804cd891c..000000000000
--- a/packages/OsuLogin/res/values-es-rUS/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Registrarse en línea"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Se produjo un error de registro"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-es/strings.xml b/packages/OsuLogin/res/values-es/strings.xml
deleted file mode 100644
index 3ad95cd8cdc9..000000000000
--- a/packages/OsuLogin/res/values-es/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Registro online"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Error al completar el registro"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-et/strings.xml b/packages/OsuLogin/res/values-et/strings.xml
deleted file mode 100644
index 94c5cea646a5..000000000000
--- a/packages/OsuLogin/res/values-et/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Veebis registreerimine"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Registreerimine ebaõnnestus"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-eu/strings.xml b/packages/OsuLogin/res/values-eu/strings.xml
deleted file mode 100644
index 30caa8740a1d..000000000000
--- a/packages/OsuLogin/res/values-eu/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Sarean izen-ematea"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Ezin izan da eman izena"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-fa/strings.xml b/packages/OsuLogin/res/values-fa/strings.xml
deleted file mode 100644
index 300520336037..000000000000
--- a/packages/OsuLogin/res/values-fa/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"ثبت‌نام آنلاین"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"ثبت‌نام انجام نشد"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-fi/strings.xml b/packages/OsuLogin/res/values-fi/strings.xml
deleted file mode 100644
index 24eac8acc8d3..000000000000
--- a/packages/OsuLogin/res/values-fi/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Rekisteröidy verkossa"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Rekisteröityminen ei onnistunut"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-fr-rCA/strings.xml b/packages/OsuLogin/res/values-fr-rCA/strings.xml
deleted file mode 100644
index bcaa6621e803..000000000000
--- a/packages/OsuLogin/res/values-fr-rCA/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Inscription en ligne"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Échec de l\'inscription"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-fr/strings.xml b/packages/OsuLogin/res/values-fr/strings.xml
deleted file mode 100644
index bcaa6621e803..000000000000
--- a/packages/OsuLogin/res/values-fr/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Inscription en ligne"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Échec de l\'inscription"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-gl/strings.xml b/packages/OsuLogin/res/values-gl/strings.xml
deleted file mode 100644
index 5fc44440d01d..000000000000
--- a/packages/OsuLogin/res/values-gl/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Rexistro en liña"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Produciuse un erro co rexistro"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-gu/strings.xml b/packages/OsuLogin/res/values-gu/strings.xml
deleted file mode 100644
index 8449963b1705..000000000000
--- a/packages/OsuLogin/res/values-gu/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"ઑનલાઇન સાઇન અપ કરો"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"સાઇન અપ નિષ્ફળ"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-hi/strings.xml b/packages/OsuLogin/res/values-hi/strings.xml
deleted file mode 100644
index 9e07438047f0..000000000000
--- a/packages/OsuLogin/res/values-hi/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"ऑनलाइन साइन अप करें"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"साइन अप नहीं किया जा सका"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-hr/strings.xml b/packages/OsuLogin/res/values-hr/strings.xml
deleted file mode 100644
index e9b9751c95cf..000000000000
--- a/packages/OsuLogin/res/values-hr/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Online registracija"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Registracija nije uspjela"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-hu/strings.xml b/packages/OsuLogin/res/values-hu/strings.xml
deleted file mode 100644
index cb0e036fbbd3..000000000000
--- a/packages/OsuLogin/res/values-hu/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Online regisztráció"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"A regisztráció nem sikerült"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-hy/strings.xml b/packages/OsuLogin/res/values-hy/strings.xml
deleted file mode 100644
index ae1c36a0b341..000000000000
--- a/packages/OsuLogin/res/values-hy/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Առցանց գրանցում"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Չհաջողվեց գրանցվել"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-in/strings.xml b/packages/OsuLogin/res/values-in/strings.xml
deleted file mode 100644
index 6aaf6942c25a..000000000000
--- a/packages/OsuLogin/res/values-in/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Pendaftaran Online"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Pendaftaran gagal"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-is/strings.xml b/packages/OsuLogin/res/values-is/strings.xml
deleted file mode 100644
index f1ae520a63ee..000000000000
--- a/packages/OsuLogin/res/values-is/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Skráning á netinu"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Skráning mistókst"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-it/strings.xml b/packages/OsuLogin/res/values-it/strings.xml
deleted file mode 100644
index fbff7b0f4c75..000000000000
--- a/packages/OsuLogin/res/values-it/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Registrazione online"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Registrazione non riuscita"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-iw/strings.xml b/packages/OsuLogin/res/values-iw/strings.xml
deleted file mode 100644
index 866ef880759c..000000000000
--- a/packages/OsuLogin/res/values-iw/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"הרשמה אונליין"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"ההרשמה נכשלה"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-ja/strings.xml b/packages/OsuLogin/res/values-ja/strings.xml
deleted file mode 100644
index 8a220d605afb..000000000000
--- a/packages/OsuLogin/res/values-ja/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"オンライン登録"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"登録できませんでした"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-ka/strings.xml b/packages/OsuLogin/res/values-ka/strings.xml
deleted file mode 100644
index bf08006c47b3..000000000000
--- a/packages/OsuLogin/res/values-ka/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"ონლაინ რეგისტრაცია"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"რეგისტრაცია ვერ მოხერხდა"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-kk/strings.xml b/packages/OsuLogin/res/values-kk/strings.xml
deleted file mode 100644
index 8b87356ad547..000000000000
--- a/packages/OsuLogin/res/values-kk/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Онлайн тіркелу"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Тіркелмеді."</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-km/strings.xml b/packages/OsuLogin/res/values-km/strings.xml
deleted file mode 100644
index f58ccc330c5f..000000000000
--- a/packages/OsuLogin/res/values-km/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"ការចុះឈ្មោះ​លើអ៊ីនធឺណិត"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"ការចុះឈ្មោះ​មិនបានសម្រេច"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-kn/strings.xml b/packages/OsuLogin/res/values-kn/strings.xml
deleted file mode 100644
index 49a65627487e..000000000000
--- a/packages/OsuLogin/res/values-kn/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"ಆನ್‌ಲೈನ್ ಸೈನ್ ಅಪ್"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"ಸೈನ್ ಅಪ್ ವಿಫಲವಾಗಿದೆ"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-ko/strings.xml b/packages/OsuLogin/res/values-ko/strings.xml
deleted file mode 100644
index e647ca05f97a..000000000000
--- a/packages/OsuLogin/res/values-ko/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"온라인 가입"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"가입에 실패했습니다."</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-ky/strings.xml b/packages/OsuLogin/res/values-ky/strings.xml
deleted file mode 100644
index 42da248ac9e5..000000000000
--- a/packages/OsuLogin/res/values-ky/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Интернет аркылуу катталуу"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Катталган жоксуз"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-lo/strings.xml b/packages/OsuLogin/res/values-lo/strings.xml
deleted file mode 100644
index 9ff224170908..000000000000
--- a/packages/OsuLogin/res/values-lo/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"ສະໝັກອອນລາຍ"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"ສະໝັກບໍ່ສຳເລັດ"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-lt/strings.xml b/packages/OsuLogin/res/values-lt/strings.xml
deleted file mode 100644
index 1a4c06e87955..000000000000
--- a/packages/OsuLogin/res/values-lt/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Internetinis prisiregistravimas"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Nepavyko prisiregistruoti"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-lv/strings.xml b/packages/OsuLogin/res/values-lv/strings.xml
deleted file mode 100644
index 11cdb974440f..000000000000
--- a/packages/OsuLogin/res/values-lv/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Reģistrācija tiešsaistē"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Reģistrācija neizdevās."</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-mk/strings.xml b/packages/OsuLogin/res/values-mk/strings.xml
deleted file mode 100644
index de608e12cab7..000000000000
--- a/packages/OsuLogin/res/values-mk/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Онлајн регистрација"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Регистрацијата не успеа"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-ml/strings.xml b/packages/OsuLogin/res/values-ml/strings.xml
deleted file mode 100644
index 8e797c8e6e98..000000000000
--- a/packages/OsuLogin/res/values-ml/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"ഓൺലെെൻ സെെൻ അപ്പ്"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"സൈൻ അപ്പ് ചെയ്യാനായില്ല"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-mn/strings.xml b/packages/OsuLogin/res/values-mn/strings.xml
deleted file mode 100644
index 59d79d0c0a5d..000000000000
--- a/packages/OsuLogin/res/values-mn/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Онлайнаар бүртгүүлэх"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Бүртгүүлж чадсангүй"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-mr/strings.xml b/packages/OsuLogin/res/values-mr/strings.xml
deleted file mode 100644
index 15479a6e2735..000000000000
--- a/packages/OsuLogin/res/values-mr/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"ऑनलाइन साइन अप करा"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"साइन-अप करता आले नाही"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-ms/strings.xml b/packages/OsuLogin/res/values-ms/strings.xml
deleted file mode 100644
index 7e1cf9535319..000000000000
--- a/packages/OsuLogin/res/values-ms/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Pendaftaran Dalam Talian"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Pendaftaran gagal"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-my/strings.xml b/packages/OsuLogin/res/values-my/strings.xml
deleted file mode 100644
index 1bd992e8485b..000000000000
--- a/packages/OsuLogin/res/values-my/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"အွန်လိုင်း အကောင့်ဖွင့်ရန်"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"အကောင့်ဖွင့်၍ မရပါ"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-nb/strings.xml b/packages/OsuLogin/res/values-nb/strings.xml
deleted file mode 100644
index 2e0c47a18fca..000000000000
--- a/packages/OsuLogin/res/values-nb/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Registrering på nettet"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Registreringen mislyktes"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-ne/strings.xml b/packages/OsuLogin/res/values-ne/strings.xml
deleted file mode 100644
index 16bd92f57e23..000000000000
--- a/packages/OsuLogin/res/values-ne/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"अनलाइन साइन अप"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"साइन अप गर्न सकिएन"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-nl/strings.xml b/packages/OsuLogin/res/values-nl/strings.xml
deleted file mode 100644
index 7cf8bd2da1ac..000000000000
--- a/packages/OsuLogin/res/values-nl/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Online aanmelding"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Aanmelding mislukt"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-or/strings.xml b/packages/OsuLogin/res/values-or/strings.xml
deleted file mode 100644
index e0584d716d66..000000000000
--- a/packages/OsuLogin/res/values-or/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"ଅନଲାଇନ୍ ସାଇନ୍ ଅପ୍ କରନ୍ତୁ"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"ସାଇନ୍ ଅପ୍ ବିଫଳ ହୋଇଛି"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-pa/strings.xml b/packages/OsuLogin/res/values-pa/strings.xml
deleted file mode 100644
index 7e47d0e0960e..000000000000
--- a/packages/OsuLogin/res/values-pa/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"ਆਨਲਾਈਨ ਸਾਈਨ-ਅੱਪ ਕਰੋ"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"ਸਾਈਨ-ਅੱਪ ਕਰਨਾ ਅਸਫਲ ਰਿਹਾ"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-pl/strings.xml b/packages/OsuLogin/res/values-pl/strings.xml
deleted file mode 100644
index c0722ab6aaf6..000000000000
--- a/packages/OsuLogin/res/values-pl/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Rejestracja online"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Nie udało się zarejestrować"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-pt-rBR/strings.xml b/packages/OsuLogin/res/values-pt-rBR/strings.xml
deleted file mode 100644
index c9fe3772504d..000000000000
--- a/packages/OsuLogin/res/values-pt-rBR/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Inscrição on-line"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Falha na inscrição"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-pt-rPT/strings.xml b/packages/OsuLogin/res/values-pt-rPT/strings.xml
deleted file mode 100644
index 0059281416c8..000000000000
--- a/packages/OsuLogin/res/values-pt-rPT/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Inscrição online"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Falha na inscrição."</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-pt/strings.xml b/packages/OsuLogin/res/values-pt/strings.xml
deleted file mode 100644
index c9fe3772504d..000000000000
--- a/packages/OsuLogin/res/values-pt/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Inscrição on-line"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Falha na inscrição"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-ro/strings.xml b/packages/OsuLogin/res/values-ro/strings.xml
deleted file mode 100644
index eead127dd877..000000000000
--- a/packages/OsuLogin/res/values-ro/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Înscriere online"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Nu s-a înscris"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-ru/strings.xml b/packages/OsuLogin/res/values-ru/strings.xml
deleted file mode 100644
index a271ef7c00fc..000000000000
--- a/packages/OsuLogin/res/values-ru/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Регистрация в Интернете"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Не удалось зарегистрироваться."</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-si/strings.xml b/packages/OsuLogin/res/values-si/strings.xml
deleted file mode 100644
index 52e5979e7078..000000000000
--- a/packages/OsuLogin/res/values-si/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"සබැඳි ලියාපදිංචිය"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"ලියාපදිංචිය අසාර්ථක විය"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-sk/strings.xml b/packages/OsuLogin/res/values-sk/strings.xml
deleted file mode 100644
index f6b9f702d3b7..000000000000
--- a/packages/OsuLogin/res/values-sk/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Online registrácia"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Registrácia zlyhala"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-sl/strings.xml b/packages/OsuLogin/res/values-sl/strings.xml
deleted file mode 100644
index 6e6b95ce07f1..000000000000
--- a/packages/OsuLogin/res/values-sl/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Spletna registracija"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Registracija ni uspela"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-sq/strings.xml b/packages/OsuLogin/res/values-sq/strings.xml
deleted file mode 100644
index f67a2382bdac..000000000000
--- a/packages/OsuLogin/res/values-sq/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Regjistrimi në linjë"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Regjistrimi dështoi"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-sr/strings.xml b/packages/OsuLogin/res/values-sr/strings.xml
deleted file mode 100644
index 14e0828d5b83..000000000000
--- a/packages/OsuLogin/res/values-sr/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Онлајн регистрација"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Регистрација није успела"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-sv/strings.xml b/packages/OsuLogin/res/values-sv/strings.xml
deleted file mode 100644
index ea5fdfda7004..000000000000
--- a/packages/OsuLogin/res/values-sv/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Registrering online"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Registreringen misslyckades"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-sw/strings.xml b/packages/OsuLogin/res/values-sw/strings.xml
deleted file mode 100644
index c20a4023dda5..000000000000
--- a/packages/OsuLogin/res/values-sw/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Kujisajili Mtandaoni"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Imeshindwa kukusajili"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-ta/strings.xml b/packages/OsuLogin/res/values-ta/strings.xml
deleted file mode 100644
index e2eb567ef92e..000000000000
--- a/packages/OsuLogin/res/values-ta/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"ஆன்லைனில் பதிவு செய்"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"பதிவு செய்ய முடியவில்லை"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-te/strings.xml b/packages/OsuLogin/res/values-te/strings.xml
deleted file mode 100644
index 56b0b44d4802..000000000000
--- a/packages/OsuLogin/res/values-te/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"ఆన్‌లైన్ సైన్ అప్"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"సైన్-అప్ విఫలమయ్యింది"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-th/strings.xml b/packages/OsuLogin/res/values-th/strings.xml
deleted file mode 100644
index 552dca2c15e3..000000000000
--- a/packages/OsuLogin/res/values-th/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"การลงชื่อสมัครใช้ออนไลน์"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"ลงชื่อสมัครใช้ไม่สำเร็จ"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-tl/strings.xml b/packages/OsuLogin/res/values-tl/strings.xml
deleted file mode 100644
index ba89e9654213..000000000000
--- a/packages/OsuLogin/res/values-tl/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Pag-sign Up Online"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Hindi nakapag-sign up"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-tr/strings.xml b/packages/OsuLogin/res/values-tr/strings.xml
deleted file mode 100644
index 1d927fef4d16..000000000000
--- a/packages/OsuLogin/res/values-tr/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Online Kaydolma"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Kaydolma işlemi başarısız oldu"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-uk/strings.xml b/packages/OsuLogin/res/values-uk/strings.xml
deleted file mode 100644
index 6e60ff008c0f..000000000000
--- a/packages/OsuLogin/res/values-uk/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Онлайн-реєстрація"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Не вдалося зареєструватись"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-ur/strings.xml b/packages/OsuLogin/res/values-ur/strings.xml
deleted file mode 100644
index eed7686c4fe9..000000000000
--- a/packages/OsuLogin/res/values-ur/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"آن لائن سائن اپ کریں"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"سائن اپ ناکام ہو گیا"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-uz/strings.xml b/packages/OsuLogin/res/values-uz/strings.xml
deleted file mode 100644
index 152d129fe05a..000000000000
--- a/packages/OsuLogin/res/values-uz/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Onlayn registratsiya"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Registratsiya qilinmadi"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-vi/strings.xml b/packages/OsuLogin/res/values-vi/strings.xml
deleted file mode 100644
index 845580760965..000000000000
--- a/packages/OsuLogin/res/values-vi/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Đăng ký trực tuyến"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Không đăng ký được"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-zh-rCN/strings.xml b/packages/OsuLogin/res/values-zh-rCN/strings.xml
deleted file mode 100644
index 7f13647bfccd..000000000000
--- a/packages/OsuLogin/res/values-zh-rCN/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"在线注册"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"注册失败"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-zh-rHK/strings.xml b/packages/OsuLogin/res/values-zh-rHK/strings.xml
deleted file mode 100644
index 873179189b24..000000000000
--- a/packages/OsuLogin/res/values-zh-rHK/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"網上申請"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"無法申請"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-zh-rTW/strings.xml b/packages/OsuLogin/res/values-zh-rTW/strings.xml
deleted file mode 100644
index 79208c8d7387..000000000000
--- a/packages/OsuLogin/res/values-zh-rTW/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"線上註冊"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"註冊失敗"</string>
-</resources>
diff --git a/packages/OsuLogin/res/values-zu/strings.xml b/packages/OsuLogin/res/values-zu/strings.xml
deleted file mode 100644
index 27ac6bb755f9..000000000000
--- a/packages/OsuLogin/res/values-zu/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="8288271429327488421">"I-OsuLogin"</string>
- <string name="action_bar_label" msgid="550995560341508693">"Ukubhalisa Okuku-inthanethi"</string>
- <string name="sign_up_failed" msgid="837216244603867568">"Ukubhalisa kuhlulekile"</string>
-</resources>
diff --git a/packages/PrintSpooler/res/values-ca/strings.xml b/packages/PrintSpooler/res/values-ca/strings.xml
index 98687b40af16..a346cb2c1b2d 100644
--- a/packages/PrintSpooler/res/values-ca/strings.xml
+++ b/packages/PrintSpooler/res/values-ca/strings.xml
@@ -16,7 +16,7 @@
<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">"Gest. cues impr."</string>
+ <string name="app_label" msgid="4469836075319831821">"Gestor de cues d\'impressió"</string>
<string name="more_options_button" msgid="2243228396432556771">"Més opcions"</string>
<string name="label_destination" msgid="9132510997381599275">"Destinació"</string>
<string name="label_copies" msgid="3634531042822968308">"Còpies"</string>
diff --git a/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveOutlineDrawable.java b/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveOutlineDrawable.java
index 3bf43dd4d1bf..3565b0e3a9ae 100644
--- a/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveOutlineDrawable.java
+++ b/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveOutlineDrawable.java
@@ -30,9 +30,7 @@ import android.graphics.Rect;
import android.graphics.drawable.AdaptiveIconDrawable;
import android.graphics.drawable.DrawableWrapper;
import android.os.RemoteException;
-import android.util.DisplayMetrics;
import android.util.PathParser;
-import android.view.Display;
import android.view.IWindowManager;
import android.view.WindowManagerGlobal;
@@ -47,6 +45,9 @@ import java.lang.annotation.RetentionPolicy;
*/
public class AdaptiveOutlineDrawable extends DrawableWrapper {
+ private static final float ADVANCED_ICON_CENTER = 50f;
+ private static final float ADVANCED_ICON_RADIUS = 48f;
+
@Retention(RetentionPolicy.SOURCE)
@IntDef({TYPE_DEFAULT, TYPE_ADVANCED})
public @interface AdaptiveOutlineIconType {
@@ -61,7 +62,6 @@ public class AdaptiveOutlineDrawable extends DrawableWrapper {
private int mStrokeWidth;
private Bitmap mBitmap;
private int mType;
- private float mDensity;
public AdaptiveOutlineDrawable(Resources resources, Bitmap bitmap) {
super(new AdaptiveIconShapeDrawable(resources));
@@ -83,7 +83,6 @@ public class AdaptiveOutlineDrawable extends DrawableWrapper {
mPath = new Path(PathParser.createPathFromPathData(
resources.getString(com.android.internal.R.string.config_icon_mask)));
mStrokeWidth = resources.getDimensionPixelSize(R.dimen.adaptive_outline_stroke);
- mDensity = resources.getDisplayMetrics().density;
mOutlinePaint = new Paint();
mOutlinePaint.setColor(getColor(resources, type));
mOutlinePaint.setStyle(Paint.Style.STROKE);
@@ -137,12 +136,7 @@ public class AdaptiveOutlineDrawable extends DrawableWrapper {
if (mType == TYPE_DEFAULT) {
canvas.drawPath(mPath, mOutlinePaint);
} else {
- final float defaultDensity = getDefaultDisplayDensity(Display.DEFAULT_DISPLAY)
- / (float) DisplayMetrics.DENSITY_DEFAULT;
- final int insetPx =
- Math.round(mInsetPx / (float) (Math.floor(
- (mDensity / defaultDensity) * 100) / 100.0));
- canvas.drawCircle(2 * insetPx, 2 * insetPx, 2 * insetPx - mStrokeWidth,
+ canvas.drawCircle(ADVANCED_ICON_CENTER, ADVANCED_ICON_CENTER, ADVANCED_ICON_RADIUS,
mOutlinePaint);
}
canvas.restoreToCount(count);
diff --git a/packages/SettingsLib/HelpUtils/res/values-en-rCA/strings.xml b/packages/SettingsLib/HelpUtils/res/values-en-rCA/strings.xml
index 759da1d0b021..150020cb17c5 100644
--- a/packages/SettingsLib/HelpUtils/res/values-en-rCA/strings.xml
+++ b/packages/SettingsLib/HelpUtils/res/values-en-rCA/strings.xml
@@ -17,5 +17,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="help_feedback_label" msgid="7106780063063027882">"Help &amp; feedback"</string>
+ <string name="help_feedback_label" msgid="7106780063063027882">"Help and feedback"</string>
</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-in/strings.xml b/packages/SettingsLib/SearchWidget/res/values-in/strings.xml
index edf51cc601ac..ccf11d26273c 100644
--- a/packages/SettingsLib/SearchWidget/res/values-in/strings.xml
+++ b/packages/SettingsLib/SearchWidget/res/values-in/strings.xml
@@ -17,5 +17,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="search_menu" msgid="1914043873178389845">"Setelan penelusuran"</string>
+ <string name="search_menu" msgid="1914043873178389845">"Telusuri setelan"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index e17c0f015ff8..39777cd5f881 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -47,7 +47,7 @@
<string name="wifi_limited_connection" msgid="1184778285475204682">"اتصال محدود"</string>
<string name="wifi_status_no_internet" msgid="3799933875988829048">"لا يتوفر اتصال إنترنت."</string>
<string name="wifi_status_sign_in_required" msgid="2236267500459526855">"يلزم تسجيل الدخول"</string>
- <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"نقطة الدخول ممتلئة مؤقتًا"</string>
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"نقطة الوصول ممتلئة مؤقتًا"</string>
<string name="connected_via_carrier" msgid="1968057009076191514">"‏تم الاتصال عبر %1$s"</string>
<string name="available_via_carrier" msgid="465598683092718294">"‏متوفرة عبر %1$s"</string>
<string name="osu_opening_provider" msgid="4318105381295178285">"فتح <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
@@ -125,7 +125,7 @@
<string name="bluetooth_talkback_phone" msgid="868393783858123880">"هاتف"</string>
<string name="bluetooth_talkback_imaging" msgid="8781682986822514331">"تصوير"</string>
<string name="bluetooth_talkback_headphone" msgid="8613073829180337091">"السمّاعة"</string>
- <string name="bluetooth_talkback_input_peripheral" msgid="5133944817800149942">"جهاز إدخال طرفي"</string>
+ <string name="bluetooth_talkback_input_peripheral" msgid="5133944817800149942">"جهاز إدخال ملحق"</string>
<string name="bluetooth_talkback_bluetooth" msgid="1143241359781999989">"بلوتوث"</string>
<string name="bluetooth_hearingaid_left_pairing_message" msgid="8561855779703533591">"جارٍ إقران سماعة الأذن الطبية اليسرى…"</string>
<string name="bluetooth_hearingaid_right_pairing_message" msgid="2655347721696331048">"جارٍ إقران سماعة الأذن الطبية اليمنى…"</string>
@@ -348,7 +348,7 @@
<string name="simulate_color_space" msgid="1206503300335835151">"محاكاة مسافة اللون"</string>
<string name="enable_opengl_traces_title" msgid="4638773318659125196">"‏تفعيل عمليات تتبع OpenGL"</string>
<string name="usb_audio_disable_routing" msgid="3367656923544254975">"‏إيقاف توجيه الصوت عبر USB"</string>
- <string name="usb_audio_disable_routing_summary" msgid="8768242894849534699">"‏إيقاف التوجيه التلقائي إلى أجهزة الصوت الطرفية عبر USB"</string>
+ <string name="usb_audio_disable_routing_summary" msgid="8768242894849534699">"‏إيقاف التوجيه التلقائي إلى أجهزة الصوت الملحقة عبر USB"</string>
<string name="debug_layout" msgid="1659216803043339741">"عرض حدود المخطط"</string>
<string name="debug_layout_summary" msgid="8825829038287321978">"عرض حدود وهوامش المقطع وما إلى ذلك"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"فرض اتجاه التنسيق ليكون من اليمين إلى اليسار"</string>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index 50f0b76b6448..f26fe9d58533 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -203,9 +203,9 @@
<string name="vpn_settings_not_available" msgid="2894137119965668920">"VPN postavke nisu dostupne za ovog korisnika"</string>
<string name="tethering_settings_not_available" msgid="266821736434699780">"Postavke za povezivanje putem mobitela nisu dostupne za ovog korisnika"</string>
<string name="apn_settings_not_available" msgid="1147111671403342300">"Postavke za ime pristupne tačke nisu dostupne za ovog korisnika"</string>
- <string name="enable_adb" msgid="8072776357237289039">"Otklanjanje grešaka putem uređaja spojenog na USB"</string>
+ <string name="enable_adb" msgid="8072776357237289039">"Otklanjanje grešaka putem USB-a"</string>
<string name="enable_adb_summary" msgid="3711526030096574316">"Način rada za uklanjanje grešaka kada je povezan USB"</string>
- <string name="clear_adb_keys" msgid="3010148733140369917">"Ukini odobrenja otklanjanja grešaka putem uređaja spojenog na USB"</string>
+ <string name="clear_adb_keys" msgid="3010148733140369917">"Ukini odobrenja otklanjanja grešaka putem USB-a"</string>
<string name="enable_adb_wireless" msgid="6973226350963971018">"Bežično otklanjanje grešaka"</string>
<string name="enable_adb_wireless_summary" msgid="7344391423657093011">"Način rada otklanjanja grešaka kada je WiFi mreža povezana"</string>
<string name="adb_wireless_error" msgid="721958772149779856">"Greška"</string>
@@ -300,11 +300,11 @@
<string name="debug_view_attributes" msgid="3539609843984208216">"Omogući pregled atributa prikaza"</string>
<string name="mobile_data_always_on_summary" msgid="1112156365594371019">"Prijenos podataka na mobilnoj mreži ostaje aktivan čak i kada je aktiviran WiFi (za brzo prebacivanje između mreža)."</string>
<string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"Korištenje hardverskog ubrzavanja za povezivanje putem mobitela ako je dostupno"</string>
- <string name="adb_warning_title" msgid="7708653449506485728">"Omogućiti otklanjanje grešaka putem uređaja spojenog na USB?"</string>
- <string name="adb_warning_message" msgid="8145270656419669221">"Otklanjanje grešaka putem uređaja spojenog na USB je namijenjeno samo u svrhe razvoja aplikacija. Koristite ga za kopiranje podataka između računara i uređaja, instaliranje aplikacija na uređaj bez obavještenja te čitanje podataka iz zapisnika."</string>
+ <string name="adb_warning_title" msgid="7708653449506485728">"Omogućiti otklanjanje grešaka putem USB-a?"</string>
+ <string name="adb_warning_message" msgid="8145270656419669221">"Otklanjanje grešaka putem USB-a je namijenjeno samo u svrhe razvoja aplikacija. Koristite ga za kopiranje podataka između računara i uređaja, instaliranje aplikacija na uređaj bez obavještenja te čitanje podataka iz zapisnika."</string>
<string name="adbwifi_warning_title" msgid="727104571653031865">"Omogućiti bežično otklanjanje grešaka?"</string>
<string name="adbwifi_warning_message" msgid="8005936574322702388">"Bežično otklanjanje grešaka je namijenjeno samo u svrhe razvoja aplikacija. Koristite ga za kopiranje podataka između računara i uređaja, instaliranje aplikacija na uređaj bez obavještenja te čitanje podataka iz zapisnika."</string>
- <string name="adb_keys_warning_message" msgid="2968555274488101220">"Opozvati pristup otklanjanju grešaka putem uređaja spojenog na USB za sve računare koje ste prethodno ovlastili?"</string>
+ <string name="adb_keys_warning_message" msgid="2968555274488101220">"Opozvati pristup otklanjanju grešaka putem USB-a za sve računare koje ste prethodno ovlastili?"</string>
<string name="dev_settings_warning_title" msgid="8251234890169074553">"Dopustiti postavke za razvoj?"</string>
<string name="dev_settings_warning_message" msgid="37741686486073668">"Ove postavke su namijenjene samo za svrhe razvoja. Mogu izazvati pogrešno ponašanje uređaja i aplikacija na njemu."</string>
<string name="verify_apps_over_usb_title" msgid="6031809675604442636">"Potvrdi aplikacije putem USB-a"</string>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index 0def17e1c21a..cc3b2aa33695 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -90,7 +90,7 @@
<string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Use for contact sharing"</string>
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Internet connection sharing"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"Text messages"</string>
- <string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM Access"</string>
+ <string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM access"</string>
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD audio"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Hearing Aids"</string>
diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml
index 0def17e1c21a..a9f039a6522c 100644
--- a/packages/SettingsLib/res/values-en-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-en-rCA/strings.xml
@@ -90,7 +90,7 @@
<string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Use for contact sharing"</string>
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Internet connection sharing"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"Text messages"</string>
- <string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM Access"</string>
+ <string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM access"</string>
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD audio"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Hearing Aids"</string>
@@ -147,14 +147,14 @@
<string name="tether_settings_title_wifi" msgid="4803402057533895526">"Portable hotspot"</string>
<string name="tether_settings_title_bluetooth" msgid="916519902721399656">"Bluetooth tethering"</string>
<string name="tether_settings_title_usb_bluetooth" msgid="1727111807207577322">"Tethering"</string>
- <string name="tether_settings_title_all" msgid="8910259483383010470">"Tethering &amp; portable hotspot"</string>
+ <string name="tether_settings_title_all" msgid="8910259483383010470">"Tethering and portable hotspot"</string>
<string name="managed_user_title" msgid="449081789742645723">"All work apps"</string>
<string name="user_guest" msgid="6939192779649870792">"Guest"</string>
<string name="unknown" msgid="3544487229740637809">"Unknown"</string>
<string name="running_process_item_user_label" msgid="3988506293099805796">"User: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
<string name="launch_defaults_some" msgid="3631650616557252926">"Some defaults set"</string>
<string name="launch_defaults_none" msgid="8049374306261262709">"No defaults set"</string>
- <string name="tts_settings" msgid="8130616705989351312">"Text-to-Speech settings"</string>
+ <string name="tts_settings" msgid="8130616705989351312">"Text-to-speech settings"</string>
<string name="tts_settings_title" msgid="7602210956640483039">"Text-to-speech output"</string>
<string name="tts_default_rate_title" msgid="3964187817364304022">"Speech rate"</string>
<string name="tts_default_rate_summary" msgid="3781937042151716987">"Speed at which the text is spoken"</string>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index 0def17e1c21a..cc3b2aa33695 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -90,7 +90,7 @@
<string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Use for contact sharing"</string>
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Internet connection sharing"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"Text messages"</string>
- <string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM Access"</string>
+ <string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM access"</string>
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD audio"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Hearing Aids"</string>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index 0def17e1c21a..cc3b2aa33695 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -90,7 +90,7 @@
<string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Use for contact sharing"</string>
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Internet connection sharing"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"Text messages"</string>
- <string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM Access"</string>
+ <string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM access"</string>
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD audio"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Hearing Aids"</string>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index 33e6659d633b..3945e5542eb7 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -545,7 +545,7 @@
<string name="profile_info_settings_title" msgid="105699672534365099">"Profiilin tiedot"</string>
<string name="user_need_lock_message" msgid="4311424336209509301">"Ennen kuin voit luoda rajoitetun profiilin, määritä näytön lukitus, joka suojelee sovelluksiasi ja henkilökohtaisia tietojasi."</string>
<string name="user_set_lock_button" msgid="1427128184982594856">"Aseta lukitus"</string>
- <string name="user_switch_to_user" msgid="6975428297154968543">"Vaihda tähän: <xliff:g id="USER_NAME">%s</xliff:g>"</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="guest_new_guest" msgid="3482026122932643557">"Lisää vieras"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Poista vieras"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Vieras"</string>
diff --git a/packages/SettingsLib/res/values-ja/arrays.xml b/packages/SettingsLib/res/values-ja/arrays.xml
index 2966f09c6c1b..d166c179757c 100644
--- a/packages/SettingsLib/res/values-ja/arrays.xml
+++ b/packages/SettingsLib/res/values-ja/arrays.xml
@@ -40,7 +40,7 @@
<item msgid="8339720953594087771">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g>に接続中..."</item>
<item msgid="3028983857109369308">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g>による認証中..."</item>
<item msgid="4287401332778341890">"IPアドレスを<xliff:g id="NETWORK_NAME">%1$s</xliff:g>から取得中..."</item>
- <item msgid="1043944043827424501">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g>に接続しました"</item>
+ <item msgid="1043944043827424501">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> に接続済み"</item>
<item msgid="7445993821842009653">"保留中"</item>
<item msgid="1175040558087735707">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g>から切断中..."</item>
<item msgid="699832486578171722">"切断されました"</item>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index 1ee06b8353c9..279aca0731f7 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -545,7 +545,7 @@
<string name="profile_info_settings_title" msgid="105699672534365099">"Профильдік ақпарат"</string>
<string name="user_need_lock_message" msgid="4311424336209509301">"Шектелген профайл жасақтауға дейін қолданбалар мен жеке деректерді қорғау үшін экран бекітпесін тағайындау қажет."</string>
<string name="user_set_lock_button" msgid="1427128184982594856">"Бекітпе тағайындау"</string>
- <string name="user_switch_to_user" msgid="6975428297154968543">"<xliff:g id="USER_NAME">%s</xliff:g> атты пайдаланушыға ауысу"</string>
+ <string name="user_switch_to_user" msgid="6975428297154968543">"<xliff:g id="USER_NAME">%s</xliff:g> пайдаланушысына ауысу"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Қонақты енгізу"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Қонақты өшіру"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Қонақ"</string>
diff --git a/packages/SettingsLib/res/values-ne/arrays.xml b/packages/SettingsLib/res/values-ne/arrays.xml
index 2895a02cbae4..fb002c2c2f03 100644
--- a/packages/SettingsLib/res/values-ne/arrays.xml
+++ b/packages/SettingsLib/res/values-ne/arrays.xml
@@ -238,7 +238,7 @@
</string-array>
<string-array name="show_non_rect_clip_entries">
<item msgid="2482978351289846212">"बन्द"</item>
- <item msgid="3405519300199774027">"गैर आयातकार क्षेत्र नीलो रङमा कोर्नुहोस्"</item>
+ <item msgid="3405519300199774027">"गैर आयातकार क्षेत्र निलो रङमा कोर्नुहोस्"</item>
<item msgid="1212561935004167943">"हाइलाइट परीक्षण चित्र कोर्ने आदेशहरू हरियोमा"</item>
</string-array>
<string-array name="track_frame_time_entries">
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index f43387955711..663d3f702ae5 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -546,7 +546,7 @@
<string name="profile_info_settings_title" msgid="105699672534365099">"Informații de profil"</string>
<string name="user_need_lock_message" msgid="4311424336209509301">"Înainte de a putea crea un profil cu permisiuni limitate, va trebui să configurați blocarea ecranului pentru a vă proteja aplicațiile și datele personale."</string>
<string name="user_set_lock_button" msgid="1427128184982594856">"Configurați blocarea"</string>
- <string name="user_switch_to_user" msgid="6975428297154968543">"Comutați la <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="user_switch_to_user" msgid="6975428297154968543">"Treceți la <xliff:g id="USER_NAME">%s</xliff:g>"</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>
<string name="guest_nickname" msgid="6332276931583337261">"Invitat"</string>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index 05cfeb67f86a..b7fbe6fad392 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -545,7 +545,7 @@
<string name="profile_info_settings_title" msgid="105699672534365099">"پروفائل کی معلومات"</string>
<string name="user_need_lock_message" msgid="4311424336209509301">"ایک محدود پروفائل بنانے سے پہلے، آپ کو اپنی ایپس اور ذاتی ڈیٹا کو محفوظ کرنے کیلئے ایک اسکرین لاک سیٹ اپ کرنا ہوگا۔"</string>
<string name="user_set_lock_button" msgid="1427128184982594856">"لاک سیٹ کریں"</string>
- <string name="user_switch_to_user" msgid="6975428297154968543">"<xliff:g id="USER_NAME">%s</xliff:g> پر سوئچ کریں"</string>
+ <string name="user_switch_to_user" msgid="6975428297154968543">"‫<xliff:g id="USER_NAME">%s</xliff:g> پر سوئچ کریں"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"مہمان کو شامل کریں"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"مہمان کو ہٹائیں"</string>
<string name="guest_nickname" msgid="6332276931583337261">"مہمان"</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/TetherUtil.java b/packages/SettingsLib/src/com/android/settingslib/TetherUtil.java
index c3993e9063b2..dc9384aa7c5d 100644
--- a/packages/SettingsLib/src/com/android/settingslib/TetherUtil.java
+++ b/packages/SettingsLib/src/com/android/settingslib/TetherUtil.java
@@ -19,42 +19,9 @@ import static android.os.UserManager.DISALLOW_CONFIG_TETHERING;
import android.content.Context;
import android.net.ConnectivityManager;
-import android.os.SystemProperties;
import android.os.UserHandle;
-import android.telephony.CarrierConfigManager;
-
-import androidx.annotation.VisibleForTesting;
public class TetherUtil {
-
- @VisibleForTesting
- static boolean isEntitlementCheckRequired(Context context) {
- final CarrierConfigManager configManager = (CarrierConfigManager) context
- .getSystemService(Context.CARRIER_CONFIG_SERVICE);
- if (configManager == null || configManager.getConfig() == null) {
- // return service default
- return true;
- }
- return configManager.getConfig().getBoolean(CarrierConfigManager
- .KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL);
- }
-
- public static boolean isProvisioningNeeded(Context context) {
- // Keep in sync with other usage of config_mobile_hotspot_provision_app.
- // ConnectivityManager#enforceTetherChangePermission
- String[] provisionApp = context.getResources().getStringArray(
- com.android.internal.R.array.config_mobile_hotspot_provision_app);
- if (SystemProperties.getBoolean("net.tethering.noprovisioning", false)
- || provisionApp == null) {
- return false;
- }
- // Check carrier config for entitlement checks
- if (isEntitlementCheckRequired(context) == false) {
- return false;
- }
- return (provisionApp.length == 2);
- }
-
public static boolean isTetherAvailable(Context context) {
final ConnectivityManager cm = context.getSystemService(ConnectivityManager.class);
final boolean tetherConfigDisallowed = RestrictedLockUtilsInternal
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/TetherUtilTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/TetherUtilTest.java
index 0ca779162ef2..df08809b5601 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/TetherUtilTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/TetherUtilTest.java
@@ -60,13 +60,6 @@ public class TetherUtilTest {
}
@Test
- public void isEntitlementCheckRequired_noConfigManager_returnTrue() {
- doReturn(null).when(mContext).getSystemService(Context.CARRIER_CONFIG_SERVICE);
-
- assertThat(TetherUtil.isEntitlementCheckRequired(mContext)).isTrue();
- }
-
- @Test
public void isTetherAvailable_supported_configDisallowed_hasUserRestriction_returnTrue() {
setupIsTetherAvailable(true, true, true);
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/ApplicationsStateRoboTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/ApplicationsStateRoboTest.java
index 95a4f69b287c..5efce4da970f 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/ApplicationsStateRoboTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/ApplicationsStateRoboTest.java
@@ -341,7 +341,6 @@ public class ApplicationsStateRoboTest {
assertThat(appEntries.size()).isEqualTo(1);
AppEntry launchableEntry = findAppEntry(appEntries, 1);
- assertThat(launchableEntry.icon).isNull();
assertThat(launchableEntry.hasLauncherEntry).isFalse();
assertThat(launchableEntry.size).isGreaterThan(0L);
}
@@ -360,7 +359,6 @@ public class ApplicationsStateRoboTest {
assertThat(appEntries.size()).isEqualTo(1);
AppEntry launchableEntry = findAppEntry(appEntries, 1);
- assertThat(launchableEntry.icon).isNull();
assertThat(launchableEntry.hasLauncherEntry).isFalse();
assertThat(launchableEntry.size).isEqualTo(-1);
assertThat(launchableEntry.isHomeApp).isTrue();
@@ -380,7 +378,6 @@ public class ApplicationsStateRoboTest {
assertThat(appEntries.size()).isEqualTo(1);
AppEntry launchableEntry = findAppEntry(appEntries, 1);
- assertThat(launchableEntry.icon).isNull();
assertThat(launchableEntry.size).isEqualTo(-1);
assertThat(launchableEntry.isHomeApp).isFalse();
assertThat(launchableEntry.hasLauncherEntry).isTrue();
diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml
index c9e1944bd6f2..51f69a95e163 100644
--- a/packages/SettingsProvider/res/values/defaults.xml
+++ b/packages/SettingsProvider/res/values/defaults.xml
@@ -237,4 +237,7 @@
<!-- Default for Settings.Secure.AWARE_LOCK_ENABLED -->
<bool name="def_aware_lock_enabled">false</bool>
+
+ <!-- Default for setting for Settings.Global.HDMI_CONTROL_AUTO_DEVICE_OFF_ENABLED -->
+ <bool name="def_hdmiControlAutoDeviceOff">false</bool>
</resources>
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
index c04a1ba689b9..d05e6e16bc1a 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
@@ -164,7 +164,8 @@ public class SecureSettings {
Settings.Secure.AWARE_TAP_PAUSE_GESTURE_COUNT,
Settings.Secure.AWARE_TAP_PAUSE_TOUCH_COUNT,
Settings.Secure.PEOPLE_STRIP,
+ Settings.Secure.MEDIA_CONTROLS_RESUME,
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE,
- Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS,
+ Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS
};
}
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
index 76746e5488b6..fa810bdf3a4e 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
@@ -243,6 +243,7 @@ public class SecureSettingsValidators {
VALIDATORS.put(Secure.DISPLAY_DENSITY_FORCED, NON_NEGATIVE_INTEGER_VALIDATOR);
VALIDATORS.put(Secure.TAP_GESTURE, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.PEOPLE_STRIP, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.MEDIA_CONTROLS_RESUME, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.ACCESSIBILITY_MAGNIFICATION_MODE,
new InclusiveIntegerRangeValidator(
Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN,
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
index 75b680dd3a88..bec8151a1351 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
@@ -219,7 +219,9 @@ public class SettingsHelper {
*/
@VisibleForTesting
public String getRealValueForSystemSetting(String setting) {
- return Settings.System.getString(mContext.getContentResolver(),
+ // The real value irrespectively of the original setting's namespace is stored in
+ // Settings.Secure.
+ return Settings.Secure.getString(mContext.getContentResolver(),
setting + SETTING_ORIGINAL_KEY_SUFFIX);
}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 94509ddcc407..b95d34f2966b 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -3513,7 +3513,7 @@ public class SettingsProvider extends ContentProvider {
}
private final class UpgradeController {
- private static final int SETTINGS_VERSION = 190;
+ private static final int SETTINGS_VERSION = 191;
private final int mUserId;
@@ -4867,6 +4867,21 @@ public class SettingsProvider extends ContentProvider {
currentVersion = 190;
}
+ if (currentVersion == 190) {
+ // Version 190: get HDMI auto device off from overlay
+ final SettingsState globalSettings = getGlobalSettingsLocked();
+ final Setting currentSetting = globalSettings.getSettingLocked(
+ Global.HDMI_CONTROL_AUTO_DEVICE_OFF_ENABLED);
+ if (currentSetting.isNull()) {
+ globalSettings.insertSettingLocked(
+ Global.HDMI_CONTROL_AUTO_DEVICE_OFF_ENABLED,
+ getContext().getResources().getBoolean(
+ R.bool.def_hdmiControlAutoDeviceOff) ? "1" : "0",
+ null, true, SettingsState.SYSTEM_PACKAGE_NAME);
+ }
+ currentVersion = 191;
+ }
+
// vXXX: Add new settings above this point.
if (currentVersion != newVersion) {
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 4e17062fc52c..b64a9e7a25bf 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -39,6 +39,8 @@
<uses-permission android:name="android.permission.WRITE_USER_DICTIONARY" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+ <!-- ACCESS_BACKGROUND_LOCATION is needed for testing purposes only. -->
+ <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
diff --git a/packages/SoundPicker/AndroidManifest.xml b/packages/SoundPicker/AndroidManifest.xml
index 9d0818230a02..73d99a55efdd 100644
--- a/packages/SoundPicker/AndroidManifest.xml
+++ b/packages/SoundPicker/AndroidManifest.xml
@@ -11,6 +11,7 @@
<application
android:allowBackup="false"
+ android:label="@string/app_label"
android:supportsRtl="true">
<receiver android:name="RingtoneReceiver">
<intent-filter>
diff --git a/packages/SoundPicker/res/values-af/strings.xml b/packages/SoundPicker/res/values-af/strings.xml
index 10110f6bf351..fd857b1c3cc4 100644
--- a/packages/SoundPicker/res/values-af/strings.xml
+++ b/packages/SoundPicker/res/values-af/strings.xml
@@ -25,4 +25,5 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"Vee uit"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"Kan nie gepasmaakte luitoon byvoeg nie"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Kan nie gepasmaakte luitoon uitvee nie"</string>
+ <string name="app_label" msgid="3091611356093417332">"Klanke"</string>
</resources>
diff --git a/packages/SoundPicker/res/values-am/strings.xml b/packages/SoundPicker/res/values-am/strings.xml
index 57f789792547..953aaa74cf83 100644
--- a/packages/SoundPicker/res/values-am/strings.xml
+++ b/packages/SoundPicker/res/values-am/strings.xml
@@ -25,4 +25,6 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"ሰርዝ"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"ብጁ የጥሪ ቅላጼን ማከል አልተቻለም"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"ብጁ የጥሪ ቅላጼን መሰረዝ አልተቻለም"</string>
+ <!-- no translation found for app_label (3091611356093417332) -->
+ <skip />
</resources>
diff --git a/packages/SoundPicker/res/values-ar/strings.xml b/packages/SoundPicker/res/values-ar/strings.xml
index 57740ef69a70..6110097240f0 100644
--- a/packages/SoundPicker/res/values-ar/strings.xml
+++ b/packages/SoundPicker/res/values-ar/strings.xml
@@ -25,4 +25,6 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"حذف"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"يتعذر إضافة نغمة رنين مخصصة"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"يتعذر حذف نغمة الرنين المخصصة"</string>
+ <!-- no translation found for app_label (3091611356093417332) -->
+ <skip />
</resources>
diff --git a/packages/SoundPicker/res/values-as/strings.xml b/packages/SoundPicker/res/values-as/strings.xml
index 659f2d5f7e16..8bd1f9871ac7 100644
--- a/packages/SoundPicker/res/values-as/strings.xml
+++ b/packages/SoundPicker/res/values-as/strings.xml
@@ -25,4 +25,6 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"মচক"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"নিজৰ উপযোগিতা অনুযায়ী তৈয়াৰ কৰা ৰিংট\'ন যোগ কৰিব পৰা নগ\'ল"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"নিজৰ উপযোগিতা অনুযায়ী তৈয়াৰ কৰা ৰিংট\'ন মচিব পৰা নগ\'ল"</string>
+ <!-- no translation found for app_label (3091611356093417332) -->
+ <skip />
</resources>
diff --git a/packages/SoundPicker/res/values-az/strings.xml b/packages/SoundPicker/res/values-az/strings.xml
index 93f4d7981a0a..20a268071b5a 100644
--- a/packages/SoundPicker/res/values-az/strings.xml
+++ b/packages/SoundPicker/res/values-az/strings.xml
@@ -25,4 +25,6 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"Silin"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"Fərdi zəng səsi əlavə etmək mümkün deyil"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Fərdi zəng səsini silmək mümkün deyil"</string>
+ <!-- no translation found for app_label (3091611356093417332) -->
+ <skip />
</resources>
diff --git a/packages/SoundPicker/res/values-b+sr+Latn/strings.xml b/packages/SoundPicker/res/values-b+sr+Latn/strings.xml
index ba8e87fe0a67..947c85c8ad91 100644
--- a/packages/SoundPicker/res/values-b+sr+Latn/strings.xml
+++ b/packages/SoundPicker/res/values-b+sr+Latn/strings.xml
@@ -25,4 +25,5 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"Izbriši"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"Dodavanje prilagođene melodije zvona nije uspelo"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Brisanje prilagođene melodije zvona nije uspelo"</string>
+ <string name="app_label" msgid="3091611356093417332">"Zvukovi"</string>
</resources>
diff --git a/packages/SoundPicker/res/values-be/strings.xml b/packages/SoundPicker/res/values-be/strings.xml
index 81b99877def6..593a68f7491f 100644
--- a/packages/SoundPicker/res/values-be/strings.xml
+++ b/packages/SoundPicker/res/values-be/strings.xml
@@ -25,4 +25,6 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"Выдаліць"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"Немагчыма дадаць карыстальніцкі рынгтон"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Немагчыма выдаліць карыстальніцкі рынгтон"</string>
+ <!-- no translation found for app_label (3091611356093417332) -->
+ <skip />
</resources>
diff --git a/packages/SoundPicker/res/values-bg/strings.xml b/packages/SoundPicker/res/values-bg/strings.xml
index e1cd2a697bf0..4277d2851e8c 100644
--- a/packages/SoundPicker/res/values-bg/strings.xml
+++ b/packages/SoundPicker/res/values-bg/strings.xml
@@ -25,4 +25,5 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"Изтриване"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"Персонализираната мелодия не може да се добави"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Персонализираната мелодия не може да се изтрие"</string>
+ <string name="app_label" msgid="3091611356093417332">"Sounds"</string>
</resources>
diff --git a/packages/SoundPicker/res/values-bn/strings.xml b/packages/SoundPicker/res/values-bn/strings.xml
index e248c2c59411..000811887788 100644
--- a/packages/SoundPicker/res/values-bn/strings.xml
+++ b/packages/SoundPicker/res/values-bn/strings.xml
@@ -25,4 +25,6 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"মুছুন"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"কাস্টম রিংটোন যোগ করা গেল না"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"কাস্টম রিংটোন মোছা গেল না"</string>
+ <!-- no translation found for app_label (3091611356093417332) -->
+ <skip />
</resources>
diff --git a/packages/SoundPicker/res/values-bs/strings.xml b/packages/SoundPicker/res/values-bs/strings.xml
index fdabd5dd22c7..0c8d33f4187e 100644
--- a/packages/SoundPicker/res/values-bs/strings.xml
+++ b/packages/SoundPicker/res/values-bs/strings.xml
@@ -25,4 +25,5 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"Izbriši"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"Nije moguće dodati prilagođenu melodiju zvona"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Nije moguće izbrisati prilagođenu melodiju zvona"</string>
+ <string name="app_label" msgid="3091611356093417332">"Zvukovi"</string>
</resources>
diff --git a/packages/SoundPicker/res/values-ca/strings.xml b/packages/SoundPicker/res/values-ca/strings.xml
index 9170740af018..ed96f70c7c01 100644
--- a/packages/SoundPicker/res/values-ca/strings.xml
+++ b/packages/SoundPicker/res/values-ca/strings.xml
@@ -25,4 +25,5 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"Suprimeix"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"No es pot afegir el so de trucada personalitzat"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"No es pot suprimir el so de trucada personalitzat"</string>
+ <string name="app_label" msgid="3091611356093417332">"Sons"</string>
</resources>
diff --git a/packages/SoundPicker/res/values-cs/strings.xml b/packages/SoundPicker/res/values-cs/strings.xml
index 899277eb1f93..e8fc97e44174 100644
--- a/packages/SoundPicker/res/values-cs/strings.xml
+++ b/packages/SoundPicker/res/values-cs/strings.xml
@@ -25,4 +25,5 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"Smazat"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"Vlastní vyzváněcí tón se nepodařilo přidat"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Vlastní vyzváněcí tón se nepodařilo smazat"</string>
+ <string name="app_label" msgid="3091611356093417332">"Zvuky"</string>
</resources>
diff --git a/packages/SoundPicker/res/values-da/strings.xml b/packages/SoundPicker/res/values-da/strings.xml
index fb3b1645b44d..b4437dc805ac 100644
--- a/packages/SoundPicker/res/values-da/strings.xml
+++ b/packages/SoundPicker/res/values-da/strings.xml
@@ -25,4 +25,5 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"Slet"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"Den tilpassede ringetone kunne ikke tilføjes"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Den tilpassede ringetone kunne ikke slettes"</string>
+ <string name="app_label" msgid="3091611356093417332">"Lyde"</string>
</resources>
diff --git a/packages/SoundPicker/res/values-de/strings.xml b/packages/SoundPicker/res/values-de/strings.xml
index b707874d8aa0..1674f307afe8 100644
--- a/packages/SoundPicker/res/values-de/strings.xml
+++ b/packages/SoundPicker/res/values-de/strings.xml
@@ -25,4 +25,6 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"Löschen"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"Benutzerdefinierter Klingelton konnte nicht hinzugefügt werden"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Benutzerdefinierter Klingelton konnte nicht gelöscht werden"</string>
+ <!-- no translation found for app_label (3091611356093417332) -->
+ <skip />
</resources>
diff --git a/packages/SoundPicker/res/values-el/strings.xml b/packages/SoundPicker/res/values-el/strings.xml
index 05c69fed8c86..41e9b0ccf334 100644
--- a/packages/SoundPicker/res/values-el/strings.xml
+++ b/packages/SoundPicker/res/values-el/strings.xml
@@ -25,4 +25,5 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"Διαγραφή"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"Δεν είναι δυνατή η προσθήκη προσαρμοσμένου ήχου κλήσης"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Δεν είναι δυνατή η διαγραφή προσαρμοσμένου ήχου κλήσης"</string>
+ <string name="app_label" msgid="3091611356093417332">"Ήχοι"</string>
</resources>
diff --git a/packages/SoundPicker/res/values-en-rAU/strings.xml b/packages/SoundPicker/res/values-en-rAU/strings.xml
index 7e4a8b695f13..4c237b993e07 100644
--- a/packages/SoundPicker/res/values-en-rAU/strings.xml
+++ b/packages/SoundPicker/res/values-en-rAU/strings.xml
@@ -25,4 +25,5 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"Delete"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"Unable to add customised ringtone"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Unable to delete customised ringtone"</string>
+ <string name="app_label" msgid="3091611356093417332">"Sounds"</string>
</resources>
diff --git a/packages/SoundPicker/res/values-en-rCA/strings.xml b/packages/SoundPicker/res/values-en-rCA/strings.xml
index 7e4a8b695f13..4c237b993e07 100644
--- a/packages/SoundPicker/res/values-en-rCA/strings.xml
+++ b/packages/SoundPicker/res/values-en-rCA/strings.xml
@@ -25,4 +25,5 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"Delete"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"Unable to add customised ringtone"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Unable to delete customised ringtone"</string>
+ <string name="app_label" msgid="3091611356093417332">"Sounds"</string>
</resources>
diff --git a/packages/SoundPicker/res/values-en-rGB/strings.xml b/packages/SoundPicker/res/values-en-rGB/strings.xml
index 7e4a8b695f13..4c237b993e07 100644
--- a/packages/SoundPicker/res/values-en-rGB/strings.xml
+++ b/packages/SoundPicker/res/values-en-rGB/strings.xml
@@ -25,4 +25,5 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"Delete"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"Unable to add customised ringtone"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Unable to delete customised ringtone"</string>
+ <string name="app_label" msgid="3091611356093417332">"Sounds"</string>
</resources>
diff --git a/packages/SoundPicker/res/values-en-rIN/strings.xml b/packages/SoundPicker/res/values-en-rIN/strings.xml
index 7e4a8b695f13..4c237b993e07 100644
--- a/packages/SoundPicker/res/values-en-rIN/strings.xml
+++ b/packages/SoundPicker/res/values-en-rIN/strings.xml
@@ -25,4 +25,5 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"Delete"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"Unable to add customised ringtone"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Unable to delete customised ringtone"</string>
+ <string name="app_label" msgid="3091611356093417332">"Sounds"</string>
</resources>
diff --git a/packages/SoundPicker/res/values-en-rXC/strings.xml b/packages/SoundPicker/res/values-en-rXC/strings.xml
index 04b2662c8caa..8397e0bb639a 100644
--- a/packages/SoundPicker/res/values-en-rXC/strings.xml
+++ b/packages/SoundPicker/res/values-en-rXC/strings.xml
@@ -25,4 +25,5 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‎‏‏‎‎‏‎‏‏‏‎‏‎‏‏‎‎‎‎‏‏‏‏‎‎‎‏‏‏‏‎‎‎‏‎‏‎‏‏‎‎‏‏‏‎‏‎‏‎‏‏‎‏‎‎‏‏‎Delete‎‏‎‎‏‎"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‎‏‏‎‏‏‏‏‏‎‎‏‏‏‎‎‏‏‎‏‎‏‏‎‏‎‏‎‎‏‏‏‏‎‏‎‎‎‎‏‎‎‏‎‎‏‏‎‏‏‏‏‏‎‎Unable to add custom ringtone‎‏‎‎‏‎"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‎‎‏‎‎‎‎‏‏‎‎‎‏‏‎‏‎‎‎‎‏‏‏‏‎‎‎‏‏‏‎‏‎‏‏‎‎‏‏‏‏‏‎‎‎‎‏‎‎‏‏‏‎‏‎‎‎‎Unable to delete custom ringtone‎‏‎‎‏‎"</string>
+ <string name="app_label" msgid="3091611356093417332">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‎‏‏‏‎‎‏‏‏‏‎‎‏‏‏‎‎‎‎‏‎‎‏‎‏‏‏‏‏‎‏‏‏‏‎‎‎‎‎‏‏‎‎‎‎‎‏‏‏‎‏‏‏‎‏‎‎‎Sounds‎‏‎‎‏‎"</string>
</resources>
diff --git a/packages/SoundPicker/res/values-es-rUS/strings.xml b/packages/SoundPicker/res/values-es-rUS/strings.xml
index 96c5e847b1c3..5bf73b2fe2b8 100644
--- a/packages/SoundPicker/res/values-es-rUS/strings.xml
+++ b/packages/SoundPicker/res/values-es-rUS/strings.xml
@@ -25,4 +25,5 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"Borrar"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"No se puede agregar el tono personalizado"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"No se puede borrar el tono personalizado"</string>
+ <string name="app_label" msgid="3091611356093417332">"Sonidos"</string>
</resources>
diff --git a/packages/SoundPicker/res/values-es/strings.xml b/packages/SoundPicker/res/values-es/strings.xml
index feccaefb2b8c..a77f656f14e5 100644
--- a/packages/SoundPicker/res/values-es/strings.xml
+++ b/packages/SoundPicker/res/values-es/strings.xml
@@ -25,4 +25,5 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"Eliminar"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"No se ha podido añadir un tono de llamada personalizado"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"No se ha podido eliminar un tono de llamada personalizado"</string>
+ <string name="app_label" msgid="3091611356093417332">"Sonidos"</string>
</resources>
diff --git a/packages/SoundPicker/res/values-et/strings.xml b/packages/SoundPicker/res/values-et/strings.xml
index 1eb5ca275b94..fa680accddf5 100644
--- a/packages/SoundPicker/res/values-et/strings.xml
+++ b/packages/SoundPicker/res/values-et/strings.xml
@@ -25,4 +25,5 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"Kustuta"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"Kohandatud helinat ei õnnestu lisada"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Kohandatud helinat ei õnnestu kustutada"</string>
+ <string name="app_label" msgid="3091611356093417332">"Helid"</string>
</resources>
diff --git a/packages/SoundPicker/res/values-eu/strings.xml b/packages/SoundPicker/res/values-eu/strings.xml
index ae3fb99d324c..0d64523aa3e9 100644
--- a/packages/SoundPicker/res/values-eu/strings.xml
+++ b/packages/SoundPicker/res/values-eu/strings.xml
@@ -25,4 +25,6 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"Ezabatu"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"Ezin da gehitu tonu pertsonalizatua"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Ezin da ezabatu tonu pertsonalizatua"</string>
+ <!-- no translation found for app_label (3091611356093417332) -->
+ <skip />
</resources>
diff --git a/packages/SoundPicker/res/values-fa/strings.xml b/packages/SoundPicker/res/values-fa/strings.xml
index bc39f74cc42b..dc7c214977f2 100644
--- a/packages/SoundPicker/res/values-fa/strings.xml
+++ b/packages/SoundPicker/res/values-fa/strings.xml
@@ -25,4 +25,5 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"حذف"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"افزودن آهنگ زنگ سفارشی ممکن نیست"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"حذف آهنگ زنگ سفارشی ممکن نیست"</string>
+ <string name="app_label" msgid="3091611356093417332">"صداها"</string>
</resources>
diff --git a/packages/SoundPicker/res/values-fi/strings.xml b/packages/SoundPicker/res/values-fi/strings.xml
index 2d602639510b..9f64f8379b43 100644
--- a/packages/SoundPicker/res/values-fi/strings.xml
+++ b/packages/SoundPicker/res/values-fi/strings.xml
@@ -25,4 +25,5 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"Poista"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"Muokatun soittoäänen lisääminen epäonnistui."</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Muokatun soittoäänen poistaminen epäonnistui."</string>
+ <string name="app_label" msgid="3091611356093417332">"Äänet"</string>
</resources>
diff --git a/packages/SoundPicker/res/values-fr-rCA/strings.xml b/packages/SoundPicker/res/values-fr-rCA/strings.xml
index 63182df7992f..cbf05909470b 100644
--- a/packages/SoundPicker/res/values-fr-rCA/strings.xml
+++ b/packages/SoundPicker/res/values-fr-rCA/strings.xml
@@ -25,4 +25,6 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"Supprimer"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"Impossible d\'ajouter une sonnerie personnalisée"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Impossible de supprimer la sonnerie personnalisée"</string>
+ <!-- no translation found for app_label (3091611356093417332) -->
+ <skip />
</resources>
diff --git a/packages/SoundPicker/res/values-fr/strings.xml b/packages/SoundPicker/res/values-fr/strings.xml
index 63182df7992f..cbf05909470b 100644
--- a/packages/SoundPicker/res/values-fr/strings.xml
+++ b/packages/SoundPicker/res/values-fr/strings.xml
@@ -25,4 +25,6 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"Supprimer"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"Impossible d\'ajouter une sonnerie personnalisée"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Impossible de supprimer la sonnerie personnalisée"</string>
+ <!-- no translation found for app_label (3091611356093417332) -->
+ <skip />
</resources>
diff --git a/packages/SoundPicker/res/values-gl/strings.xml b/packages/SoundPicker/res/values-gl/strings.xml
index 70194c778216..59a9d066a7aa 100644
--- a/packages/SoundPicker/res/values-gl/strings.xml
+++ b/packages/SoundPicker/res/values-gl/strings.xml
@@ -25,4 +25,5 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"Eliminar"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"Non se pode engadir un ton de chamada personalizado"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Non se pode eliminar un ton de chamada personalizado"</string>
+ <string name="app_label" msgid="3091611356093417332">"Sons"</string>
</resources>
diff --git a/packages/SoundPicker/res/values-gu/strings.xml b/packages/SoundPicker/res/values-gu/strings.xml
index 70d5c2c651b8..0e5cd45812d6 100644
--- a/packages/SoundPicker/res/values-gu/strings.xml
+++ b/packages/SoundPicker/res/values-gu/strings.xml
@@ -25,4 +25,6 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"ડિલીટ કરો"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"કસ્ટમ રિંગટોન ઉમેરવામાં અસમર્થ"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"કસ્ટમ રિંગટોન કાઢી નાખવામાં અસમર્થ"</string>
+ <!-- no translation found for app_label (3091611356093417332) -->
+ <skip />
</resources>
diff --git a/packages/SoundPicker/res/values-hi/strings.xml b/packages/SoundPicker/res/values-hi/strings.xml
index 316447c67ab4..80c42a1074d8 100644
--- a/packages/SoundPicker/res/values-hi/strings.xml
+++ b/packages/SoundPicker/res/values-hi/strings.xml
@@ -25,4 +25,6 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"मिटाएं"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"आपके मुताबिक रिंगटोन नहीं जोड़ी जा सकी"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"आपके मुताबिक रिंगटोन नहीं हटाई जा सकी"</string>
+ <!-- no translation found for app_label (3091611356093417332) -->
+ <skip />
</resources>
diff --git a/packages/SoundPicker/res/values-hr/strings.xml b/packages/SoundPicker/res/values-hr/strings.xml
index ed0a27da735d..f74c4ae69e80 100644
--- a/packages/SoundPicker/res/values-hr/strings.xml
+++ b/packages/SoundPicker/res/values-hr/strings.xml
@@ -25,4 +25,5 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"Izbriši"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"Dodavanje prilagođene melodije zvona nije moguće"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Brisanje prilagođene melodije zvona nije moguće"</string>
+ <string name="app_label" msgid="3091611356093417332">"Zvukovi"</string>
</resources>
diff --git a/packages/SoundPicker/res/values-hu/strings.xml b/packages/SoundPicker/res/values-hu/strings.xml
index da0b1c452d2e..c7a5cf00b0e2 100644
--- a/packages/SoundPicker/res/values-hu/strings.xml
+++ b/packages/SoundPicker/res/values-hu/strings.xml
@@ -25,4 +25,6 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"Törlés"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"Nem sikerült hozzáadni az egyéni csengőhangot"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Nem sikerült törölni az egyéni csengőhangot"</string>
+ <!-- no translation found for app_label (3091611356093417332) -->
+ <skip />
</resources>
diff --git a/packages/SoundPicker/res/values-hy/strings.xml b/packages/SoundPicker/res/values-hy/strings.xml
index f422ff861d84..f938c544d878 100644
--- a/packages/SoundPicker/res/values-hy/strings.xml
+++ b/packages/SoundPicker/res/values-hy/strings.xml
@@ -25,4 +25,6 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"Ջնջել"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"Հնարավոր չէ հատուկ զանգերանգ ավելացնել"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Հնարավոր չէ ջնջել հատուկ զանգերանգը"</string>
+ <!-- no translation found for app_label (3091611356093417332) -->
+ <skip />
</resources>
diff --git a/packages/SoundPicker/res/values-in/strings.xml b/packages/SoundPicker/res/values-in/strings.xml
index fe2d4a2c35c0..98e974aa16d5 100644
--- a/packages/SoundPicker/res/values-in/strings.xml
+++ b/packages/SoundPicker/res/values-in/strings.xml
@@ -25,4 +25,6 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"Hapus"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"Tidak dapat menambahkan nada dering khusus"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Tidak dapat menghapus nada dering khusus"</string>
+ <!-- no translation found for app_label (3091611356093417332) -->
+ <skip />
</resources>
diff --git a/packages/SoundPicker/res/values-is/strings.xml b/packages/SoundPicker/res/values-is/strings.xml
index ee4ca2e46d98..d0fce78ff9d9 100644
--- a/packages/SoundPicker/res/values-is/strings.xml
+++ b/packages/SoundPicker/res/values-is/strings.xml
@@ -25,4 +25,5 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"Eyða"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"Get ekki bætt sérsniðnum hringitóni við"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Get ekki eytt sérsniðnum hringitóni"</string>
+ <string name="app_label" msgid="3091611356093417332">"Hljóð"</string>
</resources>
diff --git a/packages/SoundPicker/res/values-it/strings.xml b/packages/SoundPicker/res/values-it/strings.xml
index f3fa56938465..e080a7557ac5 100644
--- a/packages/SoundPicker/res/values-it/strings.xml
+++ b/packages/SoundPicker/res/values-it/strings.xml
@@ -25,4 +25,6 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"Elimina"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"Impossibile aggiungere suoneria personalizzata"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Impossibile eliminare suoneria personalizzata"</string>
+ <!-- no translation found for app_label (3091611356093417332) -->
+ <skip />
</resources>
diff --git a/packages/SoundPicker/res/values-iw/strings.xml b/packages/SoundPicker/res/values-iw/strings.xml
index efe6f1e9e7e4..23dbf485971b 100644
--- a/packages/SoundPicker/res/values-iw/strings.xml
+++ b/packages/SoundPicker/res/values-iw/strings.xml
@@ -25,4 +25,6 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"מחיקה"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"לא ניתן להוסיף רינגטון מותאם אישית"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"לא ניתן למחוק רינגטון מותאם אישית"</string>
+ <!-- no translation found for app_label (3091611356093417332) -->
+ <skip />
</resources>
diff --git a/packages/SoundPicker/res/values-ja/strings.xml b/packages/SoundPicker/res/values-ja/strings.xml
index 22f4e50879bf..7c2aec60df75 100644
--- a/packages/SoundPicker/res/values-ja/strings.xml
+++ b/packages/SoundPicker/res/values-ja/strings.xml
@@ -25,4 +25,5 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"削除"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"カスタム着信音を追加できません"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"カスタム着信音を削除できません"</string>
+ <string name="app_label" msgid="3091611356093417332">"サウンド"</string>
</resources>
diff --git a/packages/SoundPicker/res/values-ka/strings.xml b/packages/SoundPicker/res/values-ka/strings.xml
index 501620885ccd..1cfe2401a99b 100644
--- a/packages/SoundPicker/res/values-ka/strings.xml
+++ b/packages/SoundPicker/res/values-ka/strings.xml
@@ -25,4 +25,5 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"წაშლა"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"მორგებული ზარის დამატება შეუძლებელია"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"მორგებული ზარის წაშლა შეუძლებელია"</string>
+ <string name="app_label" msgid="3091611356093417332">"ხმები"</string>
</resources>
diff --git a/packages/SoundPicker/res/values-kk/strings.xml b/packages/SoundPicker/res/values-kk/strings.xml
index 1c74567a0b60..59c787dbe4d4 100644
--- a/packages/SoundPicker/res/values-kk/strings.xml
+++ b/packages/SoundPicker/res/values-kk/strings.xml
@@ -25,4 +25,6 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"Жою"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"Арнаулы рингтонды енгізу мүмкін емес"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Арнаулы рингтонды жою мүмкін емес"</string>
+ <!-- no translation found for app_label (3091611356093417332) -->
+ <skip />
</resources>
diff --git a/packages/SoundPicker/res/values-km/strings.xml b/packages/SoundPicker/res/values-km/strings.xml
index d512bc62e00b..7f8720076f58 100644
--- a/packages/SoundPicker/res/values-km/strings.xml
+++ b/packages/SoundPicker/res/values-km/strings.xml
@@ -25,4 +25,6 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"លុប"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"មិន​អាច​បន្ថែម​សំឡេង​រោទ៍​ផ្ទាល់ខ្លួន​បាន"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"មិន​អាច​លុប​សំឡេង​រោទ៍​ផ្ទាល់ខ្លួន​បាន​ទេ"</string>
+ <!-- no translation found for app_label (3091611356093417332) -->
+ <skip />
</resources>
diff --git a/packages/SoundPicker/res/values-kn/strings.xml b/packages/SoundPicker/res/values-kn/strings.xml
index 030d3f2e5ca7..e6a05c2b4e2d 100644
--- a/packages/SoundPicker/res/values-kn/strings.xml
+++ b/packages/SoundPicker/res/values-kn/strings.xml
@@ -25,4 +25,5 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"ಅಳಿಸಿ"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"ಕಸ್ಟಮ್ ರಿಂಗ್‌ಟೋನ್ ಸೇರಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"ಕಸ್ಟಮ್ ರಿಂಗ್‌ಟೋನ್ ಅಳಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ"</string>
+ <string name="app_label" msgid="3091611356093417332">"ಧ್ವನಿಗಳು"</string>
</resources>
diff --git a/packages/SoundPicker/res/values-ko/strings.xml b/packages/SoundPicker/res/values-ko/strings.xml
index 555434f1f886..41711da2b4a6 100644
--- a/packages/SoundPicker/res/values-ko/strings.xml
+++ b/packages/SoundPicker/res/values-ko/strings.xml
@@ -25,4 +25,6 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"삭제"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"맞춤 벨소리를 추가할 수 없습니다."</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"맞춤 벨소리를 삭제할 수 없습니다."</string>
+ <!-- no translation found for app_label (3091611356093417332) -->
+ <skip />
</resources>
diff --git a/packages/SoundPicker/res/values-ky/strings.xml b/packages/SoundPicker/res/values-ky/strings.xml
index 5a3ef907fd63..6e8b052b6140 100644
--- a/packages/SoundPicker/res/values-ky/strings.xml
+++ b/packages/SoundPicker/res/values-ky/strings.xml
@@ -25,4 +25,6 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"Жок кылуу"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"Жеке рингтон кошулбай жатат"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Жеке рингтон жок кылынбай жатат"</string>
+ <!-- no translation found for app_label (3091611356093417332) -->
+ <skip />
</resources>
diff --git a/packages/SoundPicker/res/values-lo/strings.xml b/packages/SoundPicker/res/values-lo/strings.xml
index 983ff72493d7..8bcae0df95d2 100644
--- a/packages/SoundPicker/res/values-lo/strings.xml
+++ b/packages/SoundPicker/res/values-lo/strings.xml
@@ -25,4 +25,5 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"​ລຶບ"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"Unable to add custom ringtone"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Unable to delete custom ringtone"</string>
+ <string name="app_label" msgid="3091611356093417332">"ສຽງ"</string>
</resources>
diff --git a/packages/SoundPicker/res/values-lt/strings.xml b/packages/SoundPicker/res/values-lt/strings.xml
index 0789ea1fb881..3323ebdc8ce6 100644
--- a/packages/SoundPicker/res/values-lt/strings.xml
+++ b/packages/SoundPicker/res/values-lt/strings.xml
@@ -25,4 +25,6 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"Ištrinti"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"Nepavyksta pridėti tinkinto skambėjimo tono"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Nepavyksta ištrinti tinkinto skambėjimo tono"</string>
+ <!-- no translation found for app_label (3091611356093417332) -->
+ <skip />
</resources>
diff --git a/packages/SoundPicker/res/values-lv/strings.xml b/packages/SoundPicker/res/values-lv/strings.xml
index 3d0c5cae6bc1..5254bc6ec54b 100644
--- a/packages/SoundPicker/res/values-lv/strings.xml
+++ b/packages/SoundPicker/res/values-lv/strings.xml
@@ -25,4 +25,6 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"Dzēst"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"Nevar pievienot pielāgotu zvana signālu"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Nevar izdzēst pielāgotu zvana signālu"</string>
+ <!-- no translation found for app_label (3091611356093417332) -->
+ <skip />
</resources>
diff --git a/packages/SoundPicker/res/values-mk/strings.xml b/packages/SoundPicker/res/values-mk/strings.xml
index f39c386a7b78..545d5ed2f8f2 100644
--- a/packages/SoundPicker/res/values-mk/strings.xml
+++ b/packages/SoundPicker/res/values-mk/strings.xml
@@ -25,4 +25,5 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"Избриши"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"Не може да се додаде приспособена мелодија"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Не може да се избрише приспособена мелодија"</string>
+ <string name="app_label" msgid="3091611356093417332">"Звуци"</string>
</resources>
diff --git a/packages/SoundPicker/res/values-ml/strings.xml b/packages/SoundPicker/res/values-ml/strings.xml
index 738d7abb8eea..8772d775d34a 100644
--- a/packages/SoundPicker/res/values-ml/strings.xml
+++ b/packages/SoundPicker/res/values-ml/strings.xml
@@ -25,4 +25,6 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"ഇല്ലാതാക്കുക"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"ഇഷ്ടാനുസൃത റിംഗ്‌ടോൺ ചേർക്കാനാവില്ല"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"ഇഷ്ടാനുസൃത റിംഗ്‌ടോൺ ഇല്ലാതാക്കാനാവില്ല"</string>
+ <!-- no translation found for app_label (3091611356093417332) -->
+ <skip />
</resources>
diff --git a/packages/SoundPicker/res/values-mn/strings.xml b/packages/SoundPicker/res/values-mn/strings.xml
index cfc81d622de7..b8ce2388dc7a 100644
--- a/packages/SoundPicker/res/values-mn/strings.xml
+++ b/packages/SoundPicker/res/values-mn/strings.xml
@@ -25,4 +25,6 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"Устгах"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"Захиалгат хонхны ая нэмэх боломжгүй"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Захиалгат хонхны ая устгах боломжгүй"</string>
+ <!-- no translation found for app_label (3091611356093417332) -->
+ <skip />
</resources>
diff --git a/packages/SoundPicker/res/values-mr/strings.xml b/packages/SoundPicker/res/values-mr/strings.xml
index e759eb3e1ffc..09d0d4c2040e 100644
--- a/packages/SoundPicker/res/values-mr/strings.xml
+++ b/packages/SoundPicker/res/values-mr/strings.xml
@@ -25,4 +25,6 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"हटवा"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"कस्टम रिंगटोन जोडण्यात अक्षम"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"कस्टम रिंगटोन हटविण्यात अक्षम"</string>
+ <!-- no translation found for app_label (3091611356093417332) -->
+ <skip />
</resources>
diff --git a/packages/SoundPicker/res/values-ms/strings.xml b/packages/SoundPicker/res/values-ms/strings.xml
index a65f8bc9e926..ac5e983eac3c 100644
--- a/packages/SoundPicker/res/values-ms/strings.xml
+++ b/packages/SoundPicker/res/values-ms/strings.xml
@@ -25,4 +25,6 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"Padam"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"Tidak dapat menambah nada dering tersuai"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Tidak dapat memadamkan nada dering tersuai"</string>
+ <!-- no translation found for app_label (3091611356093417332) -->
+ <skip />
</resources>
diff --git a/packages/SoundPicker/res/values-my/strings.xml b/packages/SoundPicker/res/values-my/strings.xml
index 83c44149ad76..62163e950475 100644
--- a/packages/SoundPicker/res/values-my/strings.xml
+++ b/packages/SoundPicker/res/values-my/strings.xml
@@ -25,4 +25,5 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"ဖျက်ရန်"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"စိတ်ကြိုက်ဖုန်းမြည်သံကို ထည့်သွင်း၍မရပါ"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"စိတ်ကြိုက်ဖုန်းမြည်သံကို ဖျက်၍မရပါ"</string>
+ <string name="app_label" msgid="3091611356093417332">"အသံများ"</string>
</resources>
diff --git a/packages/SoundPicker/res/values-nb/strings.xml b/packages/SoundPicker/res/values-nb/strings.xml
index 37d3ee072f07..e4e259af541d 100644
--- a/packages/SoundPicker/res/values-nb/strings.xml
+++ b/packages/SoundPicker/res/values-nb/strings.xml
@@ -25,4 +25,5 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"Slett"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"Kan ikke legge til egendefinert ringelyd"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Kan ikke slette egendefinert ringelyd"</string>
+ <string name="app_label" msgid="3091611356093417332">"Lyder"</string>
</resources>
diff --git a/packages/SoundPicker/res/values-ne/strings.xml b/packages/SoundPicker/res/values-ne/strings.xml
index 0f787cf8b5d4..955b9fa4aa16 100644
--- a/packages/SoundPicker/res/values-ne/strings.xml
+++ b/packages/SoundPicker/res/values-ne/strings.xml
@@ -25,4 +25,6 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"मेट्नुहोस्"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"आफू अनुकूल रिङटोन थप्न सकिएन"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"आफू अनुकूल रिङटोनलाई मेट्न सकिएन"</string>
+ <!-- no translation found for app_label (3091611356093417332) -->
+ <skip />
</resources>
diff --git a/packages/SoundPicker/res/values-nl/strings.xml b/packages/SoundPicker/res/values-nl/strings.xml
index 90f2f788d933..5b6fb70b2a82 100644
--- a/packages/SoundPicker/res/values-nl/strings.xml
+++ b/packages/SoundPicker/res/values-nl/strings.xml
@@ -25,4 +25,5 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"Verwijderen"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"Toevoegen van aangepaste ringtone is mislukt"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Verwijderen van aangepaste ringtone is mislukt"</string>
+ <string name="app_label" msgid="3091611356093417332">"Geluiden"</string>
</resources>
diff --git a/packages/SoundPicker/res/values-or/strings.xml b/packages/SoundPicker/res/values-or/strings.xml
index 89dd760afd70..767eae14163a 100644
--- a/packages/SoundPicker/res/values-or/strings.xml
+++ b/packages/SoundPicker/res/values-or/strings.xml
@@ -25,4 +25,6 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"ଡିଲିଟ୍‌ କରନ୍ତୁ"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"କଷ୍ଟମ୍‍ ରିଙ୍ଗଟୋନ୍‍ ଯୋଡ଼ିପାରିବ ନାହିଁ"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"କଷ୍ଟମ୍‍ ରିଙ୍ଗଟୋନ୍‍ ଡିଲିଟ୍‍ କରିପାରିବ ନାହିଁ"</string>
+ <!-- no translation found for app_label (3091611356093417332) -->
+ <skip />
</resources>
diff --git a/packages/SoundPicker/res/values-pa/strings.xml b/packages/SoundPicker/res/values-pa/strings.xml
index 6946f18fc4e3..145bcd73957b 100644
--- a/packages/SoundPicker/res/values-pa/strings.xml
+++ b/packages/SoundPicker/res/values-pa/strings.xml
@@ -25,4 +25,6 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"ਮਿਟਾਓ"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"ਵਿਉਂਤੀ ਰਿੰਗਟੋਨ ਨੂੰ ਸ਼ਾਮਲ ਕਰਨ ਦੇ ਅਯੋਗ"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"ਵਿਉਂਤੀ ਰਿੰਗਟੋਨ ਨੂੰ ਮਿਟਾਉਣ ਦੇ ਅਯੋਗ"</string>
+ <!-- no translation found for app_label (3091611356093417332) -->
+ <skip />
</resources>
diff --git a/packages/SoundPicker/res/values-pl/strings.xml b/packages/SoundPicker/res/values-pl/strings.xml
index f172659e3d7e..ba8ee403ef14 100644
--- a/packages/SoundPicker/res/values-pl/strings.xml
+++ b/packages/SoundPicker/res/values-pl/strings.xml
@@ -25,4 +25,6 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"Usuń"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"Nie można dodać dzwonka niestandardowego"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Nie można usunąć dzwonka niestandardowego"</string>
+ <!-- no translation found for app_label (3091611356093417332) -->
+ <skip />
</resources>
diff --git a/packages/SoundPicker/res/values-pt-rBR/strings.xml b/packages/SoundPicker/res/values-pt-rBR/strings.xml
index 4fad12754ec7..7b545e15ccaa 100644
--- a/packages/SoundPicker/res/values-pt-rBR/strings.xml
+++ b/packages/SoundPicker/res/values-pt-rBR/strings.xml
@@ -25,4 +25,5 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"Excluir"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"Não foi possível adicionar o toque personalizado"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Não foi possível excluir o toque personalizado"</string>
+ <string name="app_label" msgid="3091611356093417332">"Sons"</string>
</resources>
diff --git a/packages/SoundPicker/res/values-pt-rPT/strings.xml b/packages/SoundPicker/res/values-pt-rPT/strings.xml
index c93ec85a14b7..5d742f1d75c7 100644
--- a/packages/SoundPicker/res/values-pt-rPT/strings.xml
+++ b/packages/SoundPicker/res/values-pt-rPT/strings.xml
@@ -25,4 +25,5 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"Eliminar"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"Não foi possível adicionar o toque personalizado"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Não foi possível eliminar o toque personalizado"</string>
+ <string name="app_label" msgid="3091611356093417332">"Sons"</string>
</resources>
diff --git a/packages/SoundPicker/res/values-pt/strings.xml b/packages/SoundPicker/res/values-pt/strings.xml
index 4fad12754ec7..7b545e15ccaa 100644
--- a/packages/SoundPicker/res/values-pt/strings.xml
+++ b/packages/SoundPicker/res/values-pt/strings.xml
@@ -25,4 +25,5 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"Excluir"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"Não foi possível adicionar o toque personalizado"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Não foi possível excluir o toque personalizado"</string>
+ <string name="app_label" msgid="3091611356093417332">"Sons"</string>
</resources>
diff --git a/packages/SoundPicker/res/values-ro/strings.xml b/packages/SoundPicker/res/values-ro/strings.xml
index db39f672ca16..6190f7f8eac3 100644
--- a/packages/SoundPicker/res/values-ro/strings.xml
+++ b/packages/SoundPicker/res/values-ro/strings.xml
@@ -25,4 +25,5 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"Ștergeți"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"Nu se poate adăuga tonul de sonerie personalizat"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Nu se poate șterge tonul de sonerie personalizat"</string>
+ <string name="app_label" msgid="3091611356093417332">"Sunete"</string>
</resources>
diff --git a/packages/SoundPicker/res/values-ru/strings.xml b/packages/SoundPicker/res/values-ru/strings.xml
index 5185bde47c8a..0d48ac1e8785 100644
--- a/packages/SoundPicker/res/values-ru/strings.xml
+++ b/packages/SoundPicker/res/values-ru/strings.xml
@@ -25,4 +25,5 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"Удалить"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"Не удалось добавить рингтон"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Не удалось удалить рингтон"</string>
+ <string name="app_label" msgid="3091611356093417332">"Звуки"</string>
</resources>
diff --git a/packages/SoundPicker/res/values-si/strings.xml b/packages/SoundPicker/res/values-si/strings.xml
index c8949a9f8a5d..1872b6b27f30 100644
--- a/packages/SoundPicker/res/values-si/strings.xml
+++ b/packages/SoundPicker/res/values-si/strings.xml
@@ -25,4 +25,5 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"මකන්න"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"අභිරුචි නාද රිද්මය එක් කළ නොහැකිය"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"අභිරුචි නාද රිද්මය මැකිය නොහැකිය"</string>
+ <string name="app_label" msgid="3091611356093417332">"ශබ්ද"</string>
</resources>
diff --git a/packages/SoundPicker/res/values-sk/strings.xml b/packages/SoundPicker/res/values-sk/strings.xml
index 9e401bef2382..78b0223fc549 100644
--- a/packages/SoundPicker/res/values-sk/strings.xml
+++ b/packages/SoundPicker/res/values-sk/strings.xml
@@ -25,4 +25,6 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"Odstrániť"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"Nepodarilo sa pridať vlastný tón zvonenia"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Nepodarilo sa odstrániť vlastný tón zvonenia"</string>
+ <!-- no translation found for app_label (3091611356093417332) -->
+ <skip />
</resources>
diff --git a/packages/SoundPicker/res/values-sl/strings.xml b/packages/SoundPicker/res/values-sl/strings.xml
index 2261b0313d3c..77a2a2cef0e7 100644
--- a/packages/SoundPicker/res/values-sl/strings.xml
+++ b/packages/SoundPicker/res/values-sl/strings.xml
@@ -25,4 +25,5 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"Izbriši"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"Tona zvonjenja po meri ni mogoče dodati"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Tona zvonjenja po meri ni mogoče izbrisati"</string>
+ <string name="app_label" msgid="3091611356093417332">"Zvoki"</string>
</resources>
diff --git a/packages/SoundPicker/res/values-sq/strings.xml b/packages/SoundPicker/res/values-sq/strings.xml
index 7acdfa7efdd0..e35dd71c3beb 100644
--- a/packages/SoundPicker/res/values-sq/strings.xml
+++ b/packages/SoundPicker/res/values-sq/strings.xml
@@ -25,4 +25,5 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"Fshi"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"Nuk mund të shtojë ton zileje të personalizuar"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Nuk mund të fshijë ton zileje të personalizuar"</string>
+ <string name="app_label" msgid="3091611356093417332">"Tingujt"</string>
</resources>
diff --git a/packages/SoundPicker/res/values-sr/strings.xml b/packages/SoundPicker/res/values-sr/strings.xml
index 89fffa863c06..bc573f5a2662 100644
--- a/packages/SoundPicker/res/values-sr/strings.xml
+++ b/packages/SoundPicker/res/values-sr/strings.xml
@@ -25,4 +25,5 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"Избриши"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"Додавање прилагођене мелодије звона није успело"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Брисање прилагођене мелодије звона није успело"</string>
+ <string name="app_label" msgid="3091611356093417332">"Звукови"</string>
</resources>
diff --git a/packages/SoundPicker/res/values-sv/strings.xml b/packages/SoundPicker/res/values-sv/strings.xml
index 5eb245502eeb..4bec7319c721 100644
--- a/packages/SoundPicker/res/values-sv/strings.xml
+++ b/packages/SoundPicker/res/values-sv/strings.xml
@@ -25,4 +25,6 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"Radera"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"Det gick inte att lägga till en egen ringsignal"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Det gick inte att radera den egna ringsignalen"</string>
+ <!-- no translation found for app_label (3091611356093417332) -->
+ <skip />
</resources>
diff --git a/packages/SoundPicker/res/values-sw/strings.xml b/packages/SoundPicker/res/values-sw/strings.xml
index 7a426c4f77ef..b0234500b64c 100644
--- a/packages/SoundPicker/res/values-sw/strings.xml
+++ b/packages/SoundPicker/res/values-sw/strings.xml
@@ -25,4 +25,5 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"Futa"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"Imeshindwa kuongeza mlio maalum wa simu"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Imeshindwa kufuta mlio maalum wa simu"</string>
+ <string name="app_label" msgid="3091611356093417332">"Sauti"</string>
</resources>
diff --git a/packages/SoundPicker/res/values-ta/strings.xml b/packages/SoundPicker/res/values-ta/strings.xml
index b1b80464ba8e..a3d2a7aa395a 100644
--- a/packages/SoundPicker/res/values-ta/strings.xml
+++ b/packages/SoundPicker/res/values-ta/strings.xml
@@ -25,4 +25,6 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"நீக்கு"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"பிரத்தியேக ரிங்டோனைச் சேர்க்க முடியவில்லை"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"பிரத்தியேக ரிங்டோனை நீக்க முடியவில்லை"</string>
+ <!-- no translation found for app_label (3091611356093417332) -->
+ <skip />
</resources>
diff --git a/packages/SoundPicker/res/values-te/strings.xml b/packages/SoundPicker/res/values-te/strings.xml
index 142c73c969d2..a39527c15b2a 100644
--- a/packages/SoundPicker/res/values-te/strings.xml
+++ b/packages/SoundPicker/res/values-te/strings.xml
@@ -25,4 +25,6 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"తొలగించు"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"అనుకూల రింగ్‌టోన్‌ను జోడించలేకపోయింది"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"అనుకూల రింగ్‌టోన్‌ను తొలగించలేకపోయింది"</string>
+ <!-- no translation found for app_label (3091611356093417332) -->
+ <skip />
</resources>
diff --git a/packages/SoundPicker/res/values-th/strings.xml b/packages/SoundPicker/res/values-th/strings.xml
index ae98c3cc4d62..c6b138a1e63e 100644
--- a/packages/SoundPicker/res/values-th/strings.xml
+++ b/packages/SoundPicker/res/values-th/strings.xml
@@ -25,4 +25,6 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"ลบ"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"ไม่สามารถเพิ่มเสียงเรียกเข้าที่กำหนดเอง"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"ไม่สามารถลบเสียงเรียกเข้าที่กำหนดเอง"</string>
+ <!-- no translation found for app_label (3091611356093417332) -->
+ <skip />
</resources>
diff --git a/packages/SoundPicker/res/values-tl/strings.xml b/packages/SoundPicker/res/values-tl/strings.xml
index e35c8aa133f1..c0c17128a53f 100644
--- a/packages/SoundPicker/res/values-tl/strings.xml
+++ b/packages/SoundPicker/res/values-tl/strings.xml
@@ -25,4 +25,5 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"I-delete"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"Hindi maidagdag ang custom na ringtone"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Hindi ma-delete ang custom na ringtone"</string>
+ <string name="app_label" msgid="3091611356093417332">"Mga Tunog"</string>
</resources>
diff --git a/packages/SoundPicker/res/values-tr/strings.xml b/packages/SoundPicker/res/values-tr/strings.xml
index 3c634d8c356f..955c23f068bf 100644
--- a/packages/SoundPicker/res/values-tr/strings.xml
+++ b/packages/SoundPicker/res/values-tr/strings.xml
@@ -25,4 +25,5 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"Sil"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"Özel zil sesi eklenemiyor"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Özel zil sesi silinemiyor"</string>
+ <string name="app_label" msgid="3091611356093417332">"Sesler"</string>
</resources>
diff --git a/packages/SoundPicker/res/values-uk/strings.xml b/packages/SoundPicker/res/values-uk/strings.xml
index bb71ad019713..baba766798b7 100644
--- a/packages/SoundPicker/res/values-uk/strings.xml
+++ b/packages/SoundPicker/res/values-uk/strings.xml
@@ -25,4 +25,6 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"Видалити"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"Не вдалося додати користувацький сигнал дзвінка"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Не вдалося видалити користувацький сигнал дзвінка"</string>
+ <!-- no translation found for app_label (3091611356093417332) -->
+ <skip />
</resources>
diff --git a/packages/SoundPicker/res/values-ur/strings.xml b/packages/SoundPicker/res/values-ur/strings.xml
index 0a4f5ed9a2de..e32288640e0c 100644
--- a/packages/SoundPicker/res/values-ur/strings.xml
+++ b/packages/SoundPicker/res/values-ur/strings.xml
@@ -25,4 +25,6 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"حذف کریں"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"حسب ضرورت رنگ ٹون شامل کرنے سے قاصر ہے"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"حسب ضرورت رنگ ٹون حذف کرنے سے قاصر ہے"</string>
+ <!-- no translation found for app_label (3091611356093417332) -->
+ <skip />
</resources>
diff --git a/packages/SoundPicker/res/values-uz/strings.xml b/packages/SoundPicker/res/values-uz/strings.xml
index 17d7ed8ac6a0..9018e660d8fc 100644
--- a/packages/SoundPicker/res/values-uz/strings.xml
+++ b/packages/SoundPicker/res/values-uz/strings.xml
@@ -25,4 +25,5 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"O‘chirish"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"Maxsus rington qo‘shib bo‘lmadi"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Maxsus ringtonni o‘chirib bo‘lmadi"</string>
+ <string name="app_label" msgid="3091611356093417332">"Tovushlar"</string>
</resources>
diff --git a/packages/SoundPicker/res/values-vi/strings.xml b/packages/SoundPicker/res/values-vi/strings.xml
index c167442aa40c..a52c9958222e 100644
--- a/packages/SoundPicker/res/values-vi/strings.xml
+++ b/packages/SoundPicker/res/values-vi/strings.xml
@@ -25,4 +25,6 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"Xóa"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"Không thể thêm nhạc chuông tùy chỉnh"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Không thể xóa nhạc chuông tùy chỉnh"</string>
+ <!-- no translation found for app_label (3091611356093417332) -->
+ <skip />
</resources>
diff --git a/packages/SoundPicker/res/values-zh-rCN/strings.xml b/packages/SoundPicker/res/values-zh-rCN/strings.xml
index d380a8ec5845..e2f3552ee4bd 100644
--- a/packages/SoundPicker/res/values-zh-rCN/strings.xml
+++ b/packages/SoundPicker/res/values-zh-rCN/strings.xml
@@ -25,4 +25,6 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"删除"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"无法添加自定义铃声"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"无法删除自定义铃声"</string>
+ <!-- no translation found for app_label (3091611356093417332) -->
+ <skip />
</resources>
diff --git a/packages/SoundPicker/res/values-zh-rHK/strings.xml b/packages/SoundPicker/res/values-zh-rHK/strings.xml
index ccc569275f10..1a628aa10491 100644
--- a/packages/SoundPicker/res/values-zh-rHK/strings.xml
+++ b/packages/SoundPicker/res/values-zh-rHK/strings.xml
@@ -25,4 +25,6 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"刪除"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"無法加入自訂鈴聲"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"無法刪除自訂鈴聲"</string>
+ <!-- no translation found for app_label (3091611356093417332) -->
+ <skip />
</resources>
diff --git a/packages/SoundPicker/res/values-zh-rTW/strings.xml b/packages/SoundPicker/res/values-zh-rTW/strings.xml
index b920f7c03230..b8a91e7a3257 100644
--- a/packages/SoundPicker/res/values-zh-rTW/strings.xml
+++ b/packages/SoundPicker/res/values-zh-rTW/strings.xml
@@ -25,4 +25,6 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"刪除"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"無法新增自訂鈴聲"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"無法刪除自訂鈴聲"</string>
+ <!-- no translation found for app_label (3091611356093417332) -->
+ <skip />
</resources>
diff --git a/packages/SoundPicker/res/values-zu/strings.xml b/packages/SoundPicker/res/values-zu/strings.xml
index fb75d9374d19..29a8ffe846b2 100644
--- a/packages/SoundPicker/res/values-zu/strings.xml
+++ b/packages/SoundPicker/res/values-zu/strings.xml
@@ -25,4 +25,5 @@
<string name="delete_ringtone_text" msgid="201443984070732499">"Susa"</string>
<string name="unable_to_add_ringtone" msgid="4583511263449467326">"Ayikwazi ukwengeza ithoni yokukhala yangokwezifiso"</string>
<string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Ayikwazi ukususa ithoni yokukhala yangokwezifiso"</string>
+ <string name="app_label" msgid="3091611356093417332">"Imisindo"</string>
</resources>
diff --git a/packages/SoundPicker/res/values/strings.xml b/packages/SoundPicker/res/values/strings.xml
index 56ed5fd5d58e..04a2c2bb83c3 100644
--- a/packages/SoundPicker/res/values/strings.xml
+++ b/packages/SoundPicker/res/values/strings.xml
@@ -37,4 +37,7 @@
<string name="unable_to_add_ringtone">Unable to add custom ringtone</string>
<!-- Text for the Toast displayed when deleting a custom ringtone fails. -->
<string name="unable_to_delete_ringtone">Unable to delete custom ringtone</string>
+
+ <!-- Text for the name of the app. [CHAR LIMIT=12] -->
+ <string name="app_label">Sounds</string>
</resources>
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 985269b2bb75..5b6155180e0a 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -263,6 +263,9 @@
<!-- Restore settings (used by QS) even if they have been modified -->
<uses-permission android:name="android.permission.MODIFY_SETTINGS_OVERRIDEABLE_BY_RESTORE" />
+ <!-- Permission to make accessibility service access Bubbles -->
+ <uses-permission android:name="android.permission.ADD_TRUSTED_DISPLAY" />
+
<protected-broadcast android:name="com.android.settingslib.action.REGISTER_SLICE_RECEIVER" />
<protected-broadcast android:name="com.android.settingslib.action.UNREGISTER_SLICE_RECEIVER" />
<protected-broadcast android:name="com.android.settings.flashlight.action.FLASHLIGHT_CHANGED" />
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/FalsingManager.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/FalsingManager.java
index bcff63471302..9d52098f37d5 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/FalsingManager.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/FalsingManager.java
@@ -30,7 +30,7 @@ import java.io.PrintWriter;
*/
@ProvidesInterface(version = FalsingManager.VERSION)
public interface FalsingManager {
- int VERSION = 3;
+ int VERSION = 4;
void onSuccessfulUnlock();
@@ -88,11 +88,11 @@ public interface FalsingManager {
void onScreenOff();
- void onNotificatonStopDismissing();
+ void onNotificationStopDismissing();
void onNotificationDismissed();
- void onNotificatonStartDismissing();
+ void onNotificationStartDismissing();
void onNotificationDoubleTap(boolean accepted, float dx, float dy);
diff --git a/packages/SystemUI/res-keyguard/drawable/qs_media_seamless_background.xml b/packages/SystemUI/res-keyguard/drawable/qs_media_seamless_background.xml
new file mode 100644
index 000000000000..3790378ff3ae
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/qs_media_seamless_background.xml
@@ -0,0 +1,26 @@
+<?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
+ -->
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+ android:color="@color/media_seamless_border">
+ <item android:id="@android:id/background">
+ <shape
+ android:color="@android:color/transparent">
+ <stroke android:width="1dp" android:color="@color/media_seamless_border"/>
+ <corners android:radius="24dp"/>
+ </shape>
+ </item>
+</ripple> \ No newline at end of file
diff --git a/packages/SystemUI/res-keyguard/layout/qs_media_divider.xml b/packages/SystemUI/res-keyguard/layout/qs_media_divider.xml
new file mode 100644
index 000000000000..1be489cdc700
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/layout/qs_media_divider.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<View xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="1dp"
+ android:layout_marginBottom="16dp"
+ android:background="@color/media_divider">
+</View> \ No newline at end of file
diff --git a/packages/SystemUI/res-keyguard/values/styles.xml b/packages/SystemUI/res-keyguard/values/styles.xml
index 67c4458de2f2..5f2a946a1b6d 100644
--- a/packages/SystemUI/res-keyguard/values/styles.xml
+++ b/packages/SystemUI/res-keyguard/values/styles.xml
@@ -129,7 +129,7 @@
</style>
<style name="TextAppearance.Keyguard.BottomArea">
- <item name="android:textSize">16sp</item>
+ <item name="android:textSize">14sp</item>
<item name="android:maxLines">1</item>
<item name="android:textColor">?attr/wallpaperTextColor</item>
<item name="android:shadowColor">@color/keyguard_shadow_color</item>
diff --git a/packages/SystemUI/res-product/values-ml/strings.xml b/packages/SystemUI/res-product/values-ml/strings.xml
index 284f55264909..fc322d6110e5 100644
--- a/packages/SystemUI/res-product/values-ml/strings.xml
+++ b/packages/SystemUI/res-product/values-ml/strings.xml
@@ -21,7 +21,7 @@
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 ടിവി ഉടൻ ഓഫാകും, ഓണാക്കി നിർത്താൻ ഒരു ബട്ടൺ അമർത്തുക."</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">"ടാബ്‌ലെറ്റിൽ സിം കാർഡൊന്നുമില്ല."</string>
<string name="keyguard_missing_sim_message" product="default" msgid="7053347843877341391">"ഫോണിൽ സിം കാർഡൊന്നുമില്ല."</string>
diff --git a/packages/SystemUI/res-product/values-mn/strings.xml b/packages/SystemUI/res-product/values-mn/strings.xml
index 6a0f668986f8..0b47eb06da30 100644
--- a/packages/SystemUI/res-product/values-mn/strings.xml
+++ b/packages/SystemUI/res-product/values-mn/strings.xml
@@ -21,7 +21,7 @@
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 TВ төхөөрөмж удахгүй унтрах тул асаалттай хэвээр байлгахын тулд товчлуурыг дарна уу."</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>
diff --git a/packages/SystemUI/res/drawable/bubble_stack_user_education_bg_rtl.xml b/packages/SystemUI/res/drawable/bubble_stack_user_education_bg_rtl.xml
new file mode 100644
index 000000000000..c7baba14b5e5
--- /dev/null
+++ b/packages/SystemUI/res/drawable/bubble_stack_user_education_bg_rtl.xml
@@ -0,0 +1,22 @@
+<!--
+ ~ 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.
+ -->
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="rectangle">
+ <solid android:color="?android:attr/colorAccent"/>
+ <corners
+ android:bottomLeftRadius="360dp"
+ android:topLeftRadius="360dp" />
+</shape>
diff --git a/packages/SystemUI/res/drawable/ic_hardware_speaker.xml b/packages/SystemUI/res/drawable/ic_hardware_speaker.xml
deleted file mode 100644
index 0081e56a45f2..000000000000
--- a/packages/SystemUI/res/drawable/ic_hardware_speaker.xml
+++ /dev/null
@@ -1,24 +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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="18dp"
- android:height="18dp"
- android:viewportWidth="24"
- android:viewportHeight="24">
- <path
- android:pathData="M17,2L7,2c-1.1,0 -2,0.9 -2,2v16c0,1.1 0.9,1.99 2,1.99L17,22c1.1,0 2,-0.9 2,-2L19,4c0,-1.1 -0.9,-2 -2,-2zM7,20L7,4h10v16L7,20zM12,9c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2c-1.11,0 -2,0.9 -2,2s0.89,2 2,2zM12,11c-2.21,0 -4,1.79 -4,4s1.79,4 4,4 4,-1.79 4,-4 -1.79,-4 -4,-4zM12,17c-1.1,0 -2,-0.9 -2,-2s0.9,-2 2,-2 2,0.9 2,2 -0.9,2 -2,2z"
- android:fillColor="#000000"/>
-</vector>
diff --git a/packages/SystemUI/res/layout/auth_biometric_contents.xml b/packages/SystemUI/res/layout/auth_biometric_contents.xml
index 6b61046e0f6c..a87c7b3fa927 100644
--- a/packages/SystemUI/res/layout/auth_biometric_contents.xml
+++ b/packages/SystemUI/res/layout/auth_biometric_contents.xml
@@ -50,8 +50,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="24dp"
- android:paddingTop="16dp"
- android:paddingBottom="24dp"
+ android:paddingVertical="12dp"
android:textSize="12sp"
android:gravity="center_horizontal"
android:accessibilityLiveRegion="polite"
@@ -60,22 +59,23 @@
<LinearLayout
android:id="@+id/button_bar"
android:layout_width="match_parent"
- android:layout_height="72dip"
- android:paddingTop="24dp"
- android:layout_gravity="center_vertical"
+ android:layout_height="88dp"
style="?android:attr/buttonBarStyle"
- android:orientation="horizontal">
+ android:orientation="horizontal"
+ android:paddingTop="16dp">
<Space android:id="@+id/leftSpacer"
- android:layout_width="12dp"
+ android:layout_width="8dp"
android:layout_height="match_parent"
android:visibility="visible" />
<!-- Negative Button -->
<Button android:id="@+id/button_negative"
android:layout_width="wrap_content"
- android:layout_height="match_parent"
+ android:layout_height="wrap_content"
style="@*android:style/Widget.DeviceDefault.Button.Borderless.Colored"
- android:gravity="center"
- android:maxLines="2"/>
+ android:layout_gravity="center_vertical"
+ android:ellipsize="end"
+ android:maxLines="2"
+ android:maxWidth="@dimen/biometric_dialog_button_negative_max_width"/>
<Space android:id="@+id/middleSpacer"
android:layout_width="0dp"
android:layout_height="match_parent"
@@ -84,23 +84,27 @@
<!-- Positive Button -->
<Button android:id="@+id/button_positive"
android:layout_width="wrap_content"
- android:layout_height="match_parent"
+ android:layout_height="wrap_content"
style="@*android:style/Widget.DeviceDefault.Button.Colored"
- android:gravity="center"
+ android:layout_gravity="center_vertical"
+ android:ellipsize="end"
android:maxLines="2"
+ android:maxWidth="@dimen/biometric_dialog_button_positive_max_width"
android:text="@string/biometric_dialog_confirm"
android:visibility="gone"/>
<!-- Try Again Button -->
<Button android:id="@+id/button_try_again"
android:layout_width="wrap_content"
- android:layout_height="match_parent"
+ android:layout_height="wrap_content"
style="@*android:style/Widget.DeviceDefault.Button.Colored"
- android:gravity="center"
+ android:layout_gravity="center_vertical"
+ android:ellipsize="end"
android:maxLines="2"
+ android:maxWidth="@dimen/biometric_dialog_button_positive_max_width"
android:text="@string/biometric_dialog_try_again"
android:visibility="gone"/>
<Space android:id="@+id/rightSpacer"
- android:layout_width="12dip"
+ android:layout_width="8dp"
android:layout_height="match_parent"
android:visibility="visible" />
</LinearLayout>
diff --git a/packages/SystemUI/res/layout/bubble_manage_menu.xml b/packages/SystemUI/res/layout/bubble_manage_menu.xml
index 129282dae77f..84948828bdbe 100644
--- a/packages/SystemUI/res/layout/bubble_manage_menu.xml
+++ b/packages/SystemUI/res/layout/bubble_manage_menu.xml
@@ -32,8 +32,8 @@
android:orientation="horizontal">
<ImageView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_width="24dp"
+ android:layout_height="24dp"
android:src="@drawable/ic_remove_no_shadow"
android:tint="@color/global_actions_text"/>
@@ -57,8 +57,8 @@
android:orientation="horizontal">
<ImageView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_width="24dp"
+ android:layout_height="24dp"
android:src="@drawable/ic_stop_bubble"
android:tint="@color/global_actions_text"/>
diff --git a/packages/SystemUI/res/layout/bubble_stack_user_education.xml b/packages/SystemUI/res/layout/bubble_stack_user_education.xml
index 81b28e612993..616403219bc6 100644
--- a/packages/SystemUI/res/layout/bubble_stack_user_education.xml
+++ b/packages/SystemUI/res/layout/bubble_stack_user_education.xml
@@ -33,7 +33,8 @@
android:layout_height="wrap_content"
android:paddingBottom="16dp"
android:fontFamily="@*android:string/config_bodyFontFamilyMedium"
- android:maxLines="1"
+ android:maxLines="2"
+ android:ellipsize="end"
android:text="@string/bubbles_user_education_title"
android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Headline"/>
@@ -41,6 +42,7 @@
android:id="@+id/user_education_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:ellipsize="end"
android:text="@string/bubbles_user_education_description"
android:fontFamily="@*android:string/config_bodyFontFamily"
android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body2"/>
diff --git a/packages/SystemUI/res/layout/bubbles_manage_button_education.xml b/packages/SystemUI/res/layout/bubbles_manage_button_education.xml
index 7313d54c599a..87dd58e4f0ed 100644
--- a/packages/SystemUI/res/layout/bubbles_manage_button_education.xml
+++ b/packages/SystemUI/res/layout/bubbles_manage_button_education.xml
@@ -31,7 +31,6 @@
android:layout_marginEnd="24dp"
android:orientation="vertical"
android:background="@drawable/bubble_stack_user_education_bg"
- android:alpha="0.9"
>
<TextView
@@ -41,7 +40,8 @@
android:paddingStart="16dp"
android:paddingBottom="16dp"
android:fontFamily="@*android:string/config_bodyFontFamilyMedium"
- android:maxLines="1"
+ android:maxLines="2"
+ android:ellipsize="end"
android:text="@string/bubbles_user_education_manage_title"
android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Headline"/>
@@ -52,12 +52,15 @@
android:paddingStart="16dp"
android:paddingBottom="24dp"
android:text="@string/bubbles_user_education_manage"
+ android:maxLines="2"
+ android:ellipsize="end"
android:fontFamily="@*android:string/config_bodyFontFamily"
android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body2"/>
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="wrap_content"
+ android:id="@+id/button_layout"
android:orientation="horizontal" >
<com.android.systemui.statusbar.AlphaOptimizedButton
@@ -70,7 +73,6 @@
android:clickable="false"
android:text="@string/manage_bubbles_text"
android:textColor="?attr/wallpaperTextColor"
- android:alpha="0.89"
/>
<com.android.systemui.statusbar.AlphaOptimizedButton
@@ -85,4 +87,4 @@
/>
</LinearLayout>
</LinearLayout>
-</com.android.systemui.bubbles.BubbleManageEducationView> \ No newline at end of file
+</com.android.systemui.bubbles.BubbleManageEducationView>
diff --git a/packages/SystemUI/res/layout/controls_management_favorites.xml b/packages/SystemUI/res/layout/controls_management_favorites.xml
index a0d8ae42f584..4850e7534943 100644
--- a/packages/SystemUI/res/layout/controls_management_favorites.xml
+++ b/packages/SystemUI/res/layout/controls_management_favorites.xml
@@ -26,6 +26,8 @@
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/controls_management_list_margin"
android:textAppearance="?android:attr/textAppearanceSmall"
+ android:layout_marginStart="@dimen/controls_management_status_side_margin"
+ android:layout_marginEnd="@dimen/controls_management_status_side_margin"
android:gravity="center_horizontal"
/>
diff --git a/packages/SystemUI/res/layout/global_actions_power_dialog.xml b/packages/SystemUI/res/layout/global_actions_power_dialog.xml
new file mode 100644
index 000000000000..ff3f0fb74cd5
--- /dev/null
+++ b/packages/SystemUI/res/layout/global_actions_power_dialog.xml
@@ -0,0 +1,24 @@
+<!--
+ ~ 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.
+ -->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:divider="@drawable/controls_list_divider"
+ android:showDividers="middle"
+/>
+
diff --git a/packages/SystemUI/res/layout/global_actions_power_item.xml b/packages/SystemUI/res/layout/global_actions_power_item.xml
new file mode 100644
index 000000000000..0d060b63486f
--- /dev/null
+++ b/packages/SystemUI/res/layout/global_actions_power_item.xml
@@ -0,0 +1,45 @@
+<!--
+ ~ 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.
+ -->
+<com.android.systemui.globalactions.GlobalActionsItem
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="@dimen/global_actions_power_dialog_item_width"
+ android:layout_height="@dimen/global_actions_power_dialog_item_height"
+ android:gravity="bottom|center_horizontal"
+ android:orientation="vertical"
+ android:paddingTop="12dp"
+ android:paddingBottom="12dp"
+ android:stateListAnimator="@anim/control_state_list_animator">
+ <ImageView
+ android:id="@*android:id/icon"
+ android:layout_width="24dp"
+ android:layout_height="24dp"
+ android:layout_marginBottom="45dp"
+ android:scaleType="centerInside"
+ android:tint="@color/control_primary_text" />
+ <TextView
+ android:id="@*android:id/message"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:marqueeRepeatLimit="marquee_forever"
+ android:ellipsize="marquee"
+ android:layout_marginBottom="16dp"
+ android:maxLines="1"
+ android:textSize="16sp"
+ android:gravity="center"
+ android:textColor="@color/control_primary_text"
+ android:textAppearance="?android:attr/textAppearanceSmall" />
+</com.android.systemui.globalactions.GlobalActionsItem>
+
diff --git a/packages/SystemUI/res/layout/home_handle.xml b/packages/SystemUI/res/layout/home_handle.xml
index 7c5db105a09e..54a0b9fba39c 100644
--- a/packages/SystemUI/res/layout/home_handle.xml
+++ b/packages/SystemUI/res/layout/home_handle.xml
@@ -21,6 +21,7 @@
android:layout_width="@dimen/navigation_home_handle_width"
android:layout_height="match_parent"
android:layout_weight="0"
+ android:contentDescription="@string/accessibility_home"
android:paddingStart="@dimen/navigation_key_padding"
android:paddingEnd="@dimen/navigation_key_padding"
/>
diff --git a/packages/SystemUI/res/layout/keyguard_bottom_area.xml b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
index b90a3719b08f..04de9784812f 100644
--- a/packages/SystemUI/res/layout/keyguard_bottom_area.xml
+++ b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
@@ -42,6 +42,17 @@
android:textAppearance="@style/TextAppearance.Keyguard.BottomArea"
android:accessibilityLiveRegion="polite"/>
+ <com.android.systemui.statusbar.phone.KeyguardIndicationTextView
+ android:id="@+id/keyguard_indication_enterprise_disclosure"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:paddingStart="@dimen/keyguard_indication_text_padding"
+ android:paddingEnd="@dimen/keyguard_indication_text_padding"
+ android:textAppearance="@style/TextAppearance.Keyguard.BottomArea"
+ android:alpha=".54"
+ android:visibility="gone"/>
+
</LinearLayout>
<FrameLayout
diff --git a/packages/SystemUI/res/layout/media_carousel.xml b/packages/SystemUI/res/layout/media_carousel.xml
index dc917316bef1..ee1173be0db9 100644
--- a/packages/SystemUI/res/layout/media_carousel.xml
+++ b/packages/SystemUI/res/layout/media_carousel.xml
@@ -23,7 +23,7 @@
android:clipChildren="false"
android:clipToPadding="false"
>
- <com.android.systemui.media.UnboundHorizontalScrollView
+ <com.android.systemui.media.MediaScrollView
android:id="@+id/media_carousel_scroller"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -41,14 +41,12 @@
>
<!-- QSMediaPlayers will be added here dynamically -->
</LinearLayout>
- </com.android.systemui.media.UnboundHorizontalScrollView>
+ </com.android.systemui.media.MediaScrollView>
<com.android.systemui.qs.PageIndicator
android:id="@+id/media_page_indicator"
android:layout_width="wrap_content"
android:layout_height="48dp"
android:layout_marginBottom="4dp"
- android:layout_gravity="center_horizontal|bottom"
- android:gravity="center"
android:tint="@color/media_primary_text"
/>
</FrameLayout>
diff --git a/packages/SystemUI/res/layout/media_carousel_settings_button.xml b/packages/SystemUI/res/layout/media_carousel_settings_button.xml
new file mode 100644
index 000000000000..4570cb1d1d10
--- /dev/null
+++ b/packages/SystemUI/res/layout/media_carousel_settings_button.xml
@@ -0,0 +1,29 @@
+<?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.
+ -->
+<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/settings_cog"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:contentDescription="@string/controls_media_settings_button"
+ android:paddingStart="30dp"
+ android:paddingEnd="30dp"
+ android:paddingBottom="20dp"
+ android:paddingTop="20dp"
+ android:src="@drawable/ic_settings"
+ android:tint="@color/notification_gear_color"
+ android:visibility="invisible"
+ android:forceHasOverlappingRendering="false"/>
diff --git a/packages/SystemUI/res/layout/media_view.xml b/packages/SystemUI/res/layout/media_view.xml
index a722fbfce19a..07bbb8f40eb8 100644
--- a/packages/SystemUI/res/layout/media_view.xml
+++ b/packages/SystemUI/res/layout/media_view.xml
@@ -26,6 +26,7 @@
android:gravity="center_horizontal|fill_vertical"
android:background="@drawable/qs_media_background">
+ <!-- As per Material Design on Biderectionality, this is forced to LTR in code -->
<FrameLayout
android:id="@+id/notification_media_progress_time"
android:layout_width="0dp"
@@ -36,7 +37,7 @@
android:id="@+id/media_elapsed_time"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_alignParentLeft="true"
+ android:layout_alignParentStart="true"
android:fontFamily="@*android:string/config_bodyFontFamily"
android:textColor="@color/media_primary_text"
android:gravity="start"
@@ -46,13 +47,36 @@
android:id="@+id/media_total_time"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
+ android:layout_alignParentEnd="true"
android:fontFamily="@*android:string/config_bodyFontFamily"
android:textColor="@color/media_primary_text"
android:gravity="end"
android:textSize="14sp" />
</FrameLayout>
+ <!-- Actions must be ordered left-to-right even in RTL layout. However, they appear in a chain
+ with the album art and the title, and must as a group appear at the end of that chain. This is
+ accomplished by having the guidebox (an invisible view that is positioned around all 5 actions)
+ in the chain with the album art and the title. The actions are in a LTR chain bounded by that
+ guidebox, and the ambiguity of how wide the guidebox should be is resolved by using a barrier
+ which forces it's starting edge to be as far to the end as possible while fitting the actions.
+ -->
+ <androidx.constraintlayout.widget.Barrier
+ android:id="@+id/media_action_barrier"
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:orientation="vertical"
+ app:barrierDirection="start"
+ />
+
+ <View
+ android:id="@+id/media_action_guidebox"
+ android:layout_width="0dp"
+ android:layout_height="48dp"
+ android:layout_marginTop="16dp"
+ android:visibility="invisible"
+ />
+
<ImageButton
android:id="@+id/action0"
style="@style/MediaPlayer.Button"
@@ -94,20 +118,20 @@
android:id="@+id/media_seamless"
android:layout_width="0dp"
android:layout_height="wrap_content"
- android:foreground="@*android:drawable/media_seamless_background"
+ android:foreground="@drawable/qs_media_seamless_background"
android:background="@drawable/qs_media_light_source"
android:orientation="horizontal"
android:forceHasOverlappingRendering="false"
- android:paddingLeft="12dp"
+ android:paddingStart="12dp"
android:paddingTop="6dp"
- android:paddingRight="12dp"
+ android:paddingEnd="12dp"
android:paddingBottom="6dp">
<ImageView
android:id="@+id/media_seamless_image"
android:layout_width="@dimen/qs_seamless_icon_size"
android:layout_height="@dimen/qs_seamless_icon_size"
- android:layout_marginRight="8dp"
+ android:layout_marginEnd="8dp"
android:tint="@color/media_primary_text"
android:src="@*android:drawable/ic_media_seamless" />
@@ -115,21 +139,40 @@
android:id="@+id/media_seamless_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:fontFamily="@*android:string/config_bodyFontFamily"
+ android:fontFamily="@*android:string/config_headlineFontFamily"
android:singleLine="true"
android:text="@*android:string/ext_media_seamless_action"
android:textColor="@color/media_primary_text"
+ android:textDirection="locale"
android:textSize="14sp" />
</LinearLayout>
+ <ImageView
+ android:id="@+id/media_seamless_fallback"
+ android:layout_width="@dimen/qs_seamless_icon_size"
+ android:layout_height="@dimen/qs_seamless_icon_size"
+ android:tint="@color/media_primary_text"
+ android:src="@drawable/ic_cast_connected"
+ android:forceHasOverlappingRendering="false" />
+
+ <androidx.constraintlayout.widget.Barrier
+ android:id="@+id/media_seamless_barrier"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ app:barrierDirection="start"
+ app:constraint_referenced_ids="media_seamless,media_seamless_fallback"
+ app:barrierAllowsGoneWidgets="false"
+ />
+
<!-- Seek Bar -->
+ <!-- As per Material Design on Biderectionality, this is forced to LTR in code -->
<SeekBar
android:id="@+id/media_progress_bar"
style="@android:style/Widget.ProgressBar.Horizontal"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:clickable="true"
- android:maxHeight="3dp"
+ android:maxHeight="@dimen/qs_media_enabled_seekbar_height"
android:paddingTop="16dp"
android:paddingBottom="16dp"
android:thumbTint="@color/media_primary_text"
@@ -144,6 +187,8 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:singleLine="true"
+ android:fontFamily="@*android:string/config_headlineFontFamily"
+ android:textDirection="locale"
android:textSize="14sp" />
<!-- Song name -->
@@ -154,23 +199,25 @@
android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
android:singleLine="true"
android:textColor="@color/media_primary_text"
- android:textSize="18sp" />
+ android:textDirection="locale"
+ android:textSize="16sp" />
<!-- Artist name -->
<TextView
android:id="@+id/header_artist"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:fontFamily="@*android:string/config_bodyFontFamily"
+ android:fontFamily="@*android:string/config_headlineFontFamily"
android:singleLine="true"
- android:textColor="@color/media_primary_text"
+ android:textColor="@color/media_secondary_text"
+ android:textDirection="locale"
android:textSize="14sp" />
<com.android.internal.widget.CachingIconView
android:id="@+id/icon"
android:tint="@color/media_primary_text"
- android:layout_width="16dp"
- android:layout_height="16dp" />
+ android:layout_width="20dp"
+ android:layout_height="20dp" />
<!-- Buttons to remove this view when no longer needed -->
<include
diff --git a/packages/SystemUI/res/layout/qs_panel.xml b/packages/SystemUI/res/layout/qs_panel.xml
index 761ab03ee87e..597644bf3295 100644
--- a/packages/SystemUI/res/layout/qs_panel.xml
+++ b/packages/SystemUI/res/layout/qs_panel.xml
@@ -62,6 +62,8 @@
android:focusable="true"
android:accessibilityTraversalBefore="@android:id/edit">
<include layout="@layout/qs_footer_impl" />
+ <include layout="@layout/qs_media_divider"
+ android:id="@+id/divider"/>
</com.android.systemui.qs.QSPanel>
</com.android.systemui.qs.NonInterceptingScrollView>
diff --git a/packages/SystemUI/res/layout/screen_record_dialog.xml b/packages/SystemUI/res/layout/screen_record_dialog.xml
index fd9936f6b8ea..acef94315e91 100644
--- a/packages/SystemUI/res/layout/screen_record_dialog.xml
+++ b/packages/SystemUI/res/layout/screen_record_dialog.xml
@@ -20,111 +20,126 @@
android:orientation="vertical"
android:background="@drawable/rounded_bg_full">
- <!-- Header -->
- <LinearLayout
+ <!-- Scrollview is necessary to fit everything in landscape layout -->
+ <ScrollView
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical"
- android:gravity="center"
- android:padding="@dimen/screenrecord_dialog_padding">
- <ImageView
- android:layout_width="@dimen/screenrecord_logo_size"
- android:layout_height="@dimen/screenrecord_logo_size"
- android:src="@drawable/ic_screenrecord"
- android:tint="@color/GM2_red_500"
- android:layout_marginBottom="@dimen/screenrecord_dialog_padding"/>
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textAppearance="?android:attr/textAppearanceLarge"
- android:text="@string/screenrecord_start_label"/>
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/screenrecord_description"
- android:textAppearance="?android:attr/textAppearanceSmall"
- android:paddingTop="@dimen/screenrecord_dialog_padding"
- android:paddingBottom="@dimen/screenrecord_dialog_padding"/>
+ android:layout_height="wrap_content">
- <!-- Options -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:orientation="horizontal">
- <ImageView
- android:layout_width="@dimen/screenrecord_logo_size"
- android:layout_height="@dimen/screenrecord_logo_size"
- android:src="@drawable/ic_mic_26dp"
- android:tint="@color/GM2_grey_700"
- android:layout_gravity="center"
- android:layout_weight="0"
- android:layout_marginRight="@dimen/screenrecord_dialog_padding"/>
- <Spinner
- android:id="@+id/screen_recording_options"
- android:layout_width="wrap_content"
- android:layout_height="48dp"
- android:prompt="@string/screenrecord_audio_label"/>
- <Switch
- android:layout_width="wrap_content"
- android:layout_height="48dp"
- android:layout_weight="1"
- android:layout_gravity="end"
- android:id="@+id/screenrecord_audio_switch"/>
- </LinearLayout>
+ android:orientation="vertical">
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal">
- <ImageView
- android:layout_width="@dimen/screenrecord_logo_size"
- android:layout_height="@dimen/screenrecord_logo_size"
- android:src="@drawable/ic_touch"
- android:tint="@color/GM2_grey_700"
- android:layout_gravity="center"
- android:layout_marginRight="@dimen/screenrecord_dialog_padding"/>
- <Switch
+ <!-- Header -->
+ <LinearLayout
android:layout_width="match_parent"
- android:layout_height="48dp"
- android:id="@+id/screenrecord_taps_switch"
- android:text="@string/screenrecord_taps_label"
- android:textColor="?android:attr/textColorPrimary"
- android:textAppearance="?android:attr/textAppearanceSmall"/>
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:gravity="center"
+ android:padding="@dimen/screenrecord_dialog_padding">
+ <ImageView
+ android:layout_width="@dimen/screenrecord_logo_size"
+ android:layout_height="@dimen/screenrecord_logo_size"
+ android:src="@drawable/ic_screenrecord"
+ android:tint="@color/GM2_red_500"
+ android:layout_marginBottom="@dimen/screenrecord_dialog_padding"/>
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceLarge"
+ android:text="@string/screenrecord_start_label"/>
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/screenrecord_description"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:paddingTop="@dimen/screenrecord_dialog_padding"
+ android:paddingBottom="@dimen/screenrecord_dialog_padding"/>
- </LinearLayout>
- </LinearLayout>
+ <!-- Options -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+ <ImageView
+ android:layout_width="@dimen/screenrecord_logo_size"
+ android:layout_height="@dimen/screenrecord_logo_size"
+ android:src="@drawable/ic_mic_26dp"
+ android:tint="@color/GM2_grey_700"
+ android:layout_gravity="center"
+ android:layout_weight="0"
+ android:layout_marginRight="@dimen/screenrecord_dialog_padding"/>
+ <Spinner
+ android:id="@+id/screen_recording_options"
+ android:layout_width="0dp"
+ android:layout_height="48dp"
+ android:layout_weight="1"
+ android:prompt="@string/screenrecord_audio_label"/>
+ <Switch
+ android:layout_width="wrap_content"
+ android:minWidth="48dp"
+ android:layout_height="48dp"
+ android:layout_weight="0"
+ android:layout_gravity="end"
+ android:contentDescription="@string/screenrecord_audio_label"
+ android:id="@+id/screenrecord_audio_switch"/>
+ </LinearLayout>
- <!-- hr -->
- <View
- android:layout_width="match_parent"
- android:layout_height="1dp"
- android:background="@color/GM2_grey_300"/>
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+ <ImageView
+ android:layout_width="@dimen/screenrecord_logo_size"
+ android:layout_height="@dimen/screenrecord_logo_size"
+ android:src="@drawable/ic_touch"
+ android:tint="@color/GM2_grey_700"
+ android:layout_gravity="center"
+ android:layout_marginRight="@dimen/screenrecord_dialog_padding"/>
+ <Switch
+ android:layout_width="match_parent"
+ android:layout_height="48dp"
+ android:id="@+id/screenrecord_taps_switch"
+ android:text="@string/screenrecord_taps_label"
+ android:textColor="?android:attr/textColorPrimary"
+ android:textAppearance="?android:attr/textAppearanceSmall"/>
- <!-- Buttons -->
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- android:padding="@dimen/screenrecord_dialog_padding">
- <Button
- android:id="@+id/button_cancel"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_weight="0"
- android:layout_gravity="start"
- android:text="@string/cancel"
- style="@android:style/Widget.DeviceDefault.Button.Borderless.Colored"/>
- <Space
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="1"/>
- <Button
- android:id="@+id/button_start"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_weight="0"
- android:layout_gravity="end"
- android:text="@string/screenrecord_start"
- style="@android:style/Widget.DeviceDefault.Button.Colored"/>
- </LinearLayout>
+ </LinearLayout>
+ </LinearLayout>
+
+ <!-- hr -->
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dp"
+ android:background="@color/GM2_grey_300"/>
+
+ <!-- Buttons -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:padding="@dimen/screenrecord_dialog_padding">
+ <Button
+ android:id="@+id/button_cancel"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:layout_weight="0"
+ android:layout_gravity="start"
+ android:text="@string/cancel"
+ style="@android:style/Widget.DeviceDefault.Button.Borderless.Colored"/>
+ <Space
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="1"/>
+ <Button
+ android:id="@+id/button_start"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:layout_weight="0"
+ android:layout_gravity="end"
+ android:text="@string/screenrecord_start"
+ style="@android:style/Widget.DeviceDefault.Button.Colored"/>
+ </LinearLayout>
+ </LinearLayout>
+ </ScrollView>
</LinearLayout> \ No newline at end of file
diff --git a/packages/SystemUI/res/layout/tv_audio_recording_indicator.xml b/packages/SystemUI/res/layout/tv_audio_recording_indicator.xml
index cd90efe9a215..1d2340dadb8a 100644
--- a/packages/SystemUI/res/layout/tv_audio_recording_indicator.xml
+++ b/packages/SystemUI/res/layout/tv_audio_recording_indicator.xml
@@ -45,7 +45,7 @@
android:id="@+id/icon_mic"
android:layout_width="35dp"
android:layout_height="35dp"
- android:layout_marginLeft="6dp"
+ android:layout_marginStart="6dp"
android:layout_marginTop="6dp"
android:layout_marginBottom="6dp">
@@ -112,7 +112,7 @@
</FrameLayout>
<View
- android:id="@+id/bg_right"
+ android:id="@+id/bg_end"
android:layout_width="12dp"
android:layout_height="47dp"
android:background="@drawable/tv_rect_dark_right_rounded"
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 48b25b0773e4..bdff23560d52 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -454,8 +454,8 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Tik weer om oop te maak"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Swiep op om oop te maak"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Swiep op om weer te probeer"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"Jou organisasie bestuur hierdie toestel"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"Hierdie toestel word deur <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> bestuur"</string>
+ <string name="do_disclosure_generic" msgid="4896482821974707167">"Hierdie toestel behoort aan jou organisasie"</string>
+ <string name="do_disclosure_with_name" msgid="2091641464065004091">"Hierdie toestel behoort aan <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="6682125338461375925">"Swiep vanaf ikoon vir foon"</string>
<string name="voice_hint" msgid="7476017460191291417">"Swiep vanaf ikoon vir stembystand"</string>
<string name="camera_hint" msgid="4519495795000658637">"Swiep vanaf ikoon vir kamera"</string>
@@ -521,21 +521,21 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"Profiel kan gemonitor word"</string>
<string name="vpn_footer" msgid="3457155078010607471">"Netwerk kan dalk gemonitor word"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"Netwerk kan dalk gemonitor word"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"Jou organisasie bestuur hierdie toestel en kan netwerkverkeer monitor"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> bestuur hierdie toestel en kan netwerkverkeer monitor"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"Toestel word deur jou organisasie bestuur en is aan <xliff:g id="VPN_APP">%1$s</xliff:g> gekoppel"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"Toestel word deur <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> bestuur en is aan <xliff:g id="VPN_APP">%2$s</xliff:g> gekoppel"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"Toestel word deur jou organisasie bestuur"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"Toestel word deur <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> bestuur"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"Toestel word deur jou organisasie bestuur en is aan VPN\'e gekoppel"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"Toestel word deur <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> bestuur en is aan VPN\'e gekoppel"</string>
+ <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Jou organisasie besit hierdie toestel en kan netwerkverkeer monitor"</string>
+ <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> besit hierdie toestel en kan netwerkverkeer monitor"</string>
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Hierdie toestel behoort aan jou organisasie en is gekoppel aan <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Hierdie toestel behoort aan <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> en is gekoppel aan <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Hierdie toestel behoort aan jou organisasie"</string>
+ <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Hierdie toestel behoort aan <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management_vpns" msgid="371835422690053154">"Hierdie toestel behoort aan jou organisasie en is gekoppel aan VPN\'e"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="4046375645500668555">"Hierdie toestel behoort aan <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> en is gekoppel aan VPN\'e"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Jou organisasie kan netwerkverkeer in jou werkprofiel monitor"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> kan netwerkverkeer in jou werkprofiel monitor"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Netwerk kan gemonitor word"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"Toestel is aan VPN\'e gekoppel"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"Werkprofiel is gekoppel aan <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"Persoonlike profiel is aan <xliff:g id="VPN_APP">%1$s</xliff:g> gekoppel"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"Toestel is aan <xliff:g id="VPN_APP">%1$s</xliff:g> gekoppel"</string>
+ <string name="quick_settings_disclosure_vpns" msgid="7213546797022280246">"Hierdie toestel is gekoppel aan VPN\'e"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Jou werkprofiel is gekoppel aan <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Jou persoonlike profiel is gekoppel aan <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Hierdie toestel is gekoppel aan <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Toestelbestuur"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Profielmonitering"</string>
<string name="monitoring_title" msgid="4063890083735924568">"Netwerkmonitering"</string>
@@ -545,8 +545,8 @@
<string name="disable_vpn" msgid="482685974985502922">"Deaktiveer VPN"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"Ontkoppel VPN"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"Bekyk beleide"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"Jou toestel word deur <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> bestuur.\n\nJou administrateur kan instellings, korporatiewe toegang, programme, data wat met jou toestel geassosieer word en jou toestel se ligginginligting monitor en bestuur.\n\nVir meer inligting, kontak jou administrateur."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"Jou toestel word deur jou organisasie bestuur.\n\nJou administrateur kan instellings, korporatiewe toegang, programme, data wat met jou toestel geassosieer word en jou toestel se ligginginligting monitor en bestuur.\n\nVir meer inligting, kontak jou administrateur."</string>
+ <string name="monitoring_description_named_management" msgid="505833016545056036">"Hierdie toestel behoort aan <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nJou IT-admin kan instellings, korporatiewe toegang, programme, data wat met jou toestel geassosieer word, en jou toestel se ligginginligting monitor en bestuur.\n\nKontak jou IT-admin vir meer inligting."</string>
+ <string name="monitoring_description_management" msgid="4308879039175729014">"Hierdie toestel behoort aan jou organisasie.\n\nJou IT-admin kan instellings, korporatiewe toegang, programme, data wat met jou toestel geassosieer word, en jou toestel se ligginginligting monitor en bestuur.\n\nKontak jou IT-admin vir meer inligting."</string>
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Jou organisasie het \'n sertifikaatoutoriteit op hierdie toestel geïnstalleer. Jou veilige netwerkverkeer kan gemonitor of gewysig word."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Jou organisasie het \'n sertifikaatoutoriteit in jou werkprofiel geïnstalleer. Jou veilige netwerkverkeer kan gemonitor of gewysig word."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"\'n Sertifikaatoutoriteit is op hierdie toestel geïnstalleer. Jou veilige netwerkverkeer kan gemonitor of gewysig word."</string>
@@ -920,6 +920,7 @@
<string name="pip_pause" msgid="1139598607050555845">"Laat wag"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"Slaan oor na volgende"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"Slaan oor na vorige"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"Verander grootte"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"Foon afgeskakel weens hitte"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"Jou foon werk nou normaal"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Jou foon was te warm en dit het afgeskakel om af te koel. Jou foon werk nou normaal.\n\nJou foon kan dalk te warm word as jy:\n • Hulpbron-intensiewe programme (soos dobbel-, video- of navigasieprogramme) gebruik\n • Groot lêers af- of oplaai\n • Jou foon in hoë temperature gebruik"</string>
@@ -1013,10 +1014,10 @@
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Stelselnavigasie is opgedateer. Gaan na Instellings toe om veranderinge te maak."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Gaan na Instellings toe om stelselnavigasie op te dateer"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Bystandmodus"</string>
- <string name="priority_onboarding_title" msgid="2893070698479227616">"Gesprek is op prioriteit gestel"</string>
+ <string name="priority_onboarding_title" msgid="2893070698479227616">"Gesprek is as prioriteit gestel"</string>
<string name="priority_onboarding_behavior" msgid="5342816047020432929">"Prioriteitgesprekke sal:"</string>
- <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Wys boaan gespreksafdeling"</string>
- <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Wys profielprent op slotskerm"</string>
+ <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Boaan gespreksafdeling wys"</string>
+ <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Profielprent op slotskerm wys"</string>
<string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Verskyn as \'n swewende borrel bo-oor programme"</string>
<string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Onderbreek Moenie Steur Nie"</string>
<string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Het dit"</string>
@@ -1045,7 +1046,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Hou en sleep om kontroles te herrangskik"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"Alle kontroles is verwyder"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Veranderinge is nie gestoor nie"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"Die lys met alle kontroles kon nie gelaai word nie."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"Kontroles kon nie gelaai word nie. Gaan die <xliff:g id="APP">%s</xliff:g>-program na om seker te maak dat die programinstellings nie verander het nie."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"Versoenbare kontroles is nie beskikbaar nie"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Ander"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"Voeg by toestelkontroles"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"Voeg by"</string>
@@ -1061,8 +1063,11 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"Bevestig verandering vir <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Swiep om meer te sien"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Laai tans aanbevelings"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"Maak hierdie mediasessie toe"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"Media"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"Versteek die huidige sessie."</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Versteek"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Hervat"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"Instellings"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Onaktief, gaan program na"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Fout, probeer tans weer …"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Nie gekry nie"</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 9a75c1c0879c..d4c2380bbe43 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -454,8 +454,10 @@
<string name="notification_tap_again" msgid="4477318164947497249">"ለመክፈት ዳግም መታ ያድርጉ"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"ለመክፈት በጣት ወደ ላይ ጠረግ ያድርጉ"</string>
<string name="keyguard_retry" msgid="886802522584053523">"እንደገና ለመሞከር ወደ ላይ ይጥረጉ"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"ይህ መሣሪያ በእርስዎ ድርጅት የሚተዳደር ነው"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"ይህ መሣሪያ በ<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> የሚተዳደር ነው"</string>
+ <!-- no translation found for do_disclosure_generic (4896482821974707167) -->
+ <skip />
+ <!-- no translation found for do_disclosure_with_name (2091641464065004091) -->
+ <skip />
<string name="phone_hint" msgid="6682125338461375925">"ለስልክ ከአዶ ላይ ጠረግ ያድርጉ"</string>
<string name="voice_hint" msgid="7476017460191291417">"ለድምጽ ረዳት ከአዶ ጠረግ ያድርጉ"</string>
<string name="camera_hint" msgid="4519495795000658637">"ለካሜራ ከአዶ ላይ ጠረግ ያድርጉ"</string>
@@ -521,21 +523,33 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"መገለጫ ክትትል ሊደረግበት ይችላል"</string>
<string name="vpn_footer" msgid="3457155078010607471">"አውታረ መረብ በክትትል እየተደረገበት ሊሆን ይችላል"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"አውታረ መረብ ክትትል የሚደረግበት ሊሆን ይችላል"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"የእርስዎ ድርጅት ይህን መሣሪያ ያስተዳድራል፣ እና የአውታረ መረብ ትራፊክን ሊከታተል ይችላል"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ይህን መሣሪያ ያስተዳድራል፣ እና የአውታረ መረብ ትራፊክን ሊከታተል ይችላል"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"ይህ መሣሪያ በእርስዎ ድርጅት የሚተዳደር ሲሆን ከ<xliff:g id="VPN_APP">%1$s</xliff:g> ጋር ተገናኝቷል"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"ይህ መሣሪያ በ<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> የሚተዳደር ሲሆን ወደ <xliff:g id="VPN_APP">%2$s</xliff:g> ተገናኝቷል"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"መሣሪያ በእርስዎ ድርጅት የሚተዳደር ነው"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"ይህ መሣሪያ በ<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> የሚተዳደር ነው"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"ይህ መሣሪያ በእርስዎ ድርጅት የሚተዳደር ሲሆን ወደ VPNዎች ተገናኝቷል።"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"ይህ መሣሪያ በ<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> የሚተዳደር ሲሆን ወደ VPNዎች ተገናኝቷል"</string>
+ <!-- no translation found for quick_settings_disclosure_management_monitoring (8231336875820702180) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_monitoring (2831423806103479812) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_named_vpn (6096715329056415588) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (5302786161534380104) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management (5515296598440684962) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management (3476472755775165827) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_vpns (371835422690053154) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_vpns (4046375645500668555) -->
+ <skip />
<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_monitoring" msgid="8548019955631378680">"አውታረ መረብ ክትትል የሚደረግበት ሊሆን ይችላል"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"ይህ መሣሪያ ወደ VPNዎች ተገናኝቷል"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"የሥራ መገለጫ ወደ <xliff:g id="VPN_APP">%1$s</xliff:g> ተገናኝቷል"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"የግል መገለጫ ወደ <xliff:g id="VPN_APP">%1$s</xliff:g> ተገናኝቷል"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"ይህ መሣሪያ ወደ <xliff:g id="VPN_APP">%1$s</xliff:g> ተገናኝቷል"</string>
+ <!-- no translation found for quick_settings_disclosure_vpns (7213546797022280246) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (8117568745060010789) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (5481763430080807797) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_vpn (2350838218824492465) -->
+ <skip />
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"የመሣሪያ አስተዳደር"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"መገለጫን መከታተል"</string>
<string name="monitoring_title" msgid="4063890083735924568">"የአውታረ መረብ ክትትል"</string>
@@ -545,8 +559,10 @@
<string name="disable_vpn" msgid="482685974985502922">"VPN አሰናክል"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"የVPN ግንኙነት አቋርጥ"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"መመሪያዎችን ይመልከቱ"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"የእርስዎ መሣሪያ በ<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> የሚተዳደር ነው።\n\nየእርስዎ አስተዳዳሪ ከመሣሪያዎ ጋር የተጎዳኙ ቅንብሮችን፣ የኮርፖሬት መዳረሻን፣ መተግበሪያዎችን እና የመሣሪያዎን የአካባቢ መረጃ መከታተል እና ማቀናበር ይችላሉ።\n\nተጨማሪ መረጃ ለማግኘት አስተዳዳሪዎን ያነጋግሩ።"</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"የእርስዎ መሣሪያ በድርጅትዎ የሚተዳደር ነው።\n\nየእርስዎ አስተዳዳሪ ከመሣሪያዎ ጋር የተጎዳኙ ቅንብሮችን፣ የኮርፖሬት መዳረሻንና ውሂብን እና የመሣሪያዎን የአካባቢ መረጃ መከታተል እና ማቀናበር ይችላሉ።\n\nተጨማሪ መረጃ ለማግኘት አስተዳዳሪዎን ያነጋግሩ።"</string>
+ <!-- no translation found for monitoring_description_named_management (505833016545056036) -->
+ <skip />
+ <!-- no translation found for monitoring_description_management (4308879039175729014) -->
+ <skip />
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"የእርስዎ ድርጅት የእውቅና ማረጋገጫ ሰጪ ባለሥልጣን በዚህ መሣሪያ ላይ ጭኗል። የእርስዎ ደኅንነቱ የተጠበቀ አውታረ መረብ ትራፊክ ክትትል ሊደረግበት እና ሊሻሻል ይችላል።"</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"የእርስዎ ድርጅት የእውቅና ማረጋገጫ ሰጪ ባለሥልጣን በእርስዎ የሥራ መገለጫ ላይ ጭኗል። የእርስዎ ደኅንነቱ የተጠበቀ አውታረ መረብ ትራፊክ ክትትል ሊደረግበት እና ሊሻሻል ይችላል።"</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"የእውቅና ማረጋገጫ ሰጪ ባለሥልጣን በዚህ መሣሪያ ላይ ተጭኗል። የእርስዎ ደኅንነቱ የተጠበቀ አውታረ መረብ ትራፊክ ክትትል ሊደረግበት እና ሊሻሻል ይችላል።"</string>
@@ -920,6 +936,7 @@
<string name="pip_pause" msgid="1139598607050555845">"ባለበት አቁም"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"ወደ ቀጣይ ዝለል"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"ወደ ቀዳሚ ዝለል"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"መጠን ይቀይሩ"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"ስልክ በሙቀት ምክንያት ጠፍቷል"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"የእርስዎ ስልክ አሁን በመደበኝነት እያሄደ ነው"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"የእርስዎ ስልክ በጣም ግሎ ነበር፣ ስለዚህ እንዲቀዘቅዝ ጠፍቷል። የእርስዎ ስልክ አሁን በመደበኝነት እያሄደ ነው።\n\nየሚከተሉትን ካደረጉ የእርስዎ በጣም ሊግል ይችላል፦\n • ኃይል በጣም የሚጠቀሙ መተግበሪያዎችን (እንደ ጨዋታ፣ ቪዲዮ ወይም የአሰሳ መተግበሪያዎች ያሉ) ከተጠቀሙ\n • ትላልቅ ፋይሎችን ካወረዱ ወይም ከሰቀሉ\n • ስልክዎን በከፍተኛ ሙቀት ውስጥ ከተጠቀሙ"</string>
@@ -1045,7 +1062,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"መቆጣጠሪያዎችን ዳግም ለማስተካከል ይያዙ እና ይጎትቱ"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"ሁሉም መቆጣጠሪያዎች ተወግደዋል"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"ለውጦች አልተቀመጡም"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"የሁሉም መቆጣጠሪያዎች ዝርዝር ሊጫን አልተቻለም።"</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"መቆጣጠሪያዎች ሊጫኑ አልቻሉም። የመተግበሪያው ቅንብሮች እንዳልተቀየሩ ለማረጋገጥ <xliff:g id="APP">%s</xliff:g> መተግበሪያን ይፈትሹ።"</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"ተኳዃኝ መቆጣጠሪያዎች አይገኙም"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"ሌላ"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"ወደ የመሣሪያ መቆጣጠሪያዎች ያክሉ"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"አክል"</string>
@@ -1061,8 +1079,11 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"ለ<xliff:g id="DEVICE">%s</xliff:g> ለውጥን ያረጋግጡ"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"ተጨማሪ ለማየት ያንሸራትቱ"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"ምክሮችን በመጫን ላይ"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"ይህን የሚዲያ ክፍለ-ጊዜ ዝጋ"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"ሚዲያ"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"የአሁኑን ክፍለ-ጊዜ ደብቅ።"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"ደብቅ"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"ከቆመበት ቀጥል"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"ቅንብሮች"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"ንቁ ያልኾነ፣ መተግበሪያን ይፈትሹ"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"ስህተት፣ እንደገና በመሞከር ላይ…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"አልተገኘም"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index bfa21071d815..806408af4d75 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -462,8 +462,10 @@
<string name="notification_tap_again" msgid="4477318164947497249">"انقر مرة أخرى للفتح"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"يمكنك الفتح بالتمرير سريعًا لأعلى."</string>
<string name="keyguard_retry" msgid="886802522584053523">"مرِّر سريعًا للأعلى لإعادة المحاولة."</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"تتولى مؤسستك إدارة هذا الجهاز."</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"تتم إدارة هذا الجهاز بواسطة <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for do_disclosure_generic (4896482821974707167) -->
+ <skip />
+ <!-- no translation found for do_disclosure_with_name (2091641464065004091) -->
+ <skip />
<string name="phone_hint" msgid="6682125338461375925">"يمكنك التمرير سريعًا من الرمز لتشغيل الهاتف"</string>
<string name="voice_hint" msgid="7476017460191291417">"يمكنك التمرير سريعًا من الرمز لتشغيل المساعد الصوتي"</string>
<string name="camera_hint" msgid="4519495795000658637">"يمكنك التمرير سريعًا من الرمز لتشغيل الكاميرا"</string>
@@ -533,21 +535,33 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"ربما تتم مراقبة الملف الشخصي"</string>
<string name="vpn_footer" msgid="3457155078010607471">"قد تكون الشبكة خاضعة للمراقبة"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"قد تكون الشبكة خاضعة للمراقبة"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"تدير مؤسستك هذا الجهاز ويمكنها مراقبة حركة بيانات الشبكة"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"تدير <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> هذا الجهاز ويمكنها مراقبة حركة بيانات الشبكة"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"يخضع الجهاز لإدارة مؤسستك وتم ربطه بـ <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"يخضع الجهاز لإدارة <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> وتم ربطه بـ <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"يخضع الجهاز لإدارة مؤسستك"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"تتم إدارة هذا الجهاز بواسطة <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"يخضع الجهاز لإدارة مؤسستك وتم ربطه بالشبكات الافتراضية الخاصة"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"يخضع الجهاز لإدارة <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> وتم ربطه بالشبكات الافتراضية الخاصة"</string>
+ <!-- no translation found for quick_settings_disclosure_management_monitoring (8231336875820702180) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_monitoring (2831423806103479812) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_named_vpn (6096715329056415588) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (5302786161534380104) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management (5515296598440684962) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management (3476472755775165827) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_vpns (371835422690053154) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_vpns (4046375645500668555) -->
+ <skip />
<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_monitoring" msgid="8548019955631378680">"قد تكون الشبكة خاضعة للمراقبة"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"تم ربط الجهاز بالشبكات الافتراضية الخاصة"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"تم ربط الملف الشخصي للعمل بـ <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"تم ربط الملف الشخصي بـ <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"تم ربط الجهاز بـ <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <!-- no translation found for quick_settings_disclosure_vpns (7213546797022280246) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (8117568745060010789) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (5481763430080807797) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_vpn (2350838218824492465) -->
+ <skip />
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"إدارة الأجهزة"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"مراقبة الملف الشخصي"</string>
<string name="monitoring_title" msgid="4063890083735924568">"مراقبة الشبكات"</string>
@@ -557,8 +571,10 @@
<string name="disable_vpn" msgid="482685974985502922">"إيقاف الشبكة الافتراضية الخاصة"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"‏قطع الاتصال بشبكة VPN"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"عرض السياسات"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"تتم إدارة جهازك بواسطة <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nيمكن للمشرف مراقبة وإدارة الإعدادات والدخول إلى المؤسسة والتطبيقات والبيانات المرتبطة بجهازك ومعلومات الموقع الجغرافي للجهاز.\n\nللحصول على المزيد من المعلومات، اتصل بالمشرف."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"تتم إدارة جهازك بواسطة المؤسسة.\n\nيمكن للمشرف مراقبة وإدارة الإعدادات والدخول إلى المؤسسة والتطبيقات والبيانات المرتبطة بجهازك ومعلومات الموقع الجغرافي للجهاز.\n\nللحصول على المزيد من المعلومات، اتصل بالمشرف."</string>
+ <!-- no translation found for monitoring_description_named_management (505833016545056036) -->
+ <skip />
+ <!-- no translation found for monitoring_description_management (4308879039175729014) -->
+ <skip />
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"ثبّتت مؤسستك مرجعًا مصدّقًا على هذا الجهاز. قد تتم مراقبة حركة بيانات شبكتك الآمنة أو تعديلها."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"ثبّتت مؤسستك مرجعًا مصدّقًا في ملفك الشخصي للعمل. قد تتم مراقبة حركة بيانات شبكتك الآمنة أو تعديلها."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"تم تثبيت مرجع مصدّق على هذا الجهاز. قد تتم مراقبة حركة بيانات شبكتك الآمنة أو تعديلها."</string>
@@ -940,6 +956,7 @@
<string name="pip_pause" msgid="1139598607050555845">"إيقاف مؤقت"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"التخطي إلى التالي"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"التخطي إلى السابق"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"تغيير الحجم"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"تم إيقاف الهاتف بسبب الحرارة"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"يعمل هاتفك الآن بشكل طبيعي"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"ارتفعت درجة حرارة هاتفك بشدة، لذا تم إيقاف تشغيله لخفض درجة حرارته. يعمل هاتفك الآن بشكل طبيعي.\n\nقد ترتفع بشدة درجة حرارة هاتفك إذا:\n • استخدمت تطبيقات كثيفة الاستخدام لموارد الجهاز (مثل الألعاب أو الفيديو أو تطبيقات التنقل)\n • نزَّلت أو حمَّلت ملفات كبيرة الحجم\n • استخدمت هاتفك وسط أجواء مرتفعة الحرارة"</string>
@@ -1069,7 +1086,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"اضغط مع الاستمرار واسحب لإعادة ترتيب عناصر التحكّم."</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"تمت إزالة كل عناصر التحكّم."</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"لم يتم حفظ التغييرات."</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"تعذّر تحميل قائمة كل عناصر التحكّم."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"تعذَّر تحميل عناصر التحكّم. تحقّق من تطبيق <xliff:g id="APP">%s</xliff:g> للتأكّد من أنه لم يتم تغيير إعدادات التطبيق."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"عناصر التحكّم المتوافقة غير متوفّرة"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"غير ذلك"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"إضافة إلى أدوات التحكم بالجهاز"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"إضافة"</string>
@@ -1085,8 +1103,11 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"تأكيد التغيير لـ <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"مرّر سريعًا لرؤية المزيد."</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"جارٍ تحميل الاقتراحات"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"إغلاق جلسة تشغيل الوسائط هذه"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"الوسائط"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"إخفاء الجلسة الحالية"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"إخفاء"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"استئناف التشغيل"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"الإعدادات"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"غير نشط، تحقّق من التطبيق."</string>
<string name="controls_error_retryable" msgid="864025882878378470">"حدث خطأ، جارٍ إعادة المحاولة…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"لم يتم العثور عليه."</string>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index ca21ff674595..25c87fbd3bb0 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -454,8 +454,10 @@
<string name="notification_tap_again" msgid="4477318164947497249">"খুলিবলৈ পুনৰাই টিপক"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"খুলিবলৈ ওপৰলৈ ছোৱাইপ কৰক"</string>
<string name="keyguard_retry" msgid="886802522584053523">"পুনৰ চেষ্টা কৰিবলৈ ওপৰলৈ ছোৱাইপ কৰক"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"আপোনাৰ প্ৰতিষ্ঠানে এই ডিভাইচটো পৰিচালনা কৰে"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"এই ডিভাইচটো <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>ৰ দ্বাৰা পৰিচালিত।"</string>
+ <!-- no translation found for do_disclosure_generic (4896482821974707167) -->
+ <skip />
+ <!-- no translation found for do_disclosure_with_name (2091641464065004091) -->
+ <skip />
<string name="phone_hint" msgid="6682125338461375925">"ফ\'নৰ বাবে আইকনৰপৰা ছোৱাইপ কৰক"</string>
<string name="voice_hint" msgid="7476017460191291417">"কণ্ঠধ্বনিৰে সহায়ৰ বাবে আইকনৰ পৰা ছোৱাইপ কৰক"</string>
<string name="camera_hint" msgid="4519495795000658637">"কেমেৰা খুলিবলৈ আইকনৰপৰা ছোৱাইপ কৰক"</string>
@@ -521,21 +523,33 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"প্ৰ\'ফাইল নিৰীক্ষণ কৰা হ\'ব পাৰে"</string>
<string name="vpn_footer" msgid="3457155078010607471">"নেটৱৰ্ক নিৰীক্ষণ কৰা হ\'ব পাৰে"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"নেটৱৰ্ক নিৰীক্ষণ কৰা হ\'ব পাৰে"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"আপোনাৰ প্ৰতিষ্ঠানটোৱে এই ডিভাইচটো পৰিচালনা কৰে আৰু ই নেটৱৰ্কৰ ট্ৰেফিক পৰ্যবেক্ষণ কৰিব পাৰে।"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>এ এই ডিভাইচটো পৰিচালনা কৰে আৰু নেটৱৰ্কৰ ট্ৰেফিক পৰ্যবেক্ষণ কৰিব পাৰে"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"আপোনাৰ প্ৰতিষ্ঠানে এই ডিভাইচটো পৰিচালনা কৰে আৰু ই <xliff:g id="VPN_APP">%1$s</xliff:g>ৰ সৈতে সংযুক্ত হৈ আছে"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>এ ডিভাইচটো পৰিচালনা কৰে আৰু এই ডিভাইচটো <xliff:g id="VPN_APP">%2$s</xliff:g>ৰ সৈতে সংযুক্ত হৈ আছে"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"আপোনাৰ প্ৰতিষ্ঠানে এই ডিভাইচটো পৰিচালনা কৰে"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>এ ডিভাইচটো পৰিচালনা কৰে"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"আপোনাৰ প্ৰতিষ্ঠানে এই ডিভাইচটো পৰিচালনা কৰে আৰু ই ভিপিএনৰ সৈতে সংযুক্ত হৈ আছে"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>এ ডিভাইচটো পৰিচালনা কৰে এই ডিভাইচটো ভিপিএনৰ সৈতে সংযুক্ত হৈ আছে"</string>
+ <!-- no translation found for quick_settings_disclosure_management_monitoring (8231336875820702180) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_monitoring (2831423806103479812) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_named_vpn (6096715329056415588) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (5302786161534380104) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management (5515296598440684962) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management (3476472755775165827) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_vpns (371835422690053154) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_vpns (4046375645500668555) -->
+ <skip />
<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_monitoring" msgid="8548019955631378680">"নেটৱৰ্ক নিৰীক্ষণ কৰা হ\'ব পাৰে"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"ডিভাইচটো ভিপিএনবোৰৰ সৈতে সংযুক্ত হৈ আছে"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"<xliff:g id="VPN_APP">%1$s</xliff:g>ৰ সৈতে কৰ্মস্থানৰ প্ৰ\'ফাইলটো সংযুক্ত হৈ আছে"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"ব্যক্তিগত প্ৰ\'ফাইলটো <xliff:g id="VPN_APP">%1$s</xliff:g>ৰ সৈতে সংযুক্ত হৈ আছে"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"ডিভাইচটো <xliff:g id="VPN_APP">%1$s</xliff:g>ৰ সৈতে সংযুক্ত হৈ আছে"</string>
+ <!-- no translation found for quick_settings_disclosure_vpns (7213546797022280246) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (8117568745060010789) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (5481763430080807797) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_vpn (2350838218824492465) -->
+ <skip />
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"ডিভাইচৰ পৰিচালনা"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"প্ৰ\'ফাইল নিৰীক্ষণ"</string>
<string name="monitoring_title" msgid="4063890083735924568">"নেটৱৰ্ক নিৰীক্ষণ"</string>
@@ -545,8 +559,10 @@
<string name="disable_vpn" msgid="482685974985502922">"ভিপিএন অক্ষম কৰক"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"ভিপিএন সংযোগ বিচ্ছিন্ন কৰক"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"নীতিসমূহ চাওক"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>য়ে আপোনাৰ ডিভাইচ পৰিচালনা কৰে।\n\nআপোনাৰ প্ৰশাসকে এই ডিভাইচটোৰ লগত জড়িত ছেটিংসমূহ, কৰ্প\'ৰেইট অনুমতি, এপসমূহ, ডেটা আৰু ডিভাইচটোৰ অৱস্থান সম্পৰ্কীয় তথ্য পৰ্যবেক্ষণ কৰাৰ লগতে পৰিচালনা কৰিব পাৰে।\n\nঅধিক তথ্য়ৰ বাবে আপোনাৰ প্ৰশাসকৰ সৈতে যোগাযোগ কৰক।"</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"আপোনাৰ প্ৰতিষ্ঠানে আপোনাৰ ডিভাইচটো পৰিচালনা কৰে।\n\nআপোনাৰ প্ৰশাসকে এই ডিভাইচটোৰ লগত জড়িত ছেটিংসমূহ, কৰ্প\'ৰেইট অনুমতি, এপসমূহ, ডেটা আৰু ডিভাইচটোৰ অৱস্থান সম্পৰ্কীয় তথ্য পৰ্যবেক্ষণ কৰাৰ লগতে পৰিচালনা কৰিব পাৰে।\n\nঅধিক তথ্য়ৰ বাবে আপোনাৰ প্ৰশাসকৰ সৈতে যোগাযোগ কৰক।"</string>
+ <!-- no translation found for monitoring_description_named_management (505833016545056036) -->
+ <skip />
+ <!-- no translation found for monitoring_description_management (4308879039175729014) -->
+ <skip />
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"আপোনাৰ প্ৰতিষ্ঠানে এই ডিভাইচটোত এটা প্ৰমাণপত্ৰ সম্পৰ্কীয় কৰ্তৃপক্ষ ইনষ্টল কৰিছে। আপোনাৰ সুৰক্ষিত নেটৱৰ্ক ট্ৰেফিক পৰ্যবেক্ষণ বা সংশোধন কৰা হ\'ব পাৰে।"</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"আপোনাৰ প্ৰতিষ্ঠানে আপোনাৰ কৰ্মস্থানৰ প্ৰ\'ফাইলটোত এটা প্ৰমাণপত্ৰ সম্পৰ্কীয় কৰ্তৃপক্ষ ইনষ্টল কৰিছে। আপোনাৰ সুৰক্ষিত নেটৱৰ্কৰ ট্ৰেফিক পৰ্যবেক্ষণ বা সংশোধন কৰা হ\'ব পাৰে।"</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"এই ডিভাইচটোত এটা প্ৰমাণপত্ৰ সম্পৰ্কীয় কৰ্তৃপক্ষ ইনষ্টল কৰা হৈছে। আপোনাৰ সুৰক্ষিত নেটৱৰ্কৰ ট্ৰেফিক পৰ্যবেক্ষণ বা সংশোধন কৰা হ\'ব পাৰে।"</string>
@@ -920,6 +936,7 @@
<string name="pip_pause" msgid="1139598607050555845">"পজ কৰক"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"পৰৱৰ্তী মিডিয়ালৈ যাওক"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"আগৰটো মিডিয়ালৈ যাওক"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"আকাৰ সলনি কৰক"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"আপোনাৰ ফ\'নটো গৰম হোৱাৰ কাৰণে অফ কৰা হৈছিল"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"আপোনাৰ ফ\'নটো এতিয়া স্বাভাৱিকভাৱে চলি আছে"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"আপোনাৰ ফ\'নটো অত্যধিক গৰম হোৱাৰ বাবে ইয়াক ঠাণ্ডা কৰিবলৈ অফ কৰা হৈছিল। আপোনাৰ ফ\'নটো এতিয়া স্বাভাৱিকভাৱে চলি আছে।\n\nআপোনাৰ ফ\'নটো গৰম হ\'ব পাৰে, যদিহে আপুনি:\n • ফ\'নটোৰ হাৰ্ডৱেৰ অত্যধিক মাত্ৰাত ব্যৱহাৰ কৰা এপসমূহ চলালে (যেনে, ভিডিঅ\' গেইম, ভিডিঅ\', দিক্-নিৰ্দেশনা এপসমূহ)\n • খুউব ডাঙৰ আকাৰৰ ফাইল আপল\'ড বা ডাউনল’ড কৰিলে\n • আপোনাৰ ফ\'নটো উচ্চ তাপমাত্ৰাৰ পৰিৱেশত ব্যৱহাৰ কৰিলে"</string>
@@ -1045,7 +1062,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"নিয়ন্ত্ৰণসমূহ পুনৰ সজাবলৈ ধৰি ৰাখক আৰু টানি আনি এৰক"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"সকলো নিয়ন্ত্ৰণ আঁতৰোৱা হৈছে"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"সালসলনিসমূহ ছেভ নহ’ল"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"নিয়ন্ত্ৰণসমূহৰ সম্পূর্ণ সূচীখন ল’ড কৰিব পৰা নগ’ল।"</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"নিয়ন্ত্ৰণসমূহ ল’ড কৰিবপৰা নগ’ল। এপ্‌টোৰ ছেটিংসমূহ সলনি কৰা হোৱা নাই বুলি নিশ্চিত কৰিবলৈ <xliff:g id="APP">%s</xliff:g> এপ্‌টো পৰীক্ষা কৰক।"</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"সমিল নিয়ন্ত্ৰণসমূহ উপলব্ধ নহয়"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"অন্য"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"ডিভাইচৰ নিয়ন্ত্ৰণসমূহত যোগ দিয়ক"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"যোগ দিয়ক"</string>
@@ -1061,8 +1079,11 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"<xliff:g id="DEVICE">%s</xliff:g>ৰ বাবে সলনি কৰাটো নিশ্চিত কৰক"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"অধিক চাবলৈ ছোৱাইপ কৰক"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"চুপাৰিছসমূহ ল’ড কৰি থকা হৈছে"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"এই মিডিয়া ছেশ্বনটো বন্ধ কৰক"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"মিডিয়া"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"বৰ্তমানৰ ছেশ্বনটো লুকুৱাওক।"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"লুকুৱাওক"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"পুনৰ আৰম্ভ কৰক"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"ছেটিংসমূহ"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"সক্ৰিয় নহয়, এপ্‌টো পৰীক্ষা কৰক"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"আসোঁৱাহ, পুনৰ চেষ্টা কৰি আছে…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"বিচাৰি পোৱা নগ’ল"</string>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index 3a7c98ca34cf..cfde8a6c23bd 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -454,8 +454,10 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Açmaq üçün yenidən tıklayın"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Açmaq üçün yuxarı sürüşdürün"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Yenidən cəhd etmək üçün yuxarı sürüşdürün"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"Bu cihaz təşkilatınız tərəfindən idarə olunur"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"Bu cihaz <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> tərəfindən idarə olunur"</string>
+ <!-- no translation found for do_disclosure_generic (4896482821974707167) -->
+ <skip />
+ <!-- no translation found for do_disclosure_with_name (2091641464065004091) -->
+ <skip />
<string name="phone_hint" msgid="6682125338461375925">"Telefon üçün ikonadan sürüşdürün"</string>
<string name="voice_hint" msgid="7476017460191291417">"Səs yardımçısı üçün ikonadan sürüşdürün"</string>
<string name="camera_hint" msgid="4519495795000658637">"Kamera üçün ikonadan sürüşdürün"</string>
@@ -521,21 +523,33 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"Profil izlənə bilər"</string>
<string name="vpn_footer" msgid="3457155078010607471">"Şəbəkə nəzərdən keçirilə bilər"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"Şəbəkə nəzərdən keçirilə bilər"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"Təşkilat bu cihazı idarə edir və şəbəkə ötürülməsinə nəzarət edə bilər"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> bu cihazı idarə edir və şəbəkə ötürülməsinə nəzarət edə bilər"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"Cihaz təşkilat tərəfindən idarə edilir və <xliff:g id="VPN_APP">%1$s</xliff:g> tətbiqinə bağlıdır"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"Cihaz <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> tərəfindən idarə edilir və <xliff:g id="VPN_APP">%2$s</xliff:g> tətbiqinə qoşuludur"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"Cihaz təşkilatınız tərəfindən idarə edilir"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"Cihaz <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> tərəfindən idarə edilir"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"Cihaz təşkilatınız tərəfindən idarə edilir və VPN-lərə bağlıdır"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"Cihaz <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> tərəfindən idarə edilir və VPN-lərə qoşuludur"</string>
+ <!-- no translation found for quick_settings_disclosure_management_monitoring (8231336875820702180) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_monitoring (2831423806103479812) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_named_vpn (6096715329056415588) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (5302786161534380104) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management (5515296598440684962) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management (3476472755775165827) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_vpns (371835422690053154) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_vpns (4046375645500668555) -->
+ <skip />
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Təşkilat iş profilində şəbəkə ötürülməsinə nəzarət edə bilər"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> iş profilində şəbəkə ötürülməsinə nəzarət edə bilər"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Şəbəkəyə nəzarət edilə bilər"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"Cihaz VPN-lərə qoşuludur"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"İş profili <xliff:g id="VPN_APP">%1$s</xliff:g> tətbiqinə qoşuludur"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"Şəxsi profil <xliff:g id="VPN_APP">%1$s</xliff:g> tətbiqinə qoşuludur"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"Cihaz <xliff:g id="VPN_APP">%1$s</xliff:g> tətbiqinə qoşuludur"</string>
+ <!-- no translation found for quick_settings_disclosure_vpns (7213546797022280246) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (8117568745060010789) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (5481763430080807797) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_vpn (2350838218824492465) -->
+ <skip />
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Cihaz idarəetməsi"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Profil izlənməsi"</string>
<string name="monitoring_title" msgid="4063890083735924568">"Şəbəkə monitorinqi"</string>
@@ -545,8 +559,10 @@
<string name="disable_vpn" msgid="482685974985502922">"VPN-i deaktiv edin"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"VPN-i bağlantıdan ayırın"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"Siyasətlərə Baxın"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"Cihaz <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> tərəfindən idarə edilir.\n\nAdmin cihaz və cihaz məkan məlumatı ilə əlaqəli ayarlara, korporativ girişə, tətbiqə və dataya nəzarət edə və idarə edə bilər.\n\nƏtraflı məlumat üçün admin ilə əlaqə saxlayın."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"Cihaz təşkilatınız tərəfindən idarə edilir.\n\nAdmin cihaz və cihaz məkan məlumatı ilə əlaqəli ayarlara, korporativ girişə, tətbiqə və dataya nəzarət edə və idarə edə bilər.\n\nƏtraflı məlumat üçün admin ilə əlaqə saxlayın."</string>
+ <!-- no translation found for monitoring_description_named_management (505833016545056036) -->
+ <skip />
+ <!-- no translation found for monitoring_description_management (4308879039175729014) -->
+ <skip />
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Təşkilat bu cihazda sertifikat səlahiyyəti quraşdırdı. Təhlükəsiz şəbəkə ötürülməsinə nəzarət edilə və ya dəyişdirilə bilər."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Təşkilat iş profilində sertifikat səlahiyyəti quraşdırdı. Təhlükəsiz şəbəkə ötürülməsinə nəzarət edilə və ya dəyişdirilə bilər."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Bu cihazda sertifikat səlahiyyəti quraşdırıldı. Təhlükəsiz şəbəkə ötürülməsinə nəzarət edilə və ya dəyişdirilə bilər."</string>
@@ -920,6 +936,7 @@
<string name="pip_pause" msgid="1139598607050555845">"Fasilə verin"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"Növbətiyə keçin"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"Əvvəlkinə keçin"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"Ölçüsünü dəyişin"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"İstiliyə görə telefon söndü"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"Telefon indi normal işləyir"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Telefon çox isti idi və soyumaq üçün söndü. Hazırda telefon normal işləyir.\n\n Telefon bu hallarda çox isti ola bilər:\n • Çox resurslu tətbiq istifadə etsəniz (oyun, video və ya naviqasiya tətbiqi kimi)\n • Böyük həcmli fayl endirsəniz və ya yükləsəniz\n • Telefonu yüksək temperaturda istifadə etsəniz"</string>
@@ -1002,8 +1019,8 @@
<string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Yuxarıya sağa köçürün"</string>
<string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Aşağıya sola köçürün"</string>
<string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Aşağıya sağa köçürün"</string>
- <string name="bubble_dismiss_text" msgid="1314082410868930066">"Qabarcığı ləğv edin"</string>
- <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Söhbətdən gələn bildirişi göstərməyin"</string>
+ <string name="bubble_dismiss_text" msgid="1314082410868930066">"Yumrucuğu ləğv edin"</string>
+ <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Söhbəti yumrucuqda göstərmə"</string>
<string name="bubbles_user_education_title" msgid="5547017089271445797">"Yumrucuqlardan istifadə edərək söhbət edin"</string>
<string name="bubbles_user_education_description" msgid="1160281719576715211">"Yeni söhbətlər üzən nişanlar və ya yumrucuqlar kimi görünür. Yumrucuğu açmaq üçün toxunun. Hərəkət etdirmək üçün sürüşdürün."</string>
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Yumrucuqları istənilən vaxt idarə edin"</string>
@@ -1045,7 +1062,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Nizamlayıcıları yenidən tənzimləmək üçün tutub sürüşdürün"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"Bütün nizamlayıcılar silindi"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Dəyişikliklər yadda saxlanmadı"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"Bütün nizamlayıcıların siyahısı yüklənmədi."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"Nizamlayıcıları yükləmək mümkün olmadı. <xliff:g id="APP">%s</xliff:g> tətbiqinə toxunaraq tətbiq ayarlarının dəyişmədiyinə əmin olun."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"Uyğun nizamlayıcılar əlçatan deyil"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Digər"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"Cihaz idarəetmələrinə əlavə edin"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"Əlavə edin"</string>
@@ -1061,8 +1079,15 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"<xliff:g id="DEVICE">%s</xliff:g> üzrə dəyişikliyi təsdiq edin"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Digərlərini görmək üçün sürüşdürün"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Tövsiyələr yüklənir"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"Bu media sessiyasını bağlayın"</string>
+ <!-- no translation found for controls_media_title (1746947284862928133) -->
+ <skip />
+ <!-- no translation found for controls_media_close_session (3957093425905475065) -->
+ <skip />
+ <!-- no translation found for controls_media_dismiss_button (4485675693008031646) -->
+ <skip />
<string name="controls_media_resume" msgid="1933520684481586053">"Davam edin"</string>
+ <!-- no translation found for controls_media_settings_button (5815790345117172504) -->
+ <skip />
<string name="controls_error_timeout" msgid="794197289772728958">"Aktiv deyil, tətbiqi yoxlayın"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Xəta, yenidən cəhd edilir…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Tapılmadı"</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index cdface92a34c..50aba93d30a1 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -456,8 +456,8 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Dodirnite ponovo da biste otvorili"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Prevucite nagore da biste otvorili"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Prevucite nagore da biste probali ponovo"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"Ovim uređajem upravlja organizacija"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"Ovim uređajem upravlja <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
+ <string name="do_disclosure_generic" msgid="4896482821974707167">"Ovaj uređaj pripada organizaciji"</string>
+ <string name="do_disclosure_with_name" msgid="2091641464065004091">"Ovaj uređaj pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="6682125338461375925">"Prevucite od ikone za telefon"</string>
<string name="voice_hint" msgid="7476017460191291417">"Prevucite od ikone za glasovnu pomoć"</string>
<string name="camera_hint" msgid="4519495795000658637">"Prevucite od ikone za kameru"</string>
@@ -524,21 +524,21 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"Profil se možda nadgleda"</string>
<string name="vpn_footer" msgid="3457155078010607471">"Mreža se možda nadgleda"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"Mreža se možda nadgleda"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"Organizacija upravlja ovim uređajem i može da nadgleda mrežni saobraćaj"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> upravlja ovim uređajem i može da nadgleda mrežni saobraćaj"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"Uređajem upravlja organizacija i povezan je sa aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"Uređajem upravlja <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> i povezan je sa aplikacijom <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"Uređajem upravlja organizacija"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"Ovim uređajem upravlja <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"Uređajem upravlja organizacija i povezan je sa VPN-ovima"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"Uređajem upravlja <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> i povezan je sa VPN-ovima"</string>
+ <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Organizacija je vlasnik uređaja i može da nadgleda mrežni saobraćaj"</string>
+ <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> je vlasnik ovog uređaja i može da nadgleda mrežni saobraćaj"</string>
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Ovaj uređaj pripada organizaciji i povezan je sa aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Ovaj uređaj pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> i povezan je sa aplikacijom <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Ovaj uređaj pripada organizaciji"</string>
+ <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Ovaj uređaj pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management_vpns" msgid="371835422690053154">"Ovaj uređaj pripada organizaciji i povezan je sa VPN-ovima"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="4046375645500668555">"Ovaj uređaj pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> i povezan je sa VPN-ovima"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Organizacija može da prati mrežni saobraćaj na poslovnom profilu"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> može da nadgleda mrežni saobraćaj na poslovnom profilu"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Mreža se možda nadgleda"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"Uređaj je povezan sa VPN-ovima"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"Poslovni profil je povezan sa aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"Lični profil je povezan sa aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"Uređaj je povezan sa aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_vpns" msgid="7213546797022280246">"Ovaj uređaj je povezan sa VPN-ovima"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Poslovni profil je povezan sa aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Vaš lični profil je povezan sa aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Ovaj uređaj je povezan sa aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Upravljanje uređajima"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Nadgledanje profila"</string>
<string name="monitoring_title" msgid="4063890083735924568">"Nadgledanje mreže"</string>
@@ -548,8 +548,8 @@
<string name="disable_vpn" msgid="482685974985502922">"Onemogući VPN"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"Prekini vezu sa VPN-om"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"Prikaži smernice"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"Uređajem upravlja <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nAdministrator može da nadgleda podešavanja, korporativni pristup, aplikacije, podatke povezane sa uređajem i informacije o lokaciji uređaja, kao i da upravlja njima.\n\nViše informacija potražite od administratora."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"Uređajem upravlja organizacija.\n\nAdministrator može da nadgleda podešavanja, korporativni pristup, aplikacije, podatke povezane sa uređajem i informacije o lokaciji uređaja, kao i da upravlja njima.\n\nViše informacija potražite od administratora."</string>
+ <string name="monitoring_description_named_management" msgid="505833016545056036">"Ovaj uređaj pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nIT administrator može da nadgleda podešavanja, korporativni pristup, aplikacije, podatke povezane sa uređajem i informacije o lokaciji uređaja, kao i da upravlja njima.\n\nViše informacija potražite od IT administratora."</string>
+ <string name="monitoring_description_management" msgid="4308879039175729014">"Ovaj uređaj pripada organizaciji.\n\nIT administrator može da nadgleda podešavanja, korporativni pristup, aplikacije, podatke povezane sa uređajem i informacije o lokaciji uređaja, kao i da upravlja njima.\n\nViše informacija potražite od IT administratora."</string>
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Organizacija je na ovom uređaju instalirala autoritet za izdavanje sertifikata. Bezbedni mrežni saobraćaj može da se prati ili menja."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Organizacija je na poslovnom profilu instalirala autoritet za izdavanje sertifikata. Bezbedni mrežni saobraćaj može da se prati ili menja."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Na ovom uređaju je instaliran autoritet za izdavanje sertifikata. Bezbedni mrežni saobraćaj može da se prati ili menja."</string>
@@ -925,6 +925,7 @@
<string name="pip_pause" msgid="1139598607050555845">"Pauziraj"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"Pređi na sledeće"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"Pređi na prethodno"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"Promenite veličinu"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"Telefon se isključio zbog toplote"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"Telefon sada normalno radi"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Telefon je bio prevruć, pa se isključio da se ohladi. Sada radi normalno.\n\nTelefon može previše da se ugreje ako:\n • Koristite aplikacije koje zahtevaju puno resursa (npr. video igre, video ili aplikacije za navigaciju)\n • Preuzimate/otpremate velike datoteke\n • Koristite telefon na visokoj temperaturi"</string>
@@ -1007,7 +1008,7 @@
<string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Premesti gore desno"</string>
<string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Premesti dole levo"</string>
<string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Premesti dole desno"</string>
- <string name="bubble_dismiss_text" msgid="1314082410868930066">"Odbacivanje oblačića"</string>
+ <string name="bubble_dismiss_text" msgid="1314082410868930066">"Odbaci oblačić"</string>
<string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Ne koristi oblačiće za konverzaciju"</string>
<string name="bubbles_user_education_title" msgid="5547017089271445797">"Ćaskajte u oblačićima"</string>
<string name="bubbles_user_education_description" msgid="1160281719576715211">"Nove konverzacije se prikazuju kao plutajuće ikone ili oblačići. Dodirnite da biste otvorili oblačić. Prevucite da biste ga premestili."</string>
@@ -1019,9 +1020,9 @@
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Idite u Podešavanja da biste ažurirali navigaciju sistema"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Stanje pripravnosti"</string>
<string name="priority_onboarding_title" msgid="2893070698479227616">"Konverzacija je podešena na prioritetnu"</string>
- <string name="priority_onboarding_behavior" msgid="5342816047020432929">"Prioritetne konverzacije će:"</string>
- <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Prikazuje se u vrhu odeljka za konverzacije"</string>
- <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Prikazuje sliku profila na zaključanom ekranu"</string>
+ <string name="priority_onboarding_behavior" msgid="5342816047020432929">"Prioritetne konverzacije:"</string>
+ <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"se prikazuju u vrhu odeljka za konverzacije"</string>
+ <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"prikazuju sliku profila na zaključanom ekranu"</string>
<string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Prikazuju se plutajući oblačići preko aplikacija"</string>
<string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Ometa podešavanje Ne uznemiravaj"</string>
<string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Važi"</string>
@@ -1051,7 +1052,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Zadržite i prevucite da biste promenili raspored kontrola"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"Sve kontrole su uklonjene"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Promene nisu sačuvane"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"Učitavanje liste svih kontrola nije uspelo."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"Učitavanje kontrola nije uspelo. Pogledajte aplikaciju <xliff:g id="APP">%s</xliff:g> da biste se uverili da se podešavanja aplikacije nisu promenila."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"Kompatibilne kontrole nisu dostupne"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Drugo"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"Dodajte u kontrole uređaja"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"Dodaj"</string>
@@ -1067,8 +1069,11 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"Potvrdite promenu za: <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Prevucite da biste videli još"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Učitavaju se preporuke"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"Zatvorite ovu sesiju medija"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"Mediji"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"Sakrijte aktuelnu sesiju."</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Sakrij"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Nastavi"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"Podešavanja"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Neaktivno. Vidite aplikaciju"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Greška, pokušava se ponovo…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Nije pronađeno"</string>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 32ec1841ea3e..83b58106523f 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -419,7 +419,7 @@
<string name="quick_settings_cellular_detail_data_limit" msgid="1791389609409211628">"Ліміт <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
<string name="quick_settings_cellular_detail_data_warning" msgid="7957253810481086455">"Папярэджанне: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
<string name="quick_settings_work_mode_label" msgid="2754212289804324685">"Працоўны профіль"</string>
- <string name="quick_settings_night_display_label" msgid="8180030659141778180">"Начны рэжым"</string>
+ <string name="quick_settings_night_display_label" msgid="8180030659141778180">"Начная падсветка"</string>
<string name="quick_settings_night_secondary_label_on_at_sunset" msgid="3358706312129866626">"Уключаць увечары"</string>
<string name="quick_settings_night_secondary_label_until_sunrise" msgid="4063448287758262485">"Да ўсходу сонца"</string>
<string name="quick_settings_night_secondary_label_on_at" msgid="3584738542293528235">"Уключыць у <xliff:g id="TIME">%s</xliff:g>"</string>
@@ -458,8 +458,10 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Дакраніцеся яшчэ раз, каб адкрыць"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Каб адкрыць, прагарніце ўверх"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Прагартайце ўверх, каб паўтарыць спробу"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"Гэта прылада знаходзіцца пад кіраваннем вашай арганізацыі"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"Гэта прылада знаходзіцца пад кіраваннем <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for do_disclosure_generic (4896482821974707167) -->
+ <skip />
+ <!-- no translation found for do_disclosure_with_name (2091641464065004091) -->
+ <skip />
<string name="phone_hint" msgid="6682125338461375925">"Тэлефон: правядзіце пальцам ад значка"</string>
<string name="voice_hint" msgid="7476017460191291417">"Галасавая дапамога: правядзіце пальцам ад значка"</string>
<string name="camera_hint" msgid="4519495795000658637">"Камера: правядзіце пальцам ад значка"</string>
@@ -527,21 +529,33 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"За профілем могуць назіраць"</string>
<string name="vpn_footer" msgid="3457155078010607471">"За сеткай могуць назіраць"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"За сеткай могуць назіраць"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"Ваша арганізацыя кіруе гэтай прыладай і можа сачыць за сеткавым трафікам"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> кіруе гэтай прыладай і можа сачыць за сеткавым трафікам"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"Прылада знаходзіцца пад кіраваннем вашай арганізацыі і падключана да праграмы <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"Прылада знаходзіцца пад кіраваннем <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> і падключана да праграмы <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"Прылада знаходзіцца пад кіраваннем вашай арганізацыі"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"Гэта прылада знаходзіцца пад кіраваннем <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"Прылада знаходзіцца пад кіраваннем вашай арганізацыі і падключана да сетак VPN"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"Прылада знаходзіцца пад кіраваннем <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> і падключана да сетак VPN"</string>
+ <!-- no translation found for quick_settings_disclosure_management_monitoring (8231336875820702180) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_monitoring (2831423806103479812) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_named_vpn (6096715329056415588) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (5302786161534380104) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management (5515296598440684962) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management (3476472755775165827) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_vpns (371835422690053154) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_vpns (4046375645500668555) -->
+ <skip />
<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_monitoring" msgid="8548019955631378680">"За сеткай могуць сачыць"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"Прылада падключана да сетак VPN"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"Працоўны профіль падключаны да праграмы <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"Асабісты профіль падключаны да праграмы <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"Прылада падключана да праграмы <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <!-- no translation found for quick_settings_disclosure_vpns (7213546797022280246) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (8117568745060010789) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (5481763430080807797) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_vpn (2350838218824492465) -->
+ <skip />
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Кіраванне прыладай"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Маніторынг профіляў"</string>
<string name="monitoring_title" msgid="4063890083735924568">"Маніторынг сеткі"</string>
@@ -551,8 +565,10 @@
<string name="disable_vpn" msgid="482685974985502922">"Адключыць VPN"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"Адлучыць VPN"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"Праглядзець палітыку"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"Ваша прылада знаходзіцца пад кіраваннем <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nВаш адміністратар можа сачыць і кіраваць наладамі, карпаратыўным доступам, праграмамі, данымі, звязанымі з вашай прыладай, і звесткамі пра месцазнаходжанне вашай прылады.\n\nДля атрымання дадатковай інфармацыі звярніцеся да адміністратара."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"Ваша прылада знаходзіцца пад кіраваннем вашай арганізацыі.\n\nУ вашага адміністратара ёсць магчымасць маніторынгу і адміністравання налад, карпаратыўнага доступу, праграм, даных, звязаных з гэтай прыладай, і адпаведных геаданых.\n\nДля атрымання дадатковай інфармацыі звярніцеся да адміністратара."</string>
+ <!-- no translation found for monitoring_description_named_management (505833016545056036) -->
+ <skip />
+ <!-- no translation found for monitoring_description_management (4308879039175729014) -->
+ <skip />
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Ваша арганізацыя ўсталявала на гэтай прыладзе цэнтр сертыфікацыі. Ваш абаронены сеткавы трафік могуць праглядваць ці змяняць."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Ваша арганізацыя ўсталявала ў вашым працоўным профілі цэнтр сертыфікацыі. Ваш абаронены сеткавы трафік могуць праглядваць ці змяняць."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"На гэтай прыладзе ўсталяваны цэнтр сертыфікацыі. Ваш абаронены сеткавы трафік могуць праглядваць ці змяняць."</string>
@@ -930,6 +946,7 @@
<string name="pip_pause" msgid="1139598607050555845">"Прыпыніць"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"Перайсці да наступнага"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"Перайсці да папярэдняга"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"Змяніць памер"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"З-за перагрэву тэл. выключыўся"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"Тэлефон працуе нармальна"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Ваш тэлефон пераграваўся, таму ён выключыўся, каб астыць. Зараз тэлефон працуе нармальна.\n\nТэлефон можа перагравацца пры:\n • Выкарыстанні рэсурсаёмістых праграм (напрыклад, гульняў, відэа або праграм навігацыі)\n • Спампоўцы або запампоўцы вялікіх файлаў\n • Выкарыстанні тэлефона пры высокіх тэмпературах"</string>
@@ -1024,7 +1041,7 @@
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Перайдзіце ў Налады, каб абнавіць параметры навігацыі ў сістэме"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Рэжым чакання"</string>
<string name="priority_onboarding_title" msgid="2893070698479227616">"Размова пазначана як прыярытэтная"</string>
- <string name="priority_onboarding_behavior" msgid="5342816047020432929">"Прыярытэтныя размовы будуць:"</string>
+ <string name="priority_onboarding_behavior" msgid="5342816047020432929">"Прыярытэтныя размовы:"</string>
<string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Паказваюцца ўверсе раздзела размоў"</string>
<string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Паказваюць відарыс профілю на экране блакіроўкі"</string>
<string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Паказваюцца як рухомыя апавяшчэнні паверх праграм"</string>
@@ -1057,7 +1074,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Каб змяніць парадак элементаў кіравання, утрымлівайце і перацягвайце іх"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"Усе элементы кіравання выдалены"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Змяненні не захаваны"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"Не ўдалося загрузіць спіс усіх сродкаў кіравання."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"Не ўдалося загрузіць элементы кіравання. Праверце, ці не змяніліся налады праграмы \"<xliff:g id="APP">%s</xliff:g>\"."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"Сумяшчальныя элементы кіравання недаступныя"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Іншае"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"Дадаць у элементы кіравання прыладай"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"Дадаць"</string>
@@ -1073,8 +1091,15 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"Пацвердзіце змяненне для прылады \"<xliff:g id="DEVICE">%s</xliff:g>\""</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Правядзіце пальцам, каб убачыць больш інфармацыі"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Загружаюцца рэкамендацыі"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"Закрыць гэты сеанс мультымедыя"</string>
+ <!-- no translation found for controls_media_title (1746947284862928133) -->
+ <skip />
+ <!-- no translation found for controls_media_close_session (3957093425905475065) -->
+ <skip />
+ <!-- no translation found for controls_media_dismiss_button (4485675693008031646) -->
+ <skip />
<string name="controls_media_resume" msgid="1933520684481586053">"Узнавіць"</string>
+ <!-- no translation found for controls_media_settings_button (5815790345117172504) -->
+ <skip />
<string name="controls_error_timeout" msgid="794197289772728958">"Неактыўна, праверце праграму"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Памылка, паўторная спроба…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Не знойдзена"</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index a2a2671b3f70..9d6a2bf83a88 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -454,8 +454,8 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Докоснете отново, за да отворите"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Прекарайте пръст нагоре, за да отключите"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Плъзнете бързо нагоре, за да опитате отново"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"Това устройство се управлява от организацията ви"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"Това устройство се управлява от <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
+ <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="phone_hint" msgid="6682125338461375925">"Плъзнете с пръст от иконата, за да използвате телефона"</string>
<string name="voice_hint" msgid="7476017460191291417">"Прекарайте пръст от иконата, за да получите гласова помощ"</string>
<string name="camera_hint" msgid="4519495795000658637">"Плъзнете с пръст от иконата, за да включите камерата"</string>
@@ -521,21 +521,21 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"Възможно е потребителският профил да се наблюдава"</string>
<string name="vpn_footer" msgid="3457155078010607471">"Мрежата може да се наблюдава"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"Мрежата може да се наблюдава"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"Организацията ви управлява това устройство и може да наблюдава трафика в мрежата"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> управлява това устройство и може да наблюдава трафика в мрежата"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"Устройството се управлява от организацията ви и е свързано с приложението <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"Устройството се управлява от <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> и е свързано с приложението <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"Устройството се управлява от организацията ви"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"Устройството се управлява от <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"Устройството се управлява от организацията ви и е свързано с виртуални частни мрежи (VPN)"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"Устройството се управлява от <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> и е свързано с виртуални частни мрежи (VPN)"</string>
+ <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Организацията ви притежава това устройство и може да наблюдава трафика в мрежата"</string>
+ <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> притежава това устройство и може да наблюдава трафика в мрежата"</string>
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Това устройство принадлежи на организацията ви и е свързано с(ъс) <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Това устройство принадлежи на <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> и е свързано с(ъс) <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Това устройство принадлежи на организацията ви"</string>
+ <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Това устройство принадлежи на <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management_vpns" msgid="371835422690053154">"Това устройство принадлежи на организацията ви и е свързано с виртуални частни мрежи (VPN)"</string>
+ <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_monitoring" msgid="8548019955631378680">"Мрежата може да се наблюдава"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"Устройството е свързано с виртуални частни мрежи (VPN)"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"Служебният потребителски профил е свързан с приложението <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"Личният потребителски профил е свързан с приложението <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"Устройството е свързано с приложението <xliff:g id="VPN_APP">%1$s</xliff:g>"</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>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Личният ви потребителски профил е свързан с(ъс) <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Това устройство е свързано с(ъс) <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Управление на устройствата"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Наблюдаване на потр. профил"</string>
<string name="monitoring_title" msgid="4063890083735924568">"Наблюдение на мрежата"</string>
@@ -545,8 +545,8 @@
<string name="disable_vpn" msgid="482685974985502922">"Деактивиране на VPN"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"Прекратяване на връзката с VPN"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"Преглед на правилата"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"Устройството ви се управлява от <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nАдминистраторът ви може да наблюдава и управлява настройките, корпоративния достъп, приложенията, свързаните с устройството данни и информацията за местоположението му.\n\nЗа повече информация се свържете с администратора си."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"Устройството ви се управлява от организацията ви.\n\nАдминистраторът ви може да наблюдава и управлява настройките, корпоративния достъп, приложенията, свързаните с устройството данни и информацията за местоположението му.\n\nЗа повече информация се свържете с администратора си."</string>
+ <string name="monitoring_description_named_management" msgid="505833016545056036">"Това устройство принадлежи на <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nСистемният ви администратор може да наблюдава и управлява настройките, корпоративния достъп, приложенията, свързаните с устройството данни и информацията за местоположението му.\n\nЗа повече информация се обърнете към него."</string>
+ <string name="monitoring_description_management" msgid="4308879039175729014">"Това устройство принадлежи на организацията ви.\n\nСистемният ви администратор може да наблюдава и управлява настройките, корпоративния достъп, приложенията, свързаните с устройството данни и информацията за местоположението му.\n\nЗа повече информация се обърнете към него."</string>
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Организацията ви е инсталирала сертифициращ орган на това устройство. Трафикът в защитената ви мрежа може да бъде наблюдаван или променян."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Организацията ви е инсталирала сертифициращ орган в служебния ви потребителски профил. Трафикът в защитената ви мрежа може да бъде наблюдаван или променян."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"На това устройство е инсталиран сертифициращ орган. Трафикът в защитената ви мрежа може да бъде наблюдаван или променян."</string>
@@ -920,6 +920,7 @@
<string name="pip_pause" msgid="1139598607050555845">"Поставяне на пауза"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"Към следващия елемент"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"Към предишния елемент"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"Преоразмеряване"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"Тел. се изкл. поради загряване"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"Телефонът ви вече работи нормално"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Телефонът ви бе твърде горещ, затова се изключи с цел охлаждане. Вече работи нормално.\n\nТелефонът ви може да стане твърде горещ, ако:\n • използвате приложения, които ползват голям обем ресурси (като например игри, видеосъдържание или приложения за навигация);\n • изтегляте или качвате големи файлове;\n • използвате устройството си при високи температури."</string>
@@ -1002,7 +1003,7 @@
<string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Преместване горе вдясно"</string>
<string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Преместване долу вляво"</string>
<string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Преместване долу вдясно"</string>
- <string name="bubble_dismiss_text" msgid="1314082410868930066">"Балонче: Отхвърляне"</string>
+ <string name="bubble_dismiss_text" msgid="1314082410868930066">"Отхвърляне на балончетата"</string>
<string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Без балончета за разговора"</string>
<string name="bubbles_user_education_title" msgid="5547017089271445797">"Чат с балончета"</string>
<string name="bubbles_user_education_description" msgid="1160281719576715211">"Новите разговори се показват като плаващи икони, или балончета. Докоснете балонче, за да го отворите, или го плъзнете, за да го преместите."</string>
@@ -1015,8 +1016,8 @@
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Режим на готовност"</string>
<string name="priority_onboarding_title" msgid="2893070698479227616">"Разговорът е зададен като приоритетен"</string>
<string name="priority_onboarding_behavior" msgid="5342816047020432929">"Приоритетните разговори ще:"</string>
- <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Показване върху секцията с разговори"</string>
- <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Показване на снимката на потр. профил на закл. екран"</string>
+ <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"се показват върху секцията с разговори;"</string>
+ <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"показват снимката на потребителския профил на заключения екран."</string>
<string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Показва се като плаващо балонче върху приложенията"</string>
<string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Прекъсване на режима „Не безпокойте“"</string>
<string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Разбрах"</string>
@@ -1045,7 +1046,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Задръжте и плъзнете, за да пренаредите контролите"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"Всички контроли са премахнати"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Промените не са запазени"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"Списъкът с всички контроли не бе зареден."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"Контролите не се заредиха. Отворете приложението <xliff:g id="APP">%s</xliff:g> и проверете дали настройките му не са променени."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"Не са налице съвместими контроли"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Друго"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"Добавяне към контролите за устройството"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"Добавяне"</string>
@@ -1061,8 +1063,11 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"Потвърдете промяната за <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Прекарайте пръст, за да видите повече"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Препоръките се зареждат"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"Затваряне на тази сесия за мултимедия"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"Мултимедия"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"Скриване на текущата сесия."</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Скриване"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Възобновяване"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"Настройки"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Неактивно, проверете прилож."</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Грешка. Извършва се нов опит…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Не е намерено"</string>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index 7a9fecad5f9d..e204bc8856ad 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -454,8 +454,10 @@
<string name="notification_tap_again" msgid="4477318164947497249">"খোলার জন্য আবার আলতো চাপুন"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"খোলার জন্য উপরে সোয়াইপ করুন"</string>
<string name="keyguard_retry" msgid="886802522584053523">"আবার চেষ্টা করতে উপরের দিকে সোয়াইপ করুন"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"আপনার সংস্থা এই ডিভাইসটি পরিচালনা করছে"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"এই ডিভাইসটি <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> এর দ্বারা পরিচালিত"</string>
+ <!-- no translation found for do_disclosure_generic (4896482821974707167) -->
+ <skip />
+ <!-- no translation found for do_disclosure_with_name (2091641464065004091) -->
+ <skip />
<string name="phone_hint" msgid="6682125338461375925">"ফোনের জন্য আইকন থেকে সোয়াইপ করুন"</string>
<string name="voice_hint" msgid="7476017460191291417">"ভয়েস সহায়তার জন্য আইকন থেকে সোয়াইপ করুন"</string>
<string name="camera_hint" msgid="4519495795000658637">"ক্যামেরার জন্য আইকন থেকে সোয়াইপ করুন"</string>
@@ -521,21 +523,33 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"প্রোফাইল পর্যবেক্ষণ করা হতে পারে"</string>
<string name="vpn_footer" msgid="3457155078010607471">"নেটওয়ার্ক নিরীক্ষণ করা হতে পারে"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"নেটওয়ার্ক নিরীক্ষণ করা হতে পারে"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"আপনার প্রতিষ্ঠান এই ডিভাইসটি পরিচালনা করে এবং এটির নেটওয়ার্ক ট্রাফিকের উপরে নজর রাখতে পারে"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> এই ডিভাইসটি পরিচালনা করে এবং এটির নেটওয়ার্ক ট্রাফিকের উপরে নজর রাখতে পারে"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"এই ডিভাইসটি আপনার প্রতিষ্ঠান দ্বারা পরিচালিত হচ্ছে এবং <xliff:g id="VPN_APP">%1$s</xliff:g> এর সাথে সংযুক্ত রয়েছে"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"এই ডিভাইসটি <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> দ্বারা পরিচালিত হচ্ছে এবং <xliff:g id="VPN_APP">%2$s</xliff:g> এর সাথে সংযুক্ত রয়েছে"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"আপনার প্রতিষ্ঠান এই ডিভাইসটি পরিচালনা করে"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ডিভাইসটি পরিচালনা করছে"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"এই ডিভাইসটি আপনার প্রতিষ্ঠান দ্বারা পরিচালিত হচ্ছে এবং দুটি VPN এর সাথে সংযুক্ত রয়েছে"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"এই ডিভাইসটি <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> দ্বারা পরিচালিত হচ্ছে এবং দুটি VPN এর সাথে সংযুক্ত রয়েছে"</string>
+ <!-- no translation found for quick_settings_disclosure_management_monitoring (8231336875820702180) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_monitoring (2831423806103479812) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_named_vpn (6096715329056415588) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (5302786161534380104) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management (5515296598440684962) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management (3476472755775165827) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_vpns (371835422690053154) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_vpns (4046375645500668555) -->
+ <skip />
<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_monitoring" msgid="8548019955631378680">"নেটওয়ার্কের উপরে নজর রাখা হতে পারে"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"ডিভাইসটি দুটি VPN এর সাথে সংযুক্ত রয়েছে"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"কর্মস্থলের প্রোফাইল <xliff:g id="VPN_APP">%1$s</xliff:g> এর সাথে সংযুক্ত রয়েছে"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"ব্যক্তিগত প্রোফাইল <xliff:g id="VPN_APP">%1$s</xliff:g> এর সাথে সংযুক্ত রয়েছে"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"ডিভাইসটি <xliff:g id="VPN_APP">%1$s</xliff:g> এর সাথে সংযুক্ত রয়েছে"</string>
+ <!-- no translation found for quick_settings_disclosure_vpns (7213546797022280246) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (8117568745060010789) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (5481763430080807797) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_vpn (2350838218824492465) -->
+ <skip />
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"ডিভাইসের পরিচালনা"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"প্রোফাইল দেখরেখ করা"</string>
<string name="monitoring_title" msgid="4063890083735924568">"নেটওয়ার্ক নিরীক্ষণ"</string>
@@ -545,8 +559,10 @@
<string name="disable_vpn" msgid="482685974985502922">"VPN অক্ষম করুন"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"VPN এর সংযোগ বিচ্ছিন্ন করুন"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"নীতিগুলি দেখুন"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"আপনার ডিভাইসটি <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> এর দ্বারা পরিচালিত হয়।\n\nআপনার প্রশাসক এই ডিভাইসের সেটিংস, কর্পোরেট অ্যাক্সেস, অ্যাপ, ডিভাইসের সাথে সম্পর্কিত ডেটা এবং ডিভাইসের লোকেশন তথ্য নিরীক্ষণ ও পরিচালনা করতে পারেন।\n\nআরও তথ্যের জন্য আপনার প্রশাসকের সাথে যোগাযোগ করুন।"</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"আপনার ডিভাইসটি আপনার প্রতিষ্ঠানের দ্বারা পরিচালিত হয়।\n\nআপনার প্রশাসক এই ডিভাইসের সেটিংস, কর্পোরেট অ্যাক্সেস, অ্যাপ, ডিভাইসের সাথে সম্পর্কিত ডেটা এবং ডিভাইসের লোকেশন তথ্য নিরীক্ষণ ও পরিচালনা করতে পারেন।\n\nআরও তথ্যের জন্য আপনার প্রশাসকের সাথে যোগাযোগ করুন।"</string>
+ <!-- no translation found for monitoring_description_named_management (505833016545056036) -->
+ <skip />
+ <!-- no translation found for monitoring_description_management (4308879039175729014) -->
+ <skip />
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"আপনার প্রতিষ্ঠান আপনার অফিস প্রোফাইলে একটি সার্টিফিকেট কর্তৃপক্ষ ইনস্টল করেছে।আপনার সুরক্ষিত নেটওয়ার্ক ট্রাফিক নিরীক্ষণ বা পরিবর্তন করা হতে পারে।"</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"আপনার প্রতিষ্ঠান আপনার অফিস প্রোফাইলে একটি সার্টিফিকেট কর্তৃপক্ষ ইনস্টল করেছে। আপনার নিরাপদ নেটওয়ার্ক ট্রাফিকে নজর রাখা হতে পারে বা তাতে পরিবর্তন করা হতে পারে।"</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"এই ডিভাইসে একটি সার্টিফিকেট কর্তৃপক্ষ ইনস্টল করা আছে। আপনার নিরাপদ নেটওয়ার্ক ট্রাফিকে নজর রাখা হতে পারে বা তাতে পরিবর্তন করা হতে পারে।"</string>
@@ -920,6 +936,7 @@
<string name="pip_pause" msgid="1139598607050555845">"বিরাম দিন"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"এগিয়ে যাওয়ার জন্য এড়িয়ে যান"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"পিছনে যাওয়ার জন্য এড়িয়ে যান"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"রিসাইজ করুন"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"আপনার ফোন গরম হওয়ার জন্য বন্ধ হয়ে গেছে"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"আপনার ফোন এখন ঠিক-ঠাক চলছে"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"আপনার ফোন খুব বেশি গরম হয়েছিল বলে ঠাণ্ডা হওয়ার জন্য বন্ধ হয়ে গেছে। আপনার ফোন ঠিক-ঠাক ভাবে চলছে না।\n\nআপনার ফোন খুব বেশি গরম হয়ে যাবে যদি আপনি:\n •এমন অ্যাপ ব্যবহার করলে যেটি আপনার ডিভাইসের রিসোর্স বেশি ব্যবহার করে (যেমন গেমিং, ভিডিও বা নেভিগেশন অ্যাপ)\n • বড় ফাইল ডাউনলোড বা আপলোড করলে\n • বেশি তাপমাত্রায় আপনার ফোন ব্যবহার করলে"</string>
@@ -994,7 +1011,7 @@
<string name="bubbles_settings_button_description" msgid="7324245408859877545">"<xliff:g id="APP_NAME">%1$s</xliff:g> বাবলের জন্য সেটিংস"</string>
<string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"ওভারফ্লো"</string>
<string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"স্ট্যাকে আবার যোগ করুন"</string>
- <string name="manage_bubbles_text" msgid="6856830436329494850">"ম্যানেজ করা"</string>
+ <string name="manage_bubbles_text" msgid="6856830436329494850">"ম্যানেজ করুন"</string>
<string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="APP_NAME">%2$s</xliff:g> অ্যাপ থেকে <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="APP_NAME">%2$s</xliff:g> অ্যাপ এবং আরও <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>টি থেকে <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_accessibility_action_move" msgid="3185080443743819178">"সরান"</string>
@@ -1007,7 +1024,7 @@
<string name="bubbles_user_education_title" msgid="5547017089271445797">"বাবল ব্যবহার করে চ্যাট করুন"</string>
<string name="bubbles_user_education_description" msgid="1160281719576715211">"নতুন কথোপকথন ভেসে থাকা আইকন বা বাবল হিসেবে দেখানো হয়। বাবল খুলতে ট্যাপ করুন। সেটি সরাতে ধরে টেনে আনুন।"</string>
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"যেকোনও সময় বাবল নিয়ন্ত্রণ করুন"</string>
- <string name="bubbles_user_education_manage" msgid="1391639189507036423">"এই অ্যাপ থেকে বাবল বন্ধ করতে ম্যানেজ করুন বিকল্প ট্যাপ করুন"</string>
+ <string name="bubbles_user_education_manage" msgid="1391639189507036423">"এই অ্যাপ থেকে বাবল বন্ধ করতে \'ম্যানেজ করুন\' বিকল্প ট্যাপ করুন"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"বুঝেছি"</string>
<string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> সেটিংস"</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"সিস্টেম নেভিগেশন আপডেট হয়েছে। পরিবর্তন করার জন্য সেটিংসে যান।"</string>
@@ -1015,7 +1032,7 @@
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"স্ট্যান্ডবাই"</string>
<string name="priority_onboarding_title" msgid="2893070698479227616">"কথোপকথনকে \'গুরুত্বপূর্ণ\' হিসেবে সেট করা হয়েছে"</string>
<string name="priority_onboarding_behavior" msgid="5342816047020432929">"গুরুত্বপূর্ণ কথোপকথন:"</string>
- <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"কথোপকথনের বিভাগের উপরে দেখান"</string>
+ <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"কথোপকথন বিভাগের একদম উপরে দেখুন"</string>
<string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"লক স্ক্রিনে প্রোফাইল ছবি দেখান"</string>
<string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"অ্যাপের উপরে একটি ভাসমান বুদবুদ হিসেবে দেখা যাবে"</string>
<string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"বিরক্ত করবে না মোডে ব্যাঘাত ঘটাতে পারে"</string>
@@ -1045,7 +1062,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"কন্ট্রোলগুলিকে আবার সাজানোর জন্য ধরে রেখে টেনে আনুন"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"সমস্ত কন্ট্রোল সরানো হয়েছে"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"পরিবর্তন সেভ করা হয়নি"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"সব কন্ট্রোলের তালিকা লোড করা যায়নি।"</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"কন্ট্রোল লোড করা যায়নি। অ্যাপ সেটিংসে কোনও পরিবর্তন করা হয়েছে কিনা তা ভাল করে দেখে নিতে <xliff:g id="APP">%s</xliff:g> অ্যাপ চেক করুন।"</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"মানানসই কন্ট্রোল উপলভ্য নেই"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"অন্য"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"ডিভাইস কন্ট্রোলে যোগ করুন"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"যোগ করুন"</string>
@@ -1061,8 +1079,11 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"<xliff:g id="DEVICE">%s</xliff:g>-এর জন্য পরিবর্তন কনফার্ম করুন"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"আরও দেখতে সোয়াইপ করুন"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"সাজেশন লোড করা হচ্ছে"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"এই মিডিয়া সেশন বেছে নিন"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"মিডিয়া"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"বর্তমান সেশন লুকান।"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"লুকান"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"আবার চালু করুন"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"সেটিংস"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"বন্ধ আছে, অ্যাপ চেক করুন"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"সমস্যা, আবার চেষ্টা করা হচ্ছে…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"খুঁজে পাওয়া যায়নি"</string>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 49fae626fa5a..f9c92e5a2c8d 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -57,12 +57,12 @@
<string name="label_view" msgid="6815442985276363364">"Prikaži"</string>
<string name="always_use_device" msgid="210535878779644679">"Uvijek otvori aplikaciju <xliff:g id="APPLICATION">%1$s</xliff:g> kada se poveže <xliff:g id="USB_DEVICE">%2$s</xliff:g>"</string>
<string name="always_use_accessory" msgid="1977225429341838444">"Uvijek otvori aplikaciju <xliff:g id="APPLICATION">%1$s</xliff:g> kada se poveže <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>"</string>
- <string name="usb_debugging_title" msgid="8274884945238642726">"Omogućiti otklanjanje grešaka putem uređaja spojenog na USB?"</string>
+ <string name="usb_debugging_title" msgid="8274884945238642726">"Omogućiti otklanjanje grešaka putem USB-a?"</string>
<string name="usb_debugging_message" msgid="5794616114463921773">"RSA otisak prsta za otključavanje računara je: \n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
<string name="usb_debugging_always" msgid="4003121804294739548">"Uvijek dozvoli sa ovog računara"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"Dozvoli"</string>
- <string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"Otklanjanje grešaka putem uređaja spojenog na USB nije dozvoljeno"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"Korisnik koji je trenutno prijavljen na ovaj uređaj ne može uključiti opciju za otklanjanje grešaka koristeći USB. Da koristite tu funkciju, prebacite se na primarnog korisnika."</string>
+ <string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"Otklanjanje grešaka putem USB-a nije dozvoljeno"</string>
+ <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"Korisnik koji je trenutno prijavljen na ovaj uređaj ne može uključiti opciju za otklanjanje grešaka putem USB-a. Da koristite tu funkciju, prebacite se na primarnog korisnika."</string>
<string name="wifi_debugging_title" msgid="7300007687492186076">"Dozvoliti bežično otklanjanje grešaka na ovoj mreži?"</string>
<string name="wifi_debugging_message" msgid="5461204211731802995">"Naziv mreže (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nAdresa WiFi mreže (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string>
<string name="wifi_debugging_always" msgid="2968383799517975155">"Uvijek dozvoli na ovoj mreži"</string>
@@ -456,8 +456,8 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Dodirnite ponovo da otvorite"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Prevucite da otvorite"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Prevucite prema gore da pokušate ponovo"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"Ovim uređajem upravlja vaša organizacija"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"Ovim uređajem upravlja <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
+ <string name="do_disclosure_generic" msgid="4896482821974707167">"Ovaj uređaj pripada vašoj organizaciji"</string>
+ <string name="do_disclosure_with_name" msgid="2091641464065004091">"Ovaj uređaj pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="6682125338461375925">"Prevucite preko ikone da otvorite telefon"</string>
<string name="voice_hint" msgid="7476017460191291417">"Prevucite preko ikone za glasovnu pomoć"</string>
<string name="camera_hint" msgid="4519495795000658637">"Prevucite od ikone da otvorite kameru"</string>
@@ -524,21 +524,21 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"Profil može biti nadziran"</string>
<string name="vpn_footer" msgid="3457155078010607471">"Mreža može biti nadzirana"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"Mreža može biti nadzirana"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"Vaša organizacija upravlja ovim uređajem i može pratiti mrežni saobraćaj."</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> upravlja ovim uređajem i može pratiti vaš mrežni saobraćaj"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"Uređajem upravlja vaša organizacija i povezan je s aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"Uređajem upravlja <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> i povezan je s aplikacijom <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"Uređajem upravlja vaša organizacija"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"Ovim uređajem upravlja <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>."</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"Uređajem upravlja vaša organizacija i povezan je s VPN-ovima"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"Uređajem upravlja <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> i povezan je s VPN-ovima"</string>
+ <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Vaša organizacija je vlasnik ovog uređaja i može nadzirati mrežni saobraćaj"</string>
+ <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> upravlja ovim uređajem i može nadzirati mrežni saobraćaj"</string>
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Ovaj uređaj pripada vašoj organizaciji i povezan je s aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Ovaj uređaj pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> i povezan je s aplikacijom <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Ovaj uređaj pripada vašoj organizaciji"</string>
+ <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Ovaj uređaj pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management_vpns" msgid="371835422690053154">"Ovaj uređaj pripada vašoj organizaciji i povezan je s VPN-ovima"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="4046375645500668555">"Ovaj uređaj pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> i povezan je VPN-ovima"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Vaša organizacija može pratiti mrežni saobraćaj na vašem profilu."</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> može pratiti mrežni saobraćaj na vašem radnom profilu"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Mreža može biti nadzirana"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"Uređaj je povezan s VPN-ovima"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"Radni profil je povezan s aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"Lični profil je povezan s aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"Uređaj je povezan s aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_vpns" msgid="7213546797022280246">"Ovaj uređaj je povezan VPN-ovima"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Vaš radni profil je povezan s aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Vaš lični profil je povezan s aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Ovaj uređaj je povezan s aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Upravljanje uređajem"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Praćenje profila"</string>
<string name="monitoring_title" msgid="4063890083735924568">"Praćenje mreže"</string>
@@ -548,8 +548,8 @@
<string name="disable_vpn" msgid="482685974985502922">"Isključi VPN"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"Prekini VPN vezu"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"Prikaži pravila"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"Vašim uređajem upravlja organizacija <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nVaš administrator može nadgledati i upravljati vašim postavkama, korporativnom pristupu, aplikacijama, podacima koji su povezani s vašim uređajem i informacijama o lokaciji vašeg uređaja.\n\nZa više informacija, obratite se svom administratoru."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"Vašim uređajem upravlja vaša organizacija.\n\nVaš administrator može nadgledati i upravljati vašim postavkama, korporativnom pristupu, aplikacijama, podacima koji su povezani s vašim uređajem i informacijama o lokaciji vašeg uređaja.\n\nZa više informacija, obratite se svom administratoru."</string>
+ <string name="monitoring_description_named_management" msgid="505833016545056036">"Ovaj uređaj pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nVaš IT administrator može nadzirati postavke, korporativni pristup, aplikacije, podatke povezane s vašim uređajem i informacije o lokaciji uređaja te njima upravljati.\n\nZa više informacija, kontaktirajte IT administratora."</string>
+ <string name="monitoring_description_management" msgid="4308879039175729014">"Ovaj uređaj pripada vašoj organizaciji.\n\nVaš IT administrator može nadzirati postavke, korporativni pristup, aplikacije, podatke povezane s vašim uređajem i informacije o lokaciji uređaja te njima upravljati.\n\nZa više informacija, kontaktirajte IT administratora."</string>
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Vaša organizacija je instalirala CA certifikat na ovom uređaju. Vaš saobraćaj preko sigurne mreže može se pratiti."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Vaša organizacija je instalirala CA certifikat na vašem radnom profilu. Vaš saobraćaj preko sigurne mreže može se pratiti."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"CA certifikat je instaliran na ovom uređaju. Vaš saobraćaj preko sigurne mreže može se pratiti."</string>
@@ -927,6 +927,7 @@
<string name="pip_pause" msgid="1139598607050555845">"Pauziraj"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"Preskoči na sljedeći"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"Preskoči na prethodni"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"Promjena veličine"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"Telefon se isključio zbog pregrijavanja"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"Vaš telefon sada radi normalno"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Vaš telefon se pregrijao, pa se isključio da se ohladi. Telefon sada radi normalno.\n\nTelefon se može pregrijati ako:\n • Koristite aplikacije koje troše puno resursa (kao što su aplikacije za igranje, videozapise ili navigaciju)\n • Preuzimate ili otpremate velike fajlove\n • Koristite telefon na visokim temperaturama"</string>
@@ -1013,7 +1014,7 @@
<string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Nemoj prikazivati razgovor u oblačićima"</string>
<string name="bubbles_user_education_title" msgid="5547017089271445797">"Chatajte koristeći oblačiće"</string>
<string name="bubbles_user_education_description" msgid="1160281719576715211">"Novi razgovori se prikazuju kao plutajuće ikone ili oblačići. Dodirnite da otvorite oblačić. Prevucite da ga premjestite."</string>
- <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Upravljajte oblačićima u svakom momentu"</string>
+ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Upravljajte oblačićima u svakom trenutku"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"Dodirnite Upravljaj da isključite oblačiće iz ove aplikacije"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Razumijem"</string>
<string name="bubbles_app_settings" msgid="5779443644062348657">"Postavke aplikacije <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
@@ -1022,8 +1023,8 @@
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Stanje mirovanja"</string>
<string name="priority_onboarding_title" msgid="2893070698479227616">"Razgovor je postavljen kao prioritetan"</string>
<string name="priority_onboarding_behavior" msgid="5342816047020432929">"Prioritetni razgovori će:"</string>
- <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Prikazuje se na vrhu odjeljka za razgovor"</string>
- <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Prikazuje sliku profila na zaključanom ekranu"</string>
+ <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Biti prikazani na vrhu odjeljka za razgovor"</string>
+ <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Prikazivati sliku profila na zaključanom ekranu"</string>
<string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Izgleda kao plutajući oblačić iznad aplikacija"</string>
<string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Prekida način rada Ne ometaj"</string>
<string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Razumijem"</string>
@@ -1053,7 +1054,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Držite i prevucite da preuredite kontrole"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"Sve kontrole su uklonjene"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Promjene nisu sačuvane"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"Učitavanje liste svih kontrola nije uspjelo."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"Učitavanje kontrola nije uspjelo. Provjerite aplikaciju <xliff:g id="APP">%s</xliff:g> da se uvjerite da postavke aplikacije nisu izmijenjene."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"Kompatibilne kontrole su nedostupne"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Drugo"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"Dodajte u kontrole uređaja"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"Dodaj"</string>
@@ -1069,13 +1071,16 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"Potvrdite promjenu za uređaj <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Prevucite da vidite više"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Učitavanje preporuka"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"Zatvori ovu medijsku sesiju"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"Mediji"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"Sakrijte trenutnu sesiju."</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Sakrij"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Nastavi"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"Postavke"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Neaktivno, vidite aplikaciju"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Greška, ponovni pokušaj…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Nije pronađeno"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"Kontrola nije dostupna"</string>
- <string name="controls_error_removed_message" msgid="2885911717034750542">"Pristup uređaju <xliff:g id="DEVICE">%1$s</xliff:g> nije uspio. Provjerite aplikaciju <xliff:g id="APPLICATION">%2$s</xliff:g> da se uvjerite da je kontrola i dalje dostupna i da se postavke aplikacije nisu promijenile."</string>
+ <string name="controls_error_removed_message" msgid="2885911717034750542">"Pristupanje uređaju <xliff:g id="DEVICE">%1$s</xliff:g> nije uspjelo. Provjerite aplikaciju <xliff:g id="APPLICATION">%2$s</xliff:g> da se uvjerite da je kontrola i dalje dostupna i da se postavke aplikacije nisu promijenile."</string>
<string name="controls_open_app" msgid="483650971094300141">"Otvori aplikaciju"</string>
<string name="controls_error_generic" msgid="352500456918362905">"Nije moguće učitati status"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Greška, pokušajte ponovo"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 5cc0853a6e18..0315e3fa861a 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -454,8 +454,8 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Torna a tocar per obrir-la."</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Llisca cap amunt per obrir"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Llisca cap a dalt per tornar-ho a provar"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"La teva organització gestiona aquest dispositiu"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> gestiona aquest dispositiu"</string>
+ <string name="do_disclosure_generic" msgid="4896482821974707167">"Aquest dispositiu pertany a la teva organització"</string>
+ <string name="do_disclosure_with_name" msgid="2091641464065004091">"Aquest dispositiu pertany a <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="6682125338461375925">"Llisca des de la icona per obrir el telèfon"</string>
<string name="voice_hint" msgid="7476017460191291417">"Llisca des de la icona per obrir l\'assistent de veu"</string>
<string name="camera_hint" msgid="4519495795000658637">"Llisca des de la icona per obrir la càmera"</string>
@@ -521,21 +521,21 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"El perfil es pot supervisar"</string>
<string name="vpn_footer" msgid="3457155078010607471">"És possible que la xarxa estigui supervisada."</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"És possible que la xarxa estigui supervisada"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"La teva organització gestiona aquest dispositiu i és possible que també supervisi el trànsit de xarxa"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> gestiona aquest dispositiu i és possible que també supervisi el trànsit de xarxa"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"Dispositiu gestionat per la teva organització i connectat a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> gestiona el dispositiu, que està connectat a <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"La teva organització gestiona el dispositiu"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> gestiona el dispositiu"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"Dispositiu gestionat per la teva organització i connectat a xarxes VPN"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> gestiona el dispositiu, que està connectat a xarxes VPN"</string>
+ <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"La teva organització és propietària del dispositiu i és possible que supervisi el trànsit de xarxa"</string>
+ <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> és propietària d\'aquest dispositiu i és possible que supervisi el trànsit de xarxa"</string>
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Aquest dispositiu pertany a la teva organització i està connectat a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Aquest dispositiu pertany a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> i està connectat a <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Aquest dispositiu pertany a la teva organització"</string>
+ <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Aquest dispositiu pertany a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management_vpns" msgid="371835422690053154">"Aquest dispositiu pertany a la teva organització i està connectat a xarxes VPN"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="4046375645500668555">"Aquest dispositiu pertany a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> i està connectat a xarxes VPN"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"És possible que la teva organització supervisi el trànsit de xarxa al teu perfil de treball"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"És possible que <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> supervisi el trànsit de xarxa del teu perfil de treball"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"És possible que la xarxa estigui supervisada"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"El dispositiu està connectat a xarxes VPN"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"El perfil de treball està connectat a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"El perfil de treball està connectat a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"El dispositiu està connectat a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_vpns" msgid="7213546797022280246">"Aquest dispositiu està connectat a xarxes VPN"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"El teu perfil de treball està connectat a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"El teu perfil personal està connectat a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Aquest dispositiu està connectat a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Gestió del dispositiu"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Supervisió del perfil"</string>
<string name="monitoring_title" msgid="4063890083735924568">"Supervisió de la xarxa"</string>
@@ -545,8 +545,8 @@
<string name="disable_vpn" msgid="482685974985502922">"Desactiva la VPN"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"Desconnecta la VPN"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"Consulta les polítiques"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> gestiona el dispositiu.\n\nL\'administrador pot supervisar i gestionar la configuració, l\'accés corporatiu, les aplicacions, les dades associades al dispositiu, inclosa la informació d\'ubicació.\n\nPer obtenir més informació, contacta amb l\'administrador."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"La teva organització gestiona el dispositiu.\n\nL\'administrador pot supervisar i gestionar la configuració, l\'accés corporatiu, les aplicacions, les dades associades al dispositiu, inclosa la informació d\'ubicació.\n\nPer obtenir més informació, contacta amb l\'administrador."</string>
+ <string name="monitoring_description_named_management" msgid="505833016545056036">"El dispositiu pertany a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nL\'administrador de TI pot supervisar i gestionar la configuració, l\'accés corporatiu, les aplicacions, les dades associades al dispositiu i la informació d\'ubicació.\n\nPer obtenir més informació, contacta amb l\'administrador de TI."</string>
+ <string name="monitoring_description_management" msgid="4308879039175729014">"El dispositiu pertany a la teva organització.\n\nL\'administrador de TI pot supervisar i gestionar la configuració, l\'accés corporatiu, les aplicacions, les dades associades al dispositiu i la informació d\'ubicació.\n\nPer obtenir més informació, contacta amb l\'administrador de TI."</string>
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"La teva organització ha instal·lat una autoritat de certificació en aquest dispositiu. És possible que el trànsit a la xarxa segura se supervisi o es modifiqui."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"La teva organització ha instal·lat una autoritat de certificació al teu perfil de treball. És possible que el trànsit de xarxa segura se supervisi o es modifiqui."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"S\'ha instal·lat una autoritat de certificació en aquest dispositiu. És possible que el trànsit de xarxa segura se supervisi o es modifiqui."</string>
@@ -920,6 +920,7 @@
<string name="pip_pause" msgid="1139598607050555845">"Posa en pausa"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"Ves al següent"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"Torna a l\'anterior"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"Canvia la mida"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"Telèfon apagat per la calor"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"Ara el telèfon funciona de manera normal"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"El telèfon s\'havia sobreescalfat i s\'ha apagat per refredar-se. Ara funciona amb normalitat.\n\nEs pot sobreescalfar si:\n • utilitzes aplicacions que consumeixen molts recursos (com ara, videojocs, vídeos o aplicacions de navegació);\n • baixes o penges fitxers grans;\n • l\'utilitzes amb temperatures altes."</string>
@@ -1015,8 +1016,8 @@
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"En espera"</string>
<string name="priority_onboarding_title" msgid="2893070698479227616">"La conversa s\'ha definit com a prioritària"</string>
<string name="priority_onboarding_behavior" msgid="5342816047020432929">"Les converses prioritàries:"</string>
- <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Mostra a la part superior de la secció de converses"</string>
- <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Mostra la foto de perfil a la pantalla de bloqueig"</string>
+ <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Es mostraran a la part superior de la secció de converses"</string>
+ <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Mostraran la foto de perfil a la pantalla de bloqueig"</string>
<string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Es mostra com a bombolla flotant en primer pla"</string>
<string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Interromp el mode No molestis"</string>
<string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Entesos"</string>
@@ -1045,7 +1046,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Mantén premut i arrossega per reorganitzar els controls"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"S\'han suprimit tots els controls"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Els canvis no s\'han desat"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"No s\'ha pogut carregar la llista completa de controls."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"No s\'han pogut carregar els controls. Consulta l\'aplicació <xliff:g id="APP">%s</xliff:g> per assegurar-te que la configuració de l\'aplicació no hagi canviat."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"Els controls compatibles no estan disponibles"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Altres"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"Afegeix als controls de dispositius"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"Afegeix"</string>
@@ -1061,8 +1063,11 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"Confirma el canvi per a <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Llisca per veure\'n més"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Carregant les recomanacions"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"Tanca aquesta sessió multimèdia"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"Multimèdia"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"Amaga la sessió actual."</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Amaga"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Reprèn"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"Configuració"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inactiu; comprova l\'aplicació"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Error. S\'està tornant a provar…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"No s\'ha trobat"</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index a071793af881..aa5401edf301 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -458,8 +458,8 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Oznámení otevřete opětovným klepnutím"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Otevřete přejetím prstem nahoru"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Přejetím nahoru to zkusíte znovu"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"Toto zařízení spravuje vaše organizace"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"Toto zařízení je spravováno organizací <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
+ <string name="do_disclosure_generic" msgid="4896482821974707167">"Toto zařízení patří vaší organizaci"</string>
+ <string name="do_disclosure_with_name" msgid="2091641464065004091">"Toto zařízení patří organizaci <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="6682125338461375925">"Telefon otevřete přejetím prstem od ikony"</string>
<string name="voice_hint" msgid="7476017460191291417">"Hlasovou asistenci otevřete přejetím prstem od ikony"</string>
<string name="camera_hint" msgid="4519495795000658637">"Fotoaparát otevřete přejetím prstem od ikony"</string>
@@ -527,21 +527,21 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"Profil může být monitorován"</string>
<string name="vpn_footer" msgid="3457155078010607471">"Síť může být sledována"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"Síť může být monitorována"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"Toto zařízení spravuje vaše organizace, která může sledovat síťový provoz"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> spravuje toto zařízení a může sledovat síťový provoz"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"Zařízení spravuje vaše organizace a je připojeno k aplikaci <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"Zařízení spravuje organizace <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> a je připojeno k aplikaci <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"Zařízení je spravováno vaší organizací"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"Toto zařízení spravuje organizace <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"Zařízení spravuje vaše organizace a je připojeno k sítím VPN"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"Zařízení spravuje organizace <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> a je připojeno k sítím VPN"</string>
+ <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Toto zařízení vlastní vaše organizace, která může sledovat síťový provoz"</string>
+ <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Toto zařízení spravuje organizace <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>, která může sledovat síťový provoz"</string>
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Toto zařízení patří vaší organizaci a je připojené k síti <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Toto zařízení patří organizaci <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> a je připojené k síti <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Toto zařízení patří vaší organizaci"</string>
+ <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Toto zařízení patří organizaci <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management_vpns" msgid="371835422690053154">"Toto zařízení patří vaší organizaci a je připojené k sítím VPN"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="4046375645500668555">"Toto zařízení patří organizaci <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> a je připojené k sítím VPN"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Organizace může ve vašem pracovním profilu sledovat síťový provoz"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> může ve vašem pracovním profilu sledovat síťový provoz"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Síť může být sledována"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"Zařízení je připojeno k sítím VPN"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"Pracovní profil je připojen k aplikaci <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"Osobní profil je připojen k aplikaci <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"Zařízení je připojeno k aplikaci <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_vpns" msgid="7213546797022280246">"Toto zařízení je připojené k sítím VPN"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Váš pracovní profil je připojen k síti <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Váš osobní profil je připojený k síti <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Toto zařízení je připojené k síti <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Správa zařízení"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Monitoring profilu"</string>
<string name="monitoring_title" msgid="4063890083735924568">"Sledování sítě"</string>
@@ -551,8 +551,8 @@
<string name="disable_vpn" msgid="482685974985502922">"Deaktivovat VPN"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"Odpojit VPN"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"Zobrazit zásady"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"Toto zařízení spravuje organizace <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nAdministrátor může sledovat a spravovat nastavení, firemní přístup, aplikace, data přidružená k tomuto zařízení a jeho polohu.\n\nDalší informace vám poskytne administrátor."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"Zařízení spravuje vaše organizace.\n\nAdministrátor může sledovat a spravovat nastavení, firemní přístup, aplikace, data přidružená k tomuto zařízení a jeho polohu.\n\nDalší informace vám poskytne administrátor."</string>
+ <string name="monitoring_description_named_management" msgid="505833016545056036">"Toto zařízení patří organizaci <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nVáš administrátor IT může sledovat a spravovat nastavení, firemní přístup, aplikace, data přidružená k tomuto zařízení a jeho polohu.\n\nDalší informace vám poskytne váš administrátor IT."</string>
+ <string name="monitoring_description_management" msgid="4308879039175729014">"Toto zařízení patří vaší organizaci\n\nVáš administrátor IT může sledovat a spravovat nastavení, firemní přístup, aplikace, data přidružená k tomuto zařízení a jeho polohu.\n\nDalší informace vám poskytne váš administrátor IT."</string>
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Organizace do tohoto zařízení nainstalovala certifikační autoritu. Zabezpečený síťový provoz může být sledován nebo upravován."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Organizace do vašeho pracovního profilu nainstalovala certifikační autoritu. Zabezpečený síťový provoz může být sledován nebo upravován."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"V zařízení je nainstalována certifikační autorita. Zabezpečený síťový provoz může být sledován nebo upravován."</string>
@@ -930,6 +930,7 @@
<string name="pip_pause" msgid="1139598607050555845">"Pozastavit"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"Přeskočit na další"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"Přeskočit na předchozí"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"Změnit velikost"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"Telefon se vypnul z důvodu zahřátí"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"Nyní telefon funguje jako obvykle."</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Telefon byl příliš zahřátý, proto se vypnul, aby vychladl. Nyní telefon funguje jako obvykle.\n\nTelefon se může příliš zahřát v těchto případech:\n • používání náročných aplikací (např. her, videí nebo navigace),\n • stahování nebo nahrávání velkých souborů,\n • používání telefonu při vysokých teplotách."</string>
@@ -1019,7 +1020,7 @@
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Nastavení bublin můžete kdykoli upravit"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"Bubliny pro tuto aplikaci můžete vypnout klepnutím na Spravovat"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Rozumím"</string>
- <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> – nastavení"</string>
+ <string name="bubbles_app_settings" msgid="5779443644062348657">"Nastavení <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Systémová navigace byla aktualizována. Chcete-li provést změny, přejděte do Nastavení."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Přejděte do Nastavení a aktualizujte systémovou navigaci"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Pohotovostní režim"</string>
@@ -1057,7 +1058,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Ovládací prvky můžete uspořádat podržením a přetažením"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"Všechny ovládací prvky byly odstraněny"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Změny nebyly uloženy"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"Načtení seznamu všech ovládacích prvků se nezdařilo."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"Ovládací prvky se nepodařilo načíst. V aplikaci <xliff:g id="APP">%s</xliff:g> zkontrolujte, zda se nezměnilo nastavení."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"Kompatibilní ovládání není k dispozici"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Jiné"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"Přidání ovládání zařízení"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"Přidat"</string>
@@ -1073,8 +1075,11 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"Ověřte změnu v zařízení <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Přejetím prstem zobrazíte další položky"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Načítání doporučení"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"Zavřít tuto mediální relaci"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"Média"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"Skrýt aktuální relaci."</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Skrýt"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Pokračovat"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"Nastavení"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Neaktivní, zkontrolujte aplikaci"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Chyba. Nový pokus…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Nenalezeno"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index f1bbbff3d7b6..0bd63587f6e7 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -454,8 +454,8 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Tryk igen for at åbne"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Stryg opad for at åbne"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Stryg opad for at prøve igen"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"Denne enhed administreres af din organisation"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"Denne enhed administreres af <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
+ <string name="do_disclosure_generic" msgid="4896482821974707167">"Denne enhed tilhører din organisation"</string>
+ <string name="do_disclosure_with_name" msgid="2091641464065004091">"Denne enhed tilhører <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="6682125338461375925">"Stryg fra telefonikonet"</string>
<string name="voice_hint" msgid="7476017460191291417">"Stryg fra mikrofonikonet"</string>
<string name="camera_hint" msgid="4519495795000658637">"Stryg fra kameraikonet"</string>
@@ -521,21 +521,21 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"Profilen kan overvåges"</string>
<string name="vpn_footer" msgid="3457155078010607471">"Netværket kan være overvåget"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"Netværket kan være overvåget"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"Din organisation administrerer denne enhed og kan overvåge netværkstrafik"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> administrerer denne enhed og kan overvåge netværkstrafik"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"Enheden administreres af din organisation og er forbundet til <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"Enheden administreres af <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> og er forbundet til <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"Enheden administreres af din organisation"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"Enheden administreres af <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"Enheden administreres af din organisation og er forbundet til VPN-netværk"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"Enheden administreres af <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> og er forbundet til VPN-netværk"</string>
+ <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Din organisation ejer denne enhed og overvåger muligvis netværkstrafikken"</string>
+ <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ejer denne enhed og overvåger muligvis netværkstrafikken"</string>
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Denne enhed tilhører din organisation og har forbindelse til <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Denne enhed tilhører <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> og har forbindelse til <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Denne enhed tilhører din organisation"</string>
+ <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Denne enhed tilhører <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management_vpns" msgid="371835422690053154">"Denne enhed tilhører din organisation og har forbindelse til VPN-netværk"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="4046375645500668555">"Denne enhed tilhører <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> og har forbindelse til VPN-netværk"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Din organisation kan overvåge netværkstrafikken på din arbejdsprofil"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> kan overvåge netværkstrafik på din arbejdsprofil"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Netværket kan være overvåget"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"Enheden er forbundet til VPN-netværk"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"Arbejdsprofilen er forbundet til <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"Den personlige profil er forbundet til <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"Enheden er forbundet til <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_vpns" msgid="7213546797022280246">"Denne enhed har forbindelse til VPN-netværk"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Din arbejdsprofil har forbindelse til <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Din personlige profil har forbindelse til <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Denne enhed har forbindelse til <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Administration af enheder"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Profilovervågning"</string>
<string name="monitoring_title" msgid="4063890083735924568">"Overvågning af netværk"</string>
@@ -545,8 +545,8 @@
<string name="disable_vpn" msgid="482685974985502922">"Deaktiver VPN"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"Afbryd VPN-forbindelse"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"Se politikker"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"Din enhed administreres af <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nDin administrator kan overvåge og administrere indstillinger, virksomhedsadgang, apps, data, der er knyttet til din enhed, og din enheds stedoplysninger.\n\nKontakt din administrator, hvis du vil have flere oplysninger."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"Din enhed administreres af din organisation.\n\nDin administrator kan overvåge og administrere indstillinger, virksomhedsadgang, apps, data, der er knyttet til din enhed, og din enheds stedoplysninger.\n\nKontakt din administrator, hvis du vil have flere oplysninger."</string>
+ <string name="monitoring_description_named_management" msgid="505833016545056036">"Denne enhed tilhører <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nDin it-administrator kan overvåge og administrere indstillinger, virksomhedsadgang, apps, data, der er tilknyttet din enhed, og din enheds placeringsdata.\n\nKontakt din it-administrator for at få mere at vide."</string>
+ <string name="monitoring_description_management" msgid="4308879039175729014">"Denne enhed tilhører din organisation.\n\nDin it-administrator kan overvåge og administrere indstillinger, virksomhedsadgang, apps, data, der er tilknyttet din enhed, og din enheds placeringsdata.\n\nKontakt din it-administrator for at få mere at vide."</string>
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Din organisation har installeret et nøglecenter på denne enhed. Din sikre netværkstrafik kan overvåges eller ændres."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Din organisation har installeret et nøglecenter på din arbejdsprofil. Din sikre netværkstrafik kan overvåges eller ændres."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Der er installeret et nøglecenter på denne enhed. Din sikre netværkstrafik kan overvåges eller ændres."</string>
@@ -920,6 +920,7 @@
<string name="pip_pause" msgid="1139598607050555845">"Sæt på pause"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"Gå videre til næste"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"Gå til forrige"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"Rediger størrelse"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"Telefonen slukkede pga. varme"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"Din telefon kører nu normalt"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Din telefon var blevet for varm, så den slukkede for at køle ned. Din telefon kører nu igen normalt. \n\nDin telefon kan blive for varm, hvis du:\n • Bruger ressourcekrævende apps (f.eks. spil, video eller navigation)\n • Downloader eller uploader store filer\n • Bruger din telefon i varme omgivelser"</string>
@@ -1002,7 +1003,7 @@
<string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Flyt op til højre"</string>
<string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Flyt ned til venstre"</string>
<string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Flyt ned til højre"</string>
- <string name="bubble_dismiss_text" msgid="1314082410868930066">"Afvis bobbel"</string>
+ <string name="bubble_dismiss_text" msgid="1314082410868930066">"Afvis boble"</string>
<string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Vis ikke samtaler i bobler"</string>
<string name="bubbles_user_education_title" msgid="5547017089271445797">"Chat ved hjælp af bobler"</string>
<string name="bubbles_user_education_description" msgid="1160281719576715211">"Nye samtaler vises som svævende ikoner eller bobler. Tryk for at åbne boblen. Træk for at flytte den."</string>
@@ -1013,10 +1014,10 @@
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Systemnavigationen blev opdateret. Gå til Indstillinger for at foretage ændringer."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Gå til Indstillinger for at opdatere systemnavigationen"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Standby"</string>
- <string name="priority_onboarding_title" msgid="2893070698479227616">"Samtalen er angivet som prioritet"</string>
+ <string name="priority_onboarding_title" msgid="2893070698479227616">"Samtalen er angivet som prioriteret"</string>
<string name="priority_onboarding_behavior" msgid="5342816047020432929">"Følgende gælder for prioriterede samtaler:"</string>
- <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Vis i toppen af samtalesektionen"</string>
- <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Vis profilbillede på låseskærm"</string>
+ <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Vises øverst i samtalesektionen"</string>
+ <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Viser profilbillede på låseskærm"</string>
<string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Vis som en boble oven på apps"</string>
<string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Afbryd Forstyr ikke"</string>
<string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"OK"</string>
@@ -1041,11 +1042,12 @@
<string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"fjern fra favoritter"</string>
<string name="accessibility_control_move" msgid="8980344493796647792">"Flyt til position <xliff:g id="NUMBER">%d</xliff:g>"</string>
<string name="controls_favorite_default_title" msgid="967742178688938137">"Betjeningselementer"</string>
- <string name="controls_favorite_subtitle" msgid="6604402232298443956">"Vælg, hvilke indstillinger der skal være i menuen for afbryderknappen"</string>
+ <string name="controls_favorite_subtitle" msgid="6604402232298443956">"Vælg de indstillinger, der skal vises i menuen for afbryderknappen"</string>
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Flyt rundt på styringselementer ved at holde dem nede og trække"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"Alle styringselementerne blev fjernet"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Ændringerne blev ikke gemt"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"Listen over styringselementer kunne ikke indlæses."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"Betjeningselementerne kunne ikke indlæses. Tjek <xliff:g id="APP">%s</xliff:g>-appen for at sørge for, at dine appindstillinger ikke er blevet ændret."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"Kompatible betjeningselementer er ikke tilgængelige"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Andre"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"Føj til enhedsstyring"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"Tilføj"</string>
@@ -1061,13 +1063,16 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"Bekræft ændring på <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Stryg for at se mere"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Indlæser anbefalinger"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"Luk denne mediesession"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"Medie"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"Skjul den aktuelle session."</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Skjul"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Genoptag"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"Indstillinger"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inaktiv. Tjek appen"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Fejl. Prøver igen…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Ikke fundet"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"Styringselement ikke tilgængeligt"</string>
- <string name="controls_error_removed_message" msgid="2885911717034750542">"Der kunne ikke skaffes adgang til <xliff:g id="DEVICE">%1$s</xliff:g>. Tjek <xliff:g id="APPLICATION">%2$s</xliff:g>-appen for at sikre at styringselementet stadig er tilgængeligt, og at appens indstillinger ikke er blevet ændret."</string>
+ <string name="controls_error_removed_message" msgid="2885911717034750542">"Der kunne ikke skaffes adgang til <xliff:g id="DEVICE">%1$s</xliff:g>. Tjek <xliff:g id="APPLICATION">%2$s</xliff:g>-appen for at sikre, at styringselementet stadig er tilgængeligt, og at appens indstillinger ikke er blevet ændret."</string>
<string name="controls_open_app" msgid="483650971094300141">"Åbn app"</string>
<string name="controls_error_generic" msgid="352500456918362905">"Statussen kan ikke indlæses"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Der opstod en fejl. Prøv igen"</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 3397cd615138..f7323bcaae17 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -454,8 +454,10 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Erneut tippen, um Benachrichtigung zu öffnen"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Zum Öffnen nach oben wischen"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Zum Wiederholen nach oben wischen"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"Dieses Gerät wird von deiner Organisation verwaltet"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"Dieses Gerät wird von <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> verwaltet"</string>
+ <!-- no translation found for do_disclosure_generic (4896482821974707167) -->
+ <skip />
+ <!-- no translation found for do_disclosure_with_name (2091641464065004091) -->
+ <skip />
<string name="phone_hint" msgid="6682125338461375925">"Zum Öffnen des Telefons vom Symbol wegwischen"</string>
<string name="voice_hint" msgid="7476017460191291417">"Zum Öffnen des Sprachassistenten vom Symbol wegwischen"</string>
<string name="camera_hint" msgid="4519495795000658637">"Zum Öffnen der Kamera vom Symbol wegwischen"</string>
@@ -510,8 +512,7 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"Alle löschen"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Verwalten"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Verlauf"</string>
- <!-- no translation found for notification_section_header_incoming (850925217908095197) -->
- <skip />
+ <string name="notification_section_header_incoming" msgid="850925217908095197">"Neu"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"Lautlos"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Benachrichtigungen"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Unterhaltungen"</string>
@@ -522,21 +523,33 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"Profil wird eventuell überwacht."</string>
<string name="vpn_footer" msgid="3457155078010607471">"Das Netzwerk wird eventuell überwacht."</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"Das Netzwerk wird eventuell überwacht"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"Deine Organisation verwaltet dieses Gerät und kann den Netzwerkverkehr überwachen"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> verwaltet dieses Gerät und kann den Netzwerkverkehr überwachen"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"Das Gerät wird von deiner Organisation verwaltet und ist mit <xliff:g id="VPN_APP">%1$s</xliff:g> verbunden"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"Das Gerät wird von <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> verwaltet und ist mit <xliff:g id="VPN_APP">%2$s</xliff:g> verbunden"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"Das Gerät wird von deiner Organisation verwaltet"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"Das Gerät wird von <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> verwaltet"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"Das Gerät wird von deiner Organisation verwaltet und ist mit VPNs verbunden"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"Das Gerät wird von <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> verwaltet und ist mit VPNs verbunden"</string>
+ <!-- no translation found for quick_settings_disclosure_management_monitoring (8231336875820702180) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_monitoring (2831423806103479812) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_named_vpn (6096715329056415588) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (5302786161534380104) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management (5515296598440684962) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management (3476472755775165827) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_vpns (371835422690053154) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_vpns (4046375645500668555) -->
+ <skip />
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Deine Organisation kann den Netzwerkverkehr in deinem Arbeitsprofil überwachen"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> kann den Netzwerkverkehr in deinem Arbeitsprofil überwachen"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Das Netzwerk wird eventuell überwacht"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"Das Gerät ist mit VPNs verbunden"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"Arbeitsprofil verbunden mit <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"Das persönliche Profil ist mit <xliff:g id="VPN_APP">%1$s</xliff:g> verbunden"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"Das Gerät ist mit <xliff:g id="VPN_APP">%1$s</xliff:g> verbunden"</string>
+ <!-- no translation found for quick_settings_disclosure_vpns (7213546797022280246) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (8117568745060010789) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (5481763430080807797) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_vpn (2350838218824492465) -->
+ <skip />
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Geräteverwaltung"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Profilüberwachung"</string>
<string name="monitoring_title" msgid="4063890083735924568">"Netzwerküberwachung"</string>
@@ -546,8 +559,10 @@
<string name="disable_vpn" msgid="482685974985502922">"VPN deaktivieren"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"VPN-Verbindung trennen"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"Richtlinien ansehen"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"Dein Gerät wird von <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> verwaltet.\n\nDein Administrator kann Einstellungen, Zugriffsrechte auf Unternehmensinhalte, Apps und Daten deines Geräts sowie dessen Standortinformationen überwachen und verwalten.\n\nWeitere Informationen erhältst du von deinem Administrator."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"Dein Gerät wird von deiner Organisation verwaltet.\n\nDein Administrator kann Einstellungen, Zugriffsrechte auf Unternehmensinhalte, Apps und Daten deines Geräts sowie dessen Standortinformationen überwachen und verwalten.\n\nWeitere Informationen erhältst du von deinem Administrator."</string>
+ <!-- no translation found for monitoring_description_named_management (505833016545056036) -->
+ <skip />
+ <!-- no translation found for monitoring_description_management (4308879039175729014) -->
+ <skip />
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Deine Organisation hat ein Zertifikat einer Zertifizierungsstelle auf deinem Gerät installiert. Eventuell wird dein sicherer Netzwerkverkehr überwacht oder bearbeitet."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Deine Organisation hat ein Zertifikat einer Zertifizierungsstelle in deinem Arbeitsprofil installiert. Eventuell wird dein sicherer Netzwerkverkehr überwacht oder bearbeitet."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Auf dem Gerät ist das Zertifikat einer Zertifizierungsstelle installiert. Eventuell wird dein sicherer Netzwerkverkehr überwacht oder bearbeitet."</string>
@@ -921,6 +936,7 @@
<string name="pip_pause" msgid="1139598607050555845">"Pausieren"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"Vorwärts springen"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"Rückwärts springen"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"Größe anpassen"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"Ausgeschaltet, da zu heiß"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"Dein Smartphone funktioniert jetzt wieder normal"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Dein Smartphone war zu heiß und wurde zum Abkühlen ausgeschaltet. Nun funktioniert es wieder normal.\n\nMögliche Ursachen:\n • Verwendung ressourcenintensiver Apps (z. B. Spiele-, Video- oder Navigations-Apps)\n • Download oder Upload großer Dateien \n • Verwendung des Smartphones bei hohen Temperaturen"</string>
@@ -1046,7 +1062,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Zum Verschieben von Steuerelementen halten und ziehen"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"Alle Steuerelemente entfernt"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Änderungen nicht gespeichert"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"Fehler beim Laden der Liste mit Steuerelementen."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"Steuerelemente konnten nicht geladen werden. Prüfe in der <xliff:g id="APP">%s</xliff:g> App, ob die Einstellungen möglicherweise geändert wurden."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"Kompatible Steuerelemente nicht verfügbar"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Andere"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"Zur Gerätesteuerung hinzufügen"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"Hinzufügen"</string>
@@ -1062,8 +1079,11 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"Änderung für <xliff:g id="DEVICE">%s</xliff:g> bestätigen"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Wischen, um weitere zu sehen"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Empfehlungen werden geladen"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"Diese Mediensitzung schließen"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"Medien"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"Du kannst die aktuelle Sitzung ausblenden."</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ausblenden"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Fortsetzen"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"Einstellungen"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inaktiv – sieh in der App nach"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Fehler. Neuer Versuch…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Nicht gefunden"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index f24f7457b0c6..84ae32324e88 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -454,8 +454,8 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Πατήστε ξανά για να ανοίξετε"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Σύρετε προς τα επάνω για άνοιγμα"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Σύρετε προς τα πάνω για να δοκιμάσετε ξανά"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"Αυτή η συσκευή είναι διαχειριζόμενη από τον οργανισμό σας"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"Τη συσκευή διαχειρίζεται ο οργανισμός <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
+ <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="phone_hint" msgid="6682125338461375925">"Σύρετε προς τα έξω για τηλέφωνο"</string>
<string name="voice_hint" msgid="7476017460191291417">"Σύρετε προς τα έξω για voice assist"</string>
<string name="camera_hint" msgid="4519495795000658637">"Σύρετε προς τα έξω για κάμερα"</string>
@@ -521,21 +521,21 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"Το προφίλ ενδέχεται να παρακολουθείται"</string>
<string name="vpn_footer" msgid="3457155078010607471">"Το δίκτυο ενδέχεται να παρακολουθείται"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"Το δίκτυο ενδέχεται να παρακολουθείται"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"Ο οργανισμός σας διαχειρίζ. αυτήν τη συσκευή και μπορεί να παρακολουθεί την επισκεψιμότητα δικτύου"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"Ο οργανισμός <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> διαχειρίζεται αυτήν τη συσκευή και μπορεί να παρακολουθεί την επισκεψιμότητα δικτύου"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"Η συσκευή σας διαχειρίζεται από τον οργανισμό σας και είναι συνδεδεμένη με το <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"Η συσκευή διαχειρίζεται από τον οργανισμό <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> και είναι συνδεδεμένη στην εφαρμογή <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"Η διαχείριση της συσκευής πραγματοποιείται από τον οργανισμό σας"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"Η διαχείριση της συσκευής πραγματοποιείται από τον οργανισμό <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>."</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"Η συσκευή διαχειρίζεται από τον οργανισμό σας και είναι συνδεδεμένη με VPN"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"Η συσκευή διαχειρίζεται από τον οργανισμό <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> και είναι συνδεδεμένη με VPN"</string>
+ <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Ο οργανισμός σας κατέχει αυτήν τη συσκευή και μπορεί να παρακολουθεί την επισκεψιμότητα δικτύου."</string>
+ <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Ο οργανισμός <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> κατέχει αυτήν τη συσκευή και μπορεί να παρακολουθεί την επισκεψιμότητα δικτύου."</string>
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Αυτή η συσκευή ανήκει στον οργανισμό σας και είναι συνδεδεμένη στην εφαρμογή <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Αυτή η συσκευή ανήκει στον οργανισμό <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> και είναι συνδεδεμένη στην εφαρμογή <xliff:g id="VPN_APP">%2$s</xliff:g>."</string>
+ <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Αυτή η συσκευή ανήκει στον οργανισμό σας."</string>
+ <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Αυτή η συσκευή ανήκει στον οργανισμό <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management_vpns" msgid="371835422690053154">"Αυτή η συσκευή ανήκει στον οργανισμό σας και είναι συνδεδεμένη σε ορισμένα VPN."</string>
+ <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_monitoring" msgid="8548019955631378680">"Το δίκτυο ενδέχεται να παρακολουθείται"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"Η συσκευή έχει συνδεθεί σε VPN"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"Το προφίλ εργασίας είναι συνδεδεμένο με το <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"Το προσωπικό προφίλ έχει συνδεθεί στην εφαρμογή <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"Η συσκευή έχει συνδεθεί στην εφαρμογή <xliff:g id="VPN_APP">%1$s</xliff:g>"</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>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Το προσωπικό σας προφίλ είναι συνδεδεμένο στην εφαρμογή <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Αυτή η συσκευή είναι συνδεδεμένη στην εφαρμογή <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Διαχείριση συσκευών"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Παρακολούθηση προφίλ"</string>
<string name="monitoring_title" msgid="4063890083735924568">"Παρακολούθηση δικτύου"</string>
@@ -545,8 +545,8 @@
<string name="disable_vpn" msgid="482685974985502922">"Απενεργοποίηση VPN"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"Αποσύνδεση VPN"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"Προβολή πολιτικών"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"Η διαχείριση της συσκευής σας γίνεται από <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nΟ διαχειριστής μπορεί να παρακολουθεί και να διαχειρίζεται ρυθμίσεις, εταιρική πρόσβαση, εφαρμογές και δεδομένα που σχετίζονται με τη συσκευή, καθώς και τις πληροφορίες τοποθεσίας.\n\nΓια περισσότερες πληροφορίες, επικοινωνήστε με τον διαχειριστή σας."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"Η διαχείριση της συσκευής σας γίνεται από τον οργανισμό σας.\n\nΟ διαχειριστής μπορεί να παρακολουθεί και να διαχειρίζεται ρυθμίσεις, εταιρική πρόσβαση, εφαρμογές και δεδομένα που σχετίζονται με τη συσκευή, καθώς και τις πληροφορίες τοποθεσίας.\n\nΓια περισσότερες πληροφορίες, επικοινωνήστε με τον διαχειριστή σας."</string>
+ <string name="monitoring_description_named_management" msgid="505833016545056036">"Αυτή η συσκευή ανήκει στον οργανισμό <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nΟ διαχειριστής IT μπορεί να παρακολουθεί και να διαχειρίζεται τις ρυθμίσεις, την εταιρική πρόσβαση, τις εφαρμογές, τα δεδομένα που σχετίζονται με τη συσκευή καθώς και τις πληροφορίες τοποθεσίας της συσκευής σας.\n\nΓια περισσότερες πληροφορίες, επικοινωνήστε με τον διαχειριστή IT."</string>
+ <string name="monitoring_description_management" msgid="4308879039175729014">"Αυτή η συσκευή ανήκει στον οργανισμό σας.\n\nΟ διαχειριστής IT μπορεί να παρακολουθεί και να διαχειρίζεται τις ρυθμίσεις, την εταιρική πρόσβαση, τις εφαρμογές, τα δεδομένα που σχετίζονται με τη συσκευή καθώς και τις πληροφορίες τοποθεσίας της συσκευής σας.\n\nΓια περισσότερες πληροφορίες, επικοινωνήστε με τον διαχειριστή IT."</string>
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Ο οργανισμός σας εγκατέστησε μια αρχή έκδοσης πιστοποιητικών σε αυτήν τη συσκευή. Η ασφαλής επισκεψιμότητα δικτύου σας μπορεί να παρακολουθείται ή να τροποποιείται."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Ο οργανισμός σας εγκατέστησε μια αρχή έκδοσης πιστοποιητικών στο προφίλ εργασίας σας. Η ασφαλής επισκεψιμότητα δικτύου σας μπορεί να παρακολουθείται ή να τροποποιείται."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Μια αρχή έκδοσης πιστοποιητικών έχει εγκατασταθεί σε αυτήν τη συσκευή. Η ασφαλής επισκεψιμότητα δικτύου σας μπορεί να παρακολουθείται ή να τροποποιείται."</string>
@@ -920,6 +920,7 @@
<string name="pip_pause" msgid="1139598607050555845">"Παύση"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"Μετάβαση στο επόμενο"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"Μετάβαση στο προηγούμενο"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"Αλλαγή μεγέθους"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"Το τηλέφωνο απεν. λόγω ζέστης"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"Το τηλέφωνο λειτουργεί πλέον κανονικά"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Η θερμοκρασία του τηλεφώνου είναι πολύ υψηλή και απενεργοποιήθηκε για να κρυώσει. Πλέον, λειτουργεί κανονικά.\n\nΗ θερμοκρασία ενδέχεται να ανέβει κατά τη:\n • Χρήση εφαρμογών υψηλής κατανάλωσης πόρων (όπως gaming, βίντεο ή περιήγησης)\n • Λήψη/μεταφόρτωση μεγάλων αρχείων\n • Χρήση σε υψηλές θερμοκρασίες"</string>
@@ -1014,7 +1015,7 @@
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Μεταβείτε στις Ρυθμίσεις για να ενημερώσετε την πλοήγηση συστήματος"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Κατάσταση αναμονής"</string>
<string name="priority_onboarding_title" msgid="2893070698479227616">"Ορίστηκε ως συζήτηση προτεραιότητας"</string>
- <string name="priority_onboarding_behavior" msgid="5342816047020432929">"Οι συζητήσεις προτεραιότητας θα:"</string>
+ <string name="priority_onboarding_behavior" msgid="5342816047020432929">"Οι συζητήσεις προτεραιότητας θα έχουν τα εξής χαρακτηριστικά:"</string>
<string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Εμφάνιση στο επάνω μέρος της ενότητας συνομιλιών"</string>
<string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Εμφάνιση εικόνας προφίλ στην οθόνη κλειδώματος"</string>
<string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Κινούμενο συννεφάκι στο επάνω μέρος των εφαρμογών"</string>
@@ -1045,7 +1046,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Κρατήστε και σύρετε για αναδιάταξη των στοιχείων ελέγχου"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"Όλα τα στοιχεία ελέγχου καταργήθηκαν"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Οι αλλαγές δεν αποθηκεύτηκαν"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"Ανεπιτυχής φόρτωση λίστας όλων των στοιχ. ελέγχου."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"Δεν ήταν δυνατή η φόρτωση των στοιχείων ελέγχου. Ελέγξτε την εφαρμογή <xliff:g id="APP">%s</xliff:g> για να βεβαιωθείτε ότι δεν έχουν αλλάξει οι ρυθμίσεις της εφαρμογής."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"Μη διαθέσιμα συμβατά στοιχεία ελέγχου"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Άλλο"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"Προσθήκη στα στοιχεία ελέγχου συσκευής"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"Προσθήκη"</string>
@@ -1061,8 +1063,11 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"Επιβεβαίωση αλλαγής για <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Σύρετε για να δείτε περισσότερα."</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Φόρτωση προτάσεων"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"Κλείσιμο αυτής της περιόδου λειτουργίας μέσων."</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"Μέσα"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"Απόκρυψη της τρέχουσας περιόδου λειτουργίας."</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Απόκρυψη"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Συνέχιση"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"Ρυθμίσεις"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Ανενεργό, έλεγχος εφαρμογής"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Προέκυψε σφάλμα. Επανάληψη…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Δεν βρέθηκε."</string>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index ac20c8477d47..47d708c56052 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -454,8 +454,8 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Tap again to open"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Swipe up to open"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Swipe up to try again"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"This device is managed by your organisation"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"This device is managed by <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
+ <string name="do_disclosure_generic" msgid="4896482821974707167">"This device belongs to your organisation"</string>
+ <string name="do_disclosure_with_name" msgid="2091641464065004091">"This device belongs to <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="6682125338461375925">"Swipe from icon for phone"</string>
<string name="voice_hint" msgid="7476017460191291417">"Swipe from icon for voice assist"</string>
<string name="camera_hint" msgid="4519495795000658637">"Swipe from icon for camera"</string>
@@ -521,21 +521,21 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"Profile may be monitored"</string>
<string name="vpn_footer" msgid="3457155078010607471">"Network may be monitored"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"Network may be monitored"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"Your organisation manages this device and may monitor network traffic"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> manages this device and may monitor network traffic"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"Device is managed by your organisation and connected to <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"Device is managed by <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> and connected to <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"Device is managed by your organisation"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"Device is managed by <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"Device is managed by your organisation and connected to VPNs"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"Device is managed by <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> and connected to VPNs"</string>
+ <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Your organisation owns this device and may monitor network traffic"</string>
+ <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> owns this device and may monitor network traffic"</string>
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"This device belongs to your organisation and is connected to <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"This device belongs to <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> and is connected to <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"This device belongs to your organisation"</string>
+ <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"This device belongs to <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management_vpns" msgid="371835422690053154">"This device belongs to your organisation and is connected to VPNs"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="4046375645500668555">"This device belongs to <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> and is connected to VPNs"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Your organisation may monitor network traffic in your work profile"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> may monitor network traffic in your work profile"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Network may be monitored"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"Device connected to VPNs"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"Work profile connected to <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"Personal profile connected to <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"Device connected to <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_vpns" msgid="7213546797022280246">"This device is connected to VPNs"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Your work profile is connected to <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Your personal profile is connected to <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"This device is connected to <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Device management"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Profile monitoring"</string>
<string name="monitoring_title" msgid="4063890083735924568">"Network monitoring"</string>
@@ -545,8 +545,8 @@
<string name="disable_vpn" msgid="482685974985502922">"Disable VPN"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"Disconnect VPN"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"View Policies"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"Your device is managed by <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nYour admin can monitor and manage settings, corporate access, apps, data associated with your device and your device\'s location information.\n\nFor more information, contact your admin."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"Your device is managed by your organisation.\n\nYour admin can monitor and manage settings, corporate access, apps, data associated with your device and your device\'s location information.\n\nFor more information, contact your admin."</string>
+ <string name="monitoring_description_named_management" msgid="505833016545056036">"This device belongs to <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nYour IT admin can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information.\n\nFor more information, contact your IT admin."</string>
+ <string name="monitoring_description_management" msgid="4308879039175729014">"This device belongs to your organisation.\n\nYour IT admin can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information.\n\nFor more information, contact your IT admin."</string>
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Your organisation installed a certificate authority on this device. Your secure network traffic may be monitored or modified."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Your organisation installed a certificate authority in your work profile. Your secure network traffic may be monitored or modified."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"A certificate authority is installed on this device. Your secure network traffic may be monitored or modified."</string>
@@ -920,6 +920,7 @@
<string name="pip_pause" msgid="1139598607050555845">"Pause"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"Skip to next"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"Skip to previous"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"Resize"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"Phone turned off due to heat"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"Your phone is now running normally"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Your phone was too hot, so it turned off to cool down. Your phone is now running normally.\n\nYour phone may get too hot if you:\n • Use resource-intensive apps (such as gaming, video or navigation apps)\n • Download or upload large files\n • Use your phone in high temperatures"</string>
@@ -1045,7 +1046,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Hold and drag to rearrange controls"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"All controls removed"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Changes not saved"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"The list of all controls could not be loaded."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"Controls could not be loaded. Check the <xliff:g id="APP">%s</xliff:g> app to make sure that the app settings haven’t changed."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"Compatible controls unavailable"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Other"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"Add to device controls"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"Add"</string>
@@ -1061,8 +1063,11 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"Confirm change for <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Swipe to see more"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Loading recommendations"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"Close this media session"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"Media"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"Hide the current session."</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Hide"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Resume"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"Settings"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inactive, check app"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Error, retrying…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Not found"</string>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index 233664e5fbc7..a69b4a70ebd5 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -454,8 +454,8 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Tap again to open"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Swipe up to open"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Swipe up to try again"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"This device is managed by your organisation"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"This device is managed by <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
+ <string name="do_disclosure_generic" msgid="4896482821974707167">"This device belongs to your organisation"</string>
+ <string name="do_disclosure_with_name" msgid="2091641464065004091">"This device belongs to <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="6682125338461375925">"Swipe from icon for phone"</string>
<string name="voice_hint" msgid="7476017460191291417">"Swipe from icon for voice assist"</string>
<string name="camera_hint" msgid="4519495795000658637">"Swipe from icon for camera"</string>
@@ -521,21 +521,21 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"Profile may be monitored"</string>
<string name="vpn_footer" msgid="3457155078010607471">"Network may be monitored"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"Network may be monitored"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"Your organisation manages this device and may monitor network traffic"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> manages this device and may monitor network traffic"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"Device is managed by your organisation and connected to <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"Device is managed by <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> and connected to <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"Device is managed by your organisation"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"Device is managed by <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"Device is managed by your organisation and connected to VPNs"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"Device is managed by <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> and connected to VPNs"</string>
+ <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Your organisation owns this device and may monitor network traffic"</string>
+ <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> owns this device and may monitor network traffic"</string>
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"This device belongs to your organisation and is connected to <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"This device belongs to <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> and is connected to <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"This device belongs to your organisation"</string>
+ <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"This device belongs to <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management_vpns" msgid="371835422690053154">"This device belongs to your organisation and is connected to VPNs"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="4046375645500668555">"This device belongs to <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> and is connected to VPNs"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Your organisation may monitor network traffic in your work profile"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> may monitor network traffic in your work profile"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Network may be monitored"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"Device connected to VPNs"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"Work profile connected to <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"Personal profile connected to <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"Device connected to <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_vpns" msgid="7213546797022280246">"This device is connected to VPNs"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Your work profile is connected to <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Your personal profile is connected to <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"This device is connected to <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Device management"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Profile monitoring"</string>
<string name="monitoring_title" msgid="4063890083735924568">"Network monitoring"</string>
@@ -545,8 +545,8 @@
<string name="disable_vpn" msgid="482685974985502922">"Disable VPN"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"Disconnect VPN"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"View Policies"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"Your device is managed by <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nYour admin can monitor and manage settings, corporate access, apps, data associated with your device and your device\'s location information.\n\nFor more information, contact your admin."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"Your device is managed by your organisation.\n\nYour admin can monitor and manage settings, corporate access, apps, data associated with your device and your device\'s location information.\n\nFor more information, contact your admin."</string>
+ <string name="monitoring_description_named_management" msgid="505833016545056036">"This device belongs to <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nYour IT admin can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information.\n\nFor more information, contact your IT admin."</string>
+ <string name="monitoring_description_management" msgid="4308879039175729014">"This device belongs to your organisation.\n\nYour IT admin can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information.\n\nFor more information, contact your IT admin."</string>
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Your organisation installed a certificate authority on this device. Your secure network traffic may be monitored or modified."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Your organisation installed a certificate authority in your work profile. Your secure network traffic may be monitored or modified."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"A certificate authority is installed on this device. Your secure network traffic may be monitored or modified."</string>
@@ -920,6 +920,7 @@
<string name="pip_pause" msgid="1139598607050555845">"Pause"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"Skip to next"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"Skip to previous"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"Resize"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"Phone turned off due to heat"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"Your phone is now running normally"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Your phone was too hot, so it turned off to cool down. Your phone is now running normally.\n\nYour phone may get too hot if you:\n • Use resource-intensive apps (such as gaming, video or navigation apps)\n • Download or upload large files\n • Use your phone in high temperatures"</string>
@@ -1045,7 +1046,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Hold and drag to rearrange controls"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"All controls removed"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Changes not saved"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"The list of all controls could not be loaded."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"Controls could not be loaded. Check the <xliff:g id="APP">%s</xliff:g> app to make sure that the app settings haven’t changed."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"Compatible controls unavailable"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Other"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"Add to device controls"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"Add"</string>
@@ -1061,8 +1063,11 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"Confirm change for <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Swipe to see more"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Loading recommendations"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"Close this media session"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"Media"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"Hide the current session."</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Hide"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Resume"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"Settings"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inactive, check app"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Error, retrying…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Not found"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index ac20c8477d47..47d708c56052 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -454,8 +454,8 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Tap again to open"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Swipe up to open"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Swipe up to try again"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"This device is managed by your organisation"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"This device is managed by <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
+ <string name="do_disclosure_generic" msgid="4896482821974707167">"This device belongs to your organisation"</string>
+ <string name="do_disclosure_with_name" msgid="2091641464065004091">"This device belongs to <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="6682125338461375925">"Swipe from icon for phone"</string>
<string name="voice_hint" msgid="7476017460191291417">"Swipe from icon for voice assist"</string>
<string name="camera_hint" msgid="4519495795000658637">"Swipe from icon for camera"</string>
@@ -521,21 +521,21 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"Profile may be monitored"</string>
<string name="vpn_footer" msgid="3457155078010607471">"Network may be monitored"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"Network may be monitored"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"Your organisation manages this device and may monitor network traffic"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> manages this device and may monitor network traffic"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"Device is managed by your organisation and connected to <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"Device is managed by <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> and connected to <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"Device is managed by your organisation"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"Device is managed by <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"Device is managed by your organisation and connected to VPNs"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"Device is managed by <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> and connected to VPNs"</string>
+ <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Your organisation owns this device and may monitor network traffic"</string>
+ <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> owns this device and may monitor network traffic"</string>
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"This device belongs to your organisation and is connected to <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"This device belongs to <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> and is connected to <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"This device belongs to your organisation"</string>
+ <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"This device belongs to <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management_vpns" msgid="371835422690053154">"This device belongs to your organisation and is connected to VPNs"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="4046375645500668555">"This device belongs to <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> and is connected to VPNs"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Your organisation may monitor network traffic in your work profile"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> may monitor network traffic in your work profile"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Network may be monitored"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"Device connected to VPNs"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"Work profile connected to <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"Personal profile connected to <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"Device connected to <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_vpns" msgid="7213546797022280246">"This device is connected to VPNs"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Your work profile is connected to <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Your personal profile is connected to <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"This device is connected to <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Device management"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Profile monitoring"</string>
<string name="monitoring_title" msgid="4063890083735924568">"Network monitoring"</string>
@@ -545,8 +545,8 @@
<string name="disable_vpn" msgid="482685974985502922">"Disable VPN"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"Disconnect VPN"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"View Policies"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"Your device is managed by <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nYour admin can monitor and manage settings, corporate access, apps, data associated with your device and your device\'s location information.\n\nFor more information, contact your admin."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"Your device is managed by your organisation.\n\nYour admin can monitor and manage settings, corporate access, apps, data associated with your device and your device\'s location information.\n\nFor more information, contact your admin."</string>
+ <string name="monitoring_description_named_management" msgid="505833016545056036">"This device belongs to <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nYour IT admin can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information.\n\nFor more information, contact your IT admin."</string>
+ <string name="monitoring_description_management" msgid="4308879039175729014">"This device belongs to your organisation.\n\nYour IT admin can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information.\n\nFor more information, contact your IT admin."</string>
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Your organisation installed a certificate authority on this device. Your secure network traffic may be monitored or modified."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Your organisation installed a certificate authority in your work profile. Your secure network traffic may be monitored or modified."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"A certificate authority is installed on this device. Your secure network traffic may be monitored or modified."</string>
@@ -920,6 +920,7 @@
<string name="pip_pause" msgid="1139598607050555845">"Pause"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"Skip to next"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"Skip to previous"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"Resize"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"Phone turned off due to heat"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"Your phone is now running normally"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Your phone was too hot, so it turned off to cool down. Your phone is now running normally.\n\nYour phone may get too hot if you:\n • Use resource-intensive apps (such as gaming, video or navigation apps)\n • Download or upload large files\n • Use your phone in high temperatures"</string>
@@ -1045,7 +1046,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Hold and drag to rearrange controls"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"All controls removed"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Changes not saved"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"The list of all controls could not be loaded."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"Controls could not be loaded. Check the <xliff:g id="APP">%s</xliff:g> app to make sure that the app settings haven’t changed."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"Compatible controls unavailable"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Other"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"Add to device controls"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"Add"</string>
@@ -1061,8 +1063,11 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"Confirm change for <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Swipe to see more"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Loading recommendations"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"Close this media session"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"Media"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"Hide the current session."</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Hide"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Resume"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"Settings"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inactive, check app"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Error, retrying…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Not found"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index ac20c8477d47..47d708c56052 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -454,8 +454,8 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Tap again to open"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Swipe up to open"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Swipe up to try again"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"This device is managed by your organisation"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"This device is managed by <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
+ <string name="do_disclosure_generic" msgid="4896482821974707167">"This device belongs to your organisation"</string>
+ <string name="do_disclosure_with_name" msgid="2091641464065004091">"This device belongs to <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="6682125338461375925">"Swipe from icon for phone"</string>
<string name="voice_hint" msgid="7476017460191291417">"Swipe from icon for voice assist"</string>
<string name="camera_hint" msgid="4519495795000658637">"Swipe from icon for camera"</string>
@@ -521,21 +521,21 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"Profile may be monitored"</string>
<string name="vpn_footer" msgid="3457155078010607471">"Network may be monitored"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"Network may be monitored"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"Your organisation manages this device and may monitor network traffic"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> manages this device and may monitor network traffic"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"Device is managed by your organisation and connected to <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"Device is managed by <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> and connected to <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"Device is managed by your organisation"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"Device is managed by <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"Device is managed by your organisation and connected to VPNs"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"Device is managed by <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> and connected to VPNs"</string>
+ <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Your organisation owns this device and may monitor network traffic"</string>
+ <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> owns this device and may monitor network traffic"</string>
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"This device belongs to your organisation and is connected to <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"This device belongs to <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> and is connected to <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"This device belongs to your organisation"</string>
+ <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"This device belongs to <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management_vpns" msgid="371835422690053154">"This device belongs to your organisation and is connected to VPNs"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="4046375645500668555">"This device belongs to <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> and is connected to VPNs"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Your organisation may monitor network traffic in your work profile"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> may monitor network traffic in your work profile"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Network may be monitored"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"Device connected to VPNs"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"Work profile connected to <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"Personal profile connected to <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"Device connected to <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_vpns" msgid="7213546797022280246">"This device is connected to VPNs"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Your work profile is connected to <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Your personal profile is connected to <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"This device is connected to <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Device management"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Profile monitoring"</string>
<string name="monitoring_title" msgid="4063890083735924568">"Network monitoring"</string>
@@ -545,8 +545,8 @@
<string name="disable_vpn" msgid="482685974985502922">"Disable VPN"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"Disconnect VPN"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"View Policies"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"Your device is managed by <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nYour admin can monitor and manage settings, corporate access, apps, data associated with your device and your device\'s location information.\n\nFor more information, contact your admin."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"Your device is managed by your organisation.\n\nYour admin can monitor and manage settings, corporate access, apps, data associated with your device and your device\'s location information.\n\nFor more information, contact your admin."</string>
+ <string name="monitoring_description_named_management" msgid="505833016545056036">"This device belongs to <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nYour IT admin can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information.\n\nFor more information, contact your IT admin."</string>
+ <string name="monitoring_description_management" msgid="4308879039175729014">"This device belongs to your organisation.\n\nYour IT admin can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information.\n\nFor more information, contact your IT admin."</string>
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Your organisation installed a certificate authority on this device. Your secure network traffic may be monitored or modified."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Your organisation installed a certificate authority in your work profile. Your secure network traffic may be monitored or modified."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"A certificate authority is installed on this device. Your secure network traffic may be monitored or modified."</string>
@@ -920,6 +920,7 @@
<string name="pip_pause" msgid="1139598607050555845">"Pause"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"Skip to next"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"Skip to previous"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"Resize"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"Phone turned off due to heat"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"Your phone is now running normally"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Your phone was too hot, so it turned off to cool down. Your phone is now running normally.\n\nYour phone may get too hot if you:\n • Use resource-intensive apps (such as gaming, video or navigation apps)\n • Download or upload large files\n • Use your phone in high temperatures"</string>
@@ -1045,7 +1046,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Hold and drag to rearrange controls"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"All controls removed"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Changes not saved"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"The list of all controls could not be loaded."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"Controls could not be loaded. Check the <xliff:g id="APP">%s</xliff:g> app to make sure that the app settings haven’t changed."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"Compatible controls unavailable"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Other"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"Add to device controls"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"Add"</string>
@@ -1061,8 +1063,11 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"Confirm change for <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Swipe to see more"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Loading recommendations"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"Close this media session"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"Media"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"Hide the current session."</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Hide"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Resume"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"Settings"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inactive, check app"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Error, retrying…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Not found"</string>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index f37742d62062..ee3a304a9bb4 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -454,8 +454,8 @@
<string name="notification_tap_again" msgid="4477318164947497249">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‎‎‎‏‎‎‎‏‎‏‎‏‎‎‎‎‏‎‎‏‎‎‏‏‎‎‎‏‏‎‎‎‎‎‎‎‏‏‎‎‏‎‏‏‏‎‎‎‏‎‎‏‎‎‎‎‏‎Tap again to open‎‏‎‎‏‎"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‏‏‎‏‏‏‎‏‎‎‏‏‏‏‎‏‏‎‏‏‏‎‎‏‏‏‏‎‏‎‎‎‎‎‏‏‏‎‏‏‏‎‎‎‏‎‎‏‎‎‎‎‎‏‎Swipe up to open‎‏‎‎‏‎"</string>
<string name="keyguard_retry" msgid="886802522584053523">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‎‎‏‎‎‏‏‏‎‏‎‎‎‏‏‏‎‎‎‏‏‎‎‏‎‎‎‏‎‎‎‎‎‏‎‎‎‏‎‏‎‏‏‏‏‎‏‏‏‎‎‎‏‎‎‏‏‎Swipe up to try again‎‏‎‎‏‎"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‏‎‎‏‎‎‏‎‎‎‎‏‏‎‏‏‏‎‎‎‎‎‏‏‏‎‏‏‏‎‎‏‎‏‏‎‎‎‎‎‎‎‏‎‎‎‎‎‏‎‎‎‎‏‎‎‎‎This device is managed by your organization‎‏‎‎‏‎"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‎‎‎‏‎‏‎‎‎‎‏‏‎‎‏‎‎‏‏‏‏‏‏‎‏‏‎‏‎‏‏‎‎‎‏‎‏‎‏‎‏‏‏‏‎‏‏‎‏‏‎This device is managed by ‎‏‎‎‏‏‎<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+ <string name="do_disclosure_generic" msgid="4896482821974707167">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‏‏‏‎‎‏‏‏‏‎‎‏‏‎‏‎‎‏‎‏‏‏‏‎‎‎‏‎‏‎‎‏‎‎‏‏‎‏‎‏‏‎‎‏‎‏‏‏‏‎‏‏‏‏‏‎This device belongs to your organization‎‏‎‎‏‎"</string>
+ <string name="do_disclosure_with_name" msgid="2091641464065004091">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‏‎‎‎‎‎‏‏‏‎‎‎‎‎‎‎‎‏‏‎‏‎‏‎‎‎‏‎‏‏‏‏‏‎‎‎‏‎‎‏‎‏‎‎‏‎‎‏‎‎‎‏‏‏‎‏‏‎This device belongs to ‎‏‎‎‏‏‎<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
<string name="phone_hint" msgid="6682125338461375925">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‎‏‏‏‎‏‏‏‎‏‎‏‏‎‏‏‎‎‏‎‏‏‏‏‎‎‎‎‏‏‏‏‎‏‎‎‎‎‎‏‎‎‎‏‏‎‏‏‎‏‏‎‏‎‏‎Swipe from icon for phone‎‏‎‎‏‎"</string>
<string name="voice_hint" msgid="7476017460191291417">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‏‏‏‎‎‎‎‎‎‎‎‏‎‎‏‏‎‎‏‎‎‎‏‎‏‎‎‏‏‏‎‎‏‎‏‎‏‎‎‎‏‏‏‏‎‏‎‎‎‎‎‎‏‏‎‎‏‎Swipe from icon for voice assist‎‏‎‎‏‎"</string>
<string name="camera_hint" msgid="4519495795000658637">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‎‏‎‏‏‏‎‎‎‎‏‏‏‏‎‎‏‎‏‏‏‏‎‏‎‏‏‏‏‎‎‎‎‏‏‏‎‎‎‏‎‏‏‎‎‏‎‏‎‏‏‎‎‏‏‎‏‎Swipe from icon for camera‎‏‎‎‏‎"</string>
@@ -521,21 +521,21 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‎‎‏‎‎‎‎‏‎‎‎‎‎‎‏‎‎‎‏‎‎‏‎‏‏‏‏‎‏‏‏‎‎‎‎‎‏‏‏‎‏‎‎‎‎‏‎‏‎‏‎‏‎‏‏‎‎‎Profile may be monitored‎‏‎‎‏‎"</string>
<string name="vpn_footer" msgid="3457155078010607471">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‎‏‎‎‎‎‎‏‏‏‎‏‎‎‎‎‎‎‏‏‎‎‏‎‎‎‎‏‎‏‎‎‏‎‏‏‏‎‏‏‎‏‏‏‏‎Network may be monitored‎‏‎‎‏‎"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‏‎‏‎‏‎‏‏‎‎‏‎‏‎‎‎‏‏‎‏‎‏‏‎‏‎‎‎‏‏‎‎‏‎‏‏‏‏‏‎‏‏‏‎‎‎‏‎‎‏‎‏‎‎‎‏‎‎Network may be monitored‎‏‎‎‏‎"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‏‏‎‏‏‏‎‏‎‏‏‏‎‎‎‏‎‏‎‎‎‎‎‎‏‎‏‏‎‏‎‏‎‏‎‏‏‏‎‏‏‏‎‏‏‎‏‎‎‏‎‎‏‏‎‎Your organization manages this device and may monitor network traffic‎‏‎‎‏‎"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‏‏‎‏‎‏‎‏‏‏‏‏‎‎‏‏‏‏‏‎‎‎‏‎‏‏‎‎‏‏‎‎‎‎‎‎‎‏‎‎‎‎‎‏‎‎‎‏‎‏‏‏‏‎‎‎‎‏‎‎‏‏‎<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ manages this device and may monitor network traffic‎‏‎‎‏‎"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‏‎‎‎‎‏‎‎‎‏‏‏‏‎‏‎‎‎‎‏‎‏‎‏‎‎‏‎‎‏‏‎‎‎‏‎‎‏‏‎‏‏‎‏‎‏‏‎‎‎‏‏‎‏‎‎‎‎Device is managed by your organization and connected to ‎‏‎‎‏‏‎<xliff:g id="VPN_APP">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‎‎‎‏‏‏‎‎‏‎‎‏‎‎‎‏‏‏‎‏‏‎‎‎‏‏‎‎‏‏‏‏‏‎‏‏‎‎‎‏‎‏‎‎‎‎‎‏‏‎‏‏‎‏‎‎Device is managed by ‎‏‎‎‏‏‎<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ and connected to ‎‏‎‎‏‏‎<xliff:g id="VPN_APP">%2$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‎‏‏‎‎‏‎‏‏‏‎‎‏‏‏‏‏‎‏‎‎‏‎‏‎‎‏‎‎‎‏‏‏‏‎‏‎‏‎‏‏‎‏‏‎‎‎‏‎‏‏‏‏‎‎‎Device is managed by your organization‎‏‎‎‏‎"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‎‎‎‏‎‎‎‏‏‏‎‎‏‎‎‏‎‏‏‎‏‎‎‎‏‎‎‏‏‎‏‏‏‏‏‎‏‏‎‏‎‎‏‎‏‎‎‏‏‎‎‎‏‏‎‏‎‎Device is managed by ‎‏‎‎‏‏‎<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‏‏‏‎‏‏‎‎‎‎‎‏‎‏‎‏‏‏‎‏‎‎‎‏‏‏‏‎‏‏‎‏‏‏‎‎‏‏‏‎‏‎‎‏‎‎‎‎‎‏‎‎‏‏‏‎‏‎Device is managed by your organization and connected to VPNs‎‏‎‎‏‎"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‎‎‏‏‎‏‏‏‏‎‏‏‎‏‎‏‎‏‏‏‏‎‎‏‎‏‏‎‏‎‎‏‎‏‎‏‎‏‏‏‏‎‏‏‏‏‏‎‎‏‎‏‏‏‏‎‎‎Device is managed by ‎‏‎‎‏‏‎<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ and connected to VPNs‎‏‎‎‏‎"</string>
+ <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‏‏‎‏‏‏‎‎‏‎‏‎‏‎‏‎‎‎‏‏‎‏‏‏‎‏‏‎‏‏‏‎‏‏‏‎‏‏‏‎‏‏‎‎‏‏‏‏‎‎‏‎‎‎Your organization owns this device and may monitor network traffic‎‏‎‎‏‎"</string>
+ <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‏‎‏‎‎‏‎‏‏‎‎‏‏‏‏‎‎‏‏‏‏‎‎‏‏‎‎‏‏‏‎‏‏‎‏‏‎‎‎‎‏‏‏‏‎‎‏‏‎‎‎‎‎‎‏‎‎‎‎‏‎‎‏‏‎<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ owns this device and may monitor network traffic‎‏‎‎‏‎"</string>
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‎‎‏‏‎‏‏‏‏‏‎‎‎‏‎‎‏‎‎‏‎‏‎‎‎‏‏‏‏‎‏‎‎‎‏‎‏‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‎‎‎This device belongs to your organization and is connected to ‎‏‎‎‏‏‎<xliff:g id="VPN_APP">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‎‎‏‎‏‏‏‎‏‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‎‏‎‎‏‏‎‎‎‎‏‏‏‎‏‎‎‏‎‏‎‎‎‎‏‎‎‏‎‎‎‎This device belongs to ‎‏‎‎‏‏‎<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ and is connected to ‎‏‎‎‏‏‎<xliff:g id="VPN_APP">%2$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+ <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‎‏‎‎‎‏‎‏‎‎‏‎‎‎‏‎‏‎‎‎‎‏‎‎‎‏‏‏‏‎‏‎‎‏‏‏‏‏‎‏‎‎‎‏‎‏‏‎‏‏‎‏‎‎‎‏‎‎This device belongs to your organization‎‏‎‎‏‎"</string>
+ <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‎‎‏‏‎‎‎‏‏‎‏‎‏‎‏‏‏‏‏‎‏‎‎‏‏‎‏‎‏‎‏‎‏‎‏‏‎‎‎‎‎‏‏‎This device belongs to ‎‏‎‎‏‏‎<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+ <string name="quick_settings_disclosure_management_vpns" msgid="371835422690053154">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‏‎‎‏‎‏‎‎‏‎‎‎‎‎‏‏‎‎‏‎‏‏‎‎‎‏‏‎‎‏‏‎‎‎‏‎‏‏‎‎‏‎‎‎‎‏‏‎‎‎‎‏‎‎‎‏‎‎This device belongs to your organization and is connected to VPNs‎‏‎‎‏‎"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="4046375645500668555">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‎‎‎‏‎‎‏‏‏‏‎‎‏‏‏‎‏‎‎‏‏‎‏‏‎‎‎‎‎‎‎‎‏‏‏‎‏‏‎‏‏‏‏‏‏‏‎‏‎‏‎‎‎‏‎‏‏‎This device belongs to ‎‏‎‎‏‏‎<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ and is connected to VPNs‎‏‎‎‏‎"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‏‏‏‎‎‎‎‏‎‏‎‏‏‎‏‎‎‏‎‏‎‏‏‎‎‎‏‏‎‎‏‏‎‏‏‎‎‏‎‎‎‎‏‎‎‎‎‎‏‎‎‎‎‎‎‏‎‎Your organization may monitor network traffic in your work profile‎‏‎‎‏‎"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‎‏‏‏‏‎‏‏‏‏‎‎‏‏‎‎‎‎‏‎‎‎‎‎‏‎‎‎‏‏‏‎‏‏‏‎‏‏‏‏‏‎‏‏‏‏‏‏‎‏‎‏‎‏‎‎‎‎‏‎‎‏‏‎<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ may monitor network traffic in your work profile‎‏‎‎‏‎"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‎‎‎‎‎‏‎‏‎‏‎‏‎‏‏‎‏‏‏‎‎‎‎‏‏‏‏‎‎‎‏‎‏‏‎‏‏‏‏‎‏‎‎‎‎‏‏‏‏‏‎‎‎‎Network may be monitored‎‏‎‎‏‎"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‎‎‎‎‏‏‏‎‏‎‎‏‎‎‏‏‏‏‎‎‏‎‏‎‏‎‎‎‎‏‎‏‏‎‏‎‎‎‏‏‎‎‏‎‎‏‎‎‎‏‏‏‏‎‏‏‏‎Device connected to VPNs‎‏‎‎‏‎"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‏‎‏‏‏‎‏‏‎‎‎‎‏‏‏‎‎‎‏‏‎‎‏‏‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‎‎‎‎‎‏‎‎‎‎Work profile connected to ‎‏‎‎‏‏‎<xliff:g id="VPN_APP">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‎‎‏‎‎‏‏‏‏‏‏‏‎‎‏‏‏‎‏‏‏‏‎‏‏‏‎‏‏‎‎‎‏‎‎‏‏‎‏‎‏‎‏‏‎‎‎‏‎‏‎‏‎‎‏‏‎‎Personal profile connected to ‎‏‎‎‏‏‎<xliff:g id="VPN_APP">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‎‎‏‎‏‏‎‎‏‎‎‎‎‎‏‎‏‎‏‎‏‏‎‎‏‏‏‏‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‎‏‎‏‏‏‎‎‏‏‎‏‎‎Device connected to ‎‏‎‎‏‏‎<xliff:g id="VPN_APP">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+ <string name="quick_settings_disclosure_vpns" msgid="7213546797022280246">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‎‎‏‏‎‏‏‏‎‏‎‏‎‏‎‏‎‎‏‎‏‏‏‏‏‎‎‎‏‏‏‎‎‏‎‏‎‏‏‎‏‏‏‏‎‏‎‎‎‏‏‎‏‏‎‎This device is connected to VPNs‎‏‎‎‏‎"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‏‎‎‏‏‏‎‏‏‎‎‏‎‏‏‏‎‎‎‎‏‏‏‏‎‏‎‎‎‏‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‏‎‎‏‎‎‏‎‏‎Your work profile is connected to ‎‏‎‎‏‏‎<xliff:g id="VPN_APP">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‎‎‎‎‏‎‎‏‏‎‎‏‎‎‎‏‎‏‏‎‎‏‎‏‏‏‏‎‎‏‎‎‎‏‎‏‏‎‎‎‏‏‎‎‎‎‎‏‏‎‏‏‏‎‏‎‏‎Your personal profile is connected to ‎‏‎‎‏‏‎<xliff:g id="VPN_APP">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‏‎‎‏‏‏‏‏‏‏‎‏‏‎‏‎‏‏‏‎‎‏‏‏‏‎‎‏‏‏‎‏‎‏‏‏‎‎‏‎‎‎‏‎‎‏‎‏‏‎‏‏‎‎‎‏‎This device is connected to ‎‏‎‎‏‏‎<xliff:g id="VPN_APP">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎‎‎‏‏‏‎‎‏‏‏‏‎‏‎‏‏‎‎‏‎‏‏‏‎‏‏‏‏‎‎‏‏‎‏‏‏‏‏‎‎‎‎‏‎‎‏‏‎‏‏‎‏‎‎‎Device management‎‏‎‎‏‎"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‏‏‏‎‎‏‎‎‎‎‏‎‎‏‎‎‎‎‎‎‏‏‎‏‏‏‎‎‎‎‏‎‏‏‎‎‏‏‎‏‎‏‎‎‏‎‏‎‏‏‎‎‎‎‎‎Profile monitoring‎‏‎‎‏‎"</string>
<string name="monitoring_title" msgid="4063890083735924568">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‎‎‏‏‎‎‏‎‏‏‏‎‏‎‏‏‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‎‎‏‏‏‏‏‏‏‎‏‏‏‏‎‏‎‏‏‎‎‎‎Network monitoring‎‏‎‎‏‎"</string>
@@ -545,8 +545,8 @@
<string name="disable_vpn" msgid="482685974985502922">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‎‏‎‏‏‎‎‏‎‏‏‎‏‏‎‎‎‎‏‎‏‎‏‏‎‎‎‏‏‏‏‎‏‎‎‎‏‎‎‏‎‏‏‏‏‎‎‎‎‏‏‎‎‏‎‏‎‎Disable VPN‎‏‎‎‏‎"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‎‏‏‏‏‎‏‏‏‎‏‎‏‏‎‎‎‏‏‏‏‎‎‎‎‎‎‎‎‏‏‎‏‏‏‎‎‏‏‎‏‏‏‎‏‏‏‏‎‏‏‎‎‏‎‏‏‎‏‎Disconnect VPN‎‏‎‎‏‎"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‏‏‎‏‏‎‏‎‎‎‎‎‎‎‏‏‎‎‎‏‏‏‏‎‎‎‏‎‎‏‎‏‏‏‎‎‎‏‏‏‎‎‎‎‎‎‏‏‏‏‏‎‎‏‎‏‎‎View Policies‎‏‎‎‏‎"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‎‎‏‎‎‏‏‎‎‎‎‏‎‏‏‏‎‏‏‎‎‏‎‏‏‎‎‏‏‎‎‏‎‏‏‏‎‏‎‎‏‏‎‎‏‎‎‏‏‏‏‎‎‎‎Your device is managed by ‎‏‎‎‏‏‎<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Your admin can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎For more information, contact your admin.‎‏‎‎‏‎"</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‎‏‎‎‎‏‎‏‏‎‏‏‎‏‎‏‏‏‎‎‎‏‎‎‎‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‏‏‏‎‎‏‎‏‏‎‎Your device is managed by your organization.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Your admin can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎For more information, contact your admin.‎‏‎‎‏‎"</string>
+ <string name="monitoring_description_named_management" msgid="505833016545056036">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‏‎‎‎‎‎‏‎‏‎‎‎‏‎‏‎‎‎‏‏‏‎‎‏‎‏‏‎‏‎‎‏‎‏‏‎‏‎‏‎‏‎‎‎‏‎‏‎‏‎‎‏‎‎‏‎‎‎This device belongs to ‎‏‎‎‏‏‎<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Your IT admin can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎For more information, contact your IT admin.‎‏‎‎‏‎"</string>
+ <string name="monitoring_description_management" msgid="4308879039175729014">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‏‏‏‎‎‏‏‎‎‎‎‏‏‎‏‏‎‏‎‏‎‏‎‎‎‎‎‎‏‏‏‏‎‎‎‏‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‏‎‎This device belongs to your organization.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Your IT admin can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎For more information, contact your IT admin.‎‏‎‎‏‎"</string>
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‎‎‏‎‎‏‏‏‏‎‏‏‎‎‎‎‏‏‎‎‏‎‎‎‎‏‎‎‎‎‏‎‏‎‎‎‎‎‏‏‎‏‏‎‏‎‏‎‏‏‎‎‏‎‎Your organization installed a certificate authority on this device. Your secure network traffic may be monitored or modified.‎‏‎‎‏‎"</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‏‏‎‎‎‏‏‏‎‎‏‏‎‎‎‏‎‎‎‏‎‎‏‎‏‏‏‏‎‎‎‎‏‎‎‏‏‎‏‏‎‏‎‏‏‏‎‎‏‏‏‏‏‏‎Your organization installed a certificate authority in your work profile. Your secure network traffic may be monitored or modified.‎‏‎‎‏‎"</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‎‎‎‏‏‏‎‏‎‏‏‏‎‎‏‎‏‎‎‏‎‎‏‎‎‎‏‎‏‎‎‏‏‎‏‏‏‏‏‎‏‎‏‏‎‏‎‏‏‏‎‎‏‏‎‎‏‎A certificate authority is installed on this device. Your secure network traffic may be monitored or modified.‎‏‎‎‏‎"</string>
@@ -920,6 +920,7 @@
<string name="pip_pause" msgid="1139598607050555845">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‏‏‏‎‏‎‎‎‎‏‎‏‎‏‎‏‎‏‏‏‎‎‏‎‏‎‎‏‎‏‏‏‏‏‏‎‎‎‏‏‏‎‏‎‎‎‎‎‏‏‏‎‎‎‏‎‏‎Pause‎‏‎‎‏‎"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‏‏‎‏‎‎‎‎‎‎‏‏‏‎‎‎‎‏‏‏‎‏‏‏‎‏‎‏‎‎‏‏‎‎‏‏‎‎‎‏‏‏‎‎‏‎‎‎‏‎‏‎‏‏‏‏‎‎Skip to next‎‏‎‎‏‎"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‏‏‏‏‏‎‎‎‎‎‏‎‏‏‎‎‏‎‏‏‏‎‎‏‏‎‎‏‎‎‏‏‎‎‏‎‎‎‏‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‏‎‏‎Skip to previous‎‏‎‎‏‎"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‎‏‎‎‎‎‏‏‎‎‏‎‏‏‎‎‎‎‏‏‎‎‎‏‏‏‏‎‏‎‏‏‎‏‎‎‎‎‎‏‏‎‎‎‏‏‎‎‎‎‏‎‎‎‎Resize‎‏‎‎‏‎"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‏‏‎‎‎‎‎‏‎‏‏‎‏‏‏‏‎‎‎‎‏‎‎‎‏‎‏‏‎‎‏‏‎‎‎‎‎‎‎‎‏‏‏‏‎‏‎‎‎‎‏‎‏‏‎‎‎‎Phone turned off due to heat‎‏‎‎‏‎"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‏‏‎‎‏‏‎‏‎‎‏‎‏‏‏‏‎‏‏‎‏‏‏‏‏‎‎‎‎‎‏‎‎‎‏‏‎‎‏‎‏‏‏‎‏‏‏‎‏‏‏‎Your phone is now running normally‎‏‎‎‏‎"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‏‏‎‎‏‏‏‎‏‎‏‏‏‏‏‎‎‎‎‎‏‎‎‏‏‎‎‎‎‏‏‏‏‏‏‏‎‎‎‎‎‏‏‏‎‏‎‎‏‏‎‏‏‏‏‏‏‎Your phone was too hot, so it turned off to cool down. Your phone is now running normally.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Your phone may get too hot if you:‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎ • Use resource-intensive apps (such as gaming, video, or navigation apps)‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎ • Download or upload large files‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎ • Use your phone in high temperatures‎‏‎‎‏‎"</string>
@@ -1045,7 +1046,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‏‏‏‏‏‎‎‏‏‎‏‏‎‏‏‎‎‎‏‏‏‎‎‏‎‎‎‏‏‎‏‎‏‏‎‏‎‎‎‏‎‏‎‏‎‎‏‎‎‏‏‎‏‏‏‏‏‎Hold &amp; drag to rearrange controls‎‏‎‎‏‎"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‏‎‎‏‏‏‎‏‏‏‎‎‏‎‏‏‏‏‏‏‎‎‏‏‏‎‏‏‎‎‏‏‏‏‏‎‎‏‎‏‎‎‏‎‎‎‏‏‎‏‏‏‏‏‎‎‎‎All controls removed‎‏‎‎‏‎"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‎‎‏‏‏‎‏‎‎‏‎‏‏‎‏‎‎‏‏‏‎‎‏‎‏‏‎‎‎‎‎‏‎‎‎‏‏‏‏‎‎‎‏‎‏‏‎‏‏‎‏‏‎‏‎‏‏‎Changes not saved‎‏‎‎‏‎"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‏‎‎‏‎‎‏‏‏‏‏‎‎‏‎‎‏‏‏‎‎‎‎‏‏‎‎‏‏‏‏‎‏‎‏‎‏‏‏‎‎‎‏‎‎‎‎‎‏‏‎‏‏‎‏‎‎‎The list of all controls could not be loaded.‎‏‎‎‏‎"</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‏‎‎‏‎‎‎‏‏‏‏‏‏‏‎‏‎‎‏‏‏‎‎‏‏‏‏‎‎‏‏‎‎‏‏‏‏‏‎‏‎‎‎‎‎‎‏‏‏‎‏‏‎‏‎‏‏‎Controls could not be loaded. Check the ‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>‎‏‎‎‏‏‏‎ app to make sure that the app settings haven’t changed.‎‏‎‎‏‎"</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‎‏‎‏‎‏‏‏‏‏‏‎‏‎‎‎‏‎‎‏‎‎‎‎‎‏‎‎‎‏‏‏‏‏‎‏‏‏‏‎‎‎‎‏‎‏‎‎‎‏‏‎‎‏‏‏‏‎Compatible controls unavailable‎‏‎‎‏‎"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‎‏‎‎‏‏‎‎‏‎‏‏‎‎‎‏‏‎‏‏‎‏‏‎‏‎‏‏‏‏‏‎‏‎‎‏‏‎‎‎‎‏‎‏‏‎‎‎‎‏‎‎‎Other‎‏‎‎‏‎"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‏‎‎‎‎‏‏‎‎‎‎‎‎‏‎‎‎‎‏‏‎‎‎‏‏‎‏‎‏‎‎‎‏‏‎‎‎‏‏‎‎‏‏‎‏‎‏‎‏‎‏‏‏‎‏‎‎Add to device controls‎‏‎‎‏‎"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‎‎‏‏‏‎‎‎‏‏‏‎‏‎‏‎‏‏‎‎‎‎‏‎‎‏‏‏‏‎‏‏‎‏‎‎‎‎‏‎‏‎‎‎‏‎‏‎‎‏‏‎‏‏‏‏‎‎Add‎‏‎‎‏‎"</string>
@@ -1061,8 +1063,11 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‏‏‏‎‎‎‏‎‎‏‎‏‏‎‎‏‏‏‎‏‎‏‏‏‏‏‎‎‏‏‏‏‎‏‎‎‏‎‏‏‏‎‏‏‎‏‏‏‏‎‏‎‏‏‎Confirm change for ‎‏‎‎‏‏‎<xliff:g id="DEVICE">%s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‎‎‏‏‏‎‎‏‏‎‏‎‏‏‎‎‎‎‎‏‎‏‏‏‎‏‏‎‏‏‏‏‏‏‏‎‏‎‏‎‏‎‏‏‎‏‏‎‏‎‏‏‏‏‎‏‏‎Swipe to see more‎‏‎‎‏‎"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‎‎‎‎‏‏‎‏‎‎‏‏‎‏‎‏‏‎‏‎‏‏‎‏‏‏‏‏‎‎‏‎‎‏‎‏‎‏‏‏‎‎‎‏‎‎‏‎‎‎‏‎‏‎‏‎‎‎Loading recommendations‎‏‎‎‏‎"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‎‏‏‏‎‏‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‎‎‏‏‏‎‏‎‏‎‎‏‏‏‏‏‏‏‎‏‎‎‎‎‏‎‎‏‏‏‏‎‎‏‎Close this media session‎‏‎‎‏‎"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‎‎‎‏‏‏‏‏‎‎‏‏‎‎‏‏‏‎‏‎‎‏‏‎‎‏‏‎‎‎‎‏‏‏‎‎‏‎‏‏‎‏‎‎‎‎‏‎‏‎‎‎‎‎‏‎‏‎Media‎‏‎‎‏‎"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‎‏‏‏‎‏‎‏‎‎‏‏‎‏‎‏‏‏‎‎‎‎‎‎‏‎‏‎‏‏‎‏‎‎‎‏‎‎‎‎‏‎‎‎‏‏‏‎‏‏‏‏‏‏‎‎‏‎Hide the current session.‎‏‎‎‏‎"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‎‎‏‎‎‎‎‎‎‎‏‎‏‎‎‏‎‎‏‎‎‎‏‏‎‏‏‎‏‎‎‏‏‎‏‎‏‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‏‎‎Hide‎‏‎‎‏‎"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‎‏‏‎‏‎‏‎‏‎‎‏‏‏‏‏‎‏‏‎‏‎‎‎‏‎‏‏‏‏‏‎‎‎‏‏‎‎‏‎‏‎‎‏‎‎‎‏‏‏‎‎‎‎‏‎‏‎Resume‎‏‎‎‏‎"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‎‏‎‏‏‎‏‎‏‏‏‎‏‎‏‏‎‏‎‎‎‎‎‎‏‎‏‏‎‏‎‎‎‏‏‎‏‏‎‏‏‎‎‎‎‎‎‏‏‎‎‎‏‏‎‎‎‎Settings‎‏‎‎‏‎"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‏‎‎‎‎‎‏‎‏‏‎‎‎‏‏‏‎‎‎‏‏‏‎‏‎‎‎‏‎‏‎‏‎‎‏‏‏‏‎‏‏‎‏‎‎‎‎‏‎‎‏‏‏‏‏‏‎‎Inactive, check app‎‏‎‎‏‎"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‎‎‏‎‏‏‏‏‎‏‏‎‎‏‏‏‎‎‎‏‏‎‏‏‎‏‎‏‏‎‎‎‎‎‎‏‏‏‏‎‎‏‏‎‎Error, retrying…‎‏‎‎‏‎"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‎‏‎‎‏‎‎‏‎‏‎‎‎‎‏‎‏‏‏‎‏‎‎‏‎‎‏‏‎‏‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‎‏‏‎‎‏‏‏‏‎‎Not found‎‏‎‎‏‎"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index b4bba8f3145b..874b99a9d84c 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -454,8 +454,8 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Presiona de nuevo para abrir"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Desliza el dedo hacia arriba para abrir"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Desliza el dedo hacia arriba para volver a intentarlo"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"Tu organización administra este dispositivo"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> administra este dispositivo"</string>
+ <string name="do_disclosure_generic" msgid="4896482821974707167">"Este dispositivo pertenece a tu organización"</string>
+ <string name="do_disclosure_with_name" msgid="2091641464065004091">"Este dispositivo pertenece a <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="6682125338461375925">"Desliza el dedo para desbloquear el teléfono."</string>
<string name="voice_hint" msgid="7476017460191291417">"Desliza el dedo desde el ícono para abrir asistente de voz."</string>
<string name="camera_hint" msgid="4519495795000658637">"Desliza el dedo para acceder a la cámara."</string>
@@ -521,21 +521,21 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"Es posible que se supervise el perfil."</string>
<string name="vpn_footer" msgid="3457155078010607471">"Es posible que la red esté supervisada."</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"Es posible que la red esté supervisada"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"Tu organización administra este dispositivo y podría controlar el tráfico de red"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> administra este dispositivo y podría controlar el tráfico de red"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"Tu organización administra el dispositivo, el cual está conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> administra el dispositivo, el cual está conectado a <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"Tu organización administra el dispositivo"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> administra este dispositivo"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"Tu organización administra el dispositivo, el cual está conectado a varias VPN"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> administra el dispositivo, el cual está conectado a varias VPN"</string>
+ <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Tu organización es propietaria de este dispositivo y podría controlar el tráfico de red"</string>
+ <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> es la organización propietaria de este dispositivo y podría controlar el tráfico de red"</string>
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Este dispositivo pertenece a tu organización y está conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Este dispositivo pertenece a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> y está conectado a <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Este dispositivo pertenece a tu organización"</string>
+ <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Este dispositivo pertenece a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management_vpns" msgid="371835422690053154">"Este dispositivo pertenece a tu organización y está conectado a VPN"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="4046375645500668555">"Este dispositivo pertenece a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> y está conectado a VPN"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Tu organización puede controlar el tráfico de red en tu perfil de trabajo"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"Es posible que <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> controle el tráfico de red en tu perfil de trabajo"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Es posible que la red esté supervisada"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"Dispositivo conectado a varias VPN"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"Perfil de trabajo conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"Perfil personal conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"Dispositivo conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_vpns" msgid="7213546797022280246">"Este dispositivo está conectado a VPN"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Tu perfil de trabajo está conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Tu perfil personal está conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Este dispositivo está conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Administración del dispositivo"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Supervisión del perfil"</string>
<string name="monitoring_title" msgid="4063890083735924568">"Supervisión de red"</string>
@@ -545,8 +545,8 @@
<string name="disable_vpn" msgid="482685974985502922">"Inhabilitar VPN"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"Desconectar VPN"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"Ver políticas"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> administra tu dispositivo.\n\nTu administrador puede controlar y administrar la configuración, el acceso corporativo, las apps, los datos asociados a tu dispositivo y la información de ubicación.\n\nPara obtener más información, comunícate con tu administrador."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"Tu organización administra tu dispositivo.\n\nTu administrador puede controlar y administrar la configuración, el acceso corporativo, las apps, los datos asociados a tu dispositivo y la información de ubicación.\n\nPara obtener más información, comunícate con tu administrador."</string>
+ <string name="monitoring_description_named_management" msgid="505833016545056036">"Este dispositivo pertenece a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nTu administrador de TI puede controlar y administrar la configuración, el acceso corporativo, las apps, los datos asociados al dispositivo y la información de ubicación.\n\nPara obtener más información, comunícate con el administrador de TI."</string>
+ <string name="monitoring_description_management" msgid="4308879039175729014">"Este dispositivo pertenece a tu organización.\n\nTu administrador de TI puede controlar y administrar la configuración, el acceso corporativo, las apps, los datos asociados al dispositivo y la información de ubicación.\n\nPara obtener más información, comunícate con el administrador de TI."</string>
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Tu organización instaló una autoridad de certificación en este dispositivo. Es posible que se controle o modifique el tráfico de tu red segura."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Tu organización instaló una autoridad de certificación en tu perfil de trabajo. Es posible que se controle o modifique el tráfico de tu red segura."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Hay una autoridad de certificación instalada en este dispositivo. Es posible que se controle o modifique el tráfico de tu red segura."</string>
@@ -920,6 +920,7 @@
<string name="pip_pause" msgid="1139598607050555845">"Pausar"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"Siguiente"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"Anterior"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"Cambiar el tamaño"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"El teléfono se apagó por calor"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"Tu teléfono ya funciona correctamente"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Tu teléfono estaba muy caliente y se apagó para enfriarse. Ya funciona correctamente.\n\nTu teléfono puede calentarse en estos casos:\n • Usas apps que consumen muchos recursos (como juegos, videos o navegación).\n • Subes o descargas archivos grandes.\n • Usas el teléfono en condiciones de temperatura alta."</string>
@@ -1006,7 +1007,7 @@
<string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"No mostrar la conversación en burbujas"</string>
<string name="bubbles_user_education_title" msgid="5547017089271445797">"Chat con burbujas"</string>
<string name="bubbles_user_education_description" msgid="1160281719576715211">"Las conversaciones nuevas aparecen como elementos flotantes o burbujas. Presiona para abrir la burbuja. Arrástrala para moverla."</string>
- <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Controla las burbujas en todo momento"</string>
+ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Controla las burbujas"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"Presiona Administrar para desactivar las burbujas de esta app"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Entendido"</string>
<string name="bubbles_app_settings" msgid="5779443644062348657">"Configuración de <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
@@ -1015,9 +1016,9 @@
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"En espera"</string>
<string name="priority_onboarding_title" msgid="2893070698479227616">"Se estableció la conversación como prioritaria"</string>
<string name="priority_onboarding_behavior" msgid="5342816047020432929">"Las conversaciones prioritarias harán lo siguiente:"</string>
- <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Se muestran en la parte superior de conversaciones"</string>
- <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Muestran una foto de perfil en pantalla de bloqueo"</string>
- <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Aparecen como burbujas flotantes encima de apps"</string>
+ <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Mostrarse en la parte superior de conversaciones"</string>
+ <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Mostrarán una foto de perfil en pantalla de bloqueo"</string>
+ <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Aparecerán como burbujas flotantes encima de apps"</string>
<string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Suspender No interrumpir"</string>
<string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Entendido"</string>
<string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Configuración"</string>
@@ -1045,7 +1046,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Mantén presionado y arrastra un control para reubicarlo"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"Se quitaron todos los controles"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"No se guardaron los cambios"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"No se cargó la lista completa de controles."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"No se pudieron cargar los controles. Revisa la app de <xliff:g id="APP">%s</xliff:g> para asegurarte de que su configuración no haya cambiado."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"No hay ningún control compatible disponible"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Otros"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"Agregar a controles de dispositivos"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"Agregar"</string>
@@ -1056,17 +1058,20 @@
<string name="controls_pin_wrong" msgid="6162694056042164211">"PIN incorrecto"</string>
<string name="controls_pin_verifying" msgid="3755045989392131746">"Verificando…"</string>
<string name="controls_pin_instructions" msgid="6363309783822475238">"Ingresa el PIN"</string>
- <string name="controls_pin_instructions_retry" msgid="1566667581012131046">"Probar con otro PIN"</string>
+ <string name="controls_pin_instructions_retry" msgid="1566667581012131046">"Prueba con otro PIN"</string>
<string name="controls_confirmation_confirming" msgid="2596071302617310665">"Confirmando…"</string>
<string name="controls_confirmation_message" msgid="7744104992609594859">"Confirmar cambio para <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Desliza el dedo para ver más elementos"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Cargando recomendaciones"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"Cerrar esta sesión multimedia"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"Contenido multimedia"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"Oculta la sesión actual."</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ocultar"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Reanudar"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"Configuración"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inactivo. Verifica la app"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Hubo un error. Reintentando…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"No se encontró"</string>
- <string name="controls_error_removed_title" msgid="1207794911208047818">"El control no está disponible."</string>
+ <string name="controls_error_removed_title" msgid="1207794911208047818">"El control no está disponible"</string>
<string name="controls_error_removed_message" msgid="2885911717034750542">"No se pudo acceder a <xliff:g id="DEVICE">%1$s</xliff:g>. Revisa la app de <xliff:g id="APPLICATION">%2$s</xliff:g> para asegurarte de que el control siga estando disponible y de que no haya cambiado la configuración de la app."</string>
<string name="controls_open_app" msgid="483650971094300141">"Abrir app"</string>
<string name="controls_error_generic" msgid="352500456918362905">"No se pudo cargar el estado"</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 6ffed58c3df8..91f33feeed3a 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -454,8 +454,8 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Toca de nuevo para abrir"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Desliza el dedo hacia arriba para abrir"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Desliza el dedo hacia arriba para volverlo a intentar"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"Este dispositivo está administrado por tu organización"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"Este dispositivo está administrado por <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
+ <string name="do_disclosure_generic" msgid="4896482821974707167">"Este dispositivo pertenece a tu organización"</string>
+ <string name="do_disclosure_with_name" msgid="2091641464065004091">"Este dispositivo pertenece a <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="6682125338461375925">"Desliza desde el icono para abrir el teléfono"</string>
<string name="voice_hint" msgid="7476017460191291417">"Desliza desde el icono para abrir asistente de voz"</string>
<string name="camera_hint" msgid="4519495795000658637">"Desliza desde el icono para abrir la cámara"</string>
@@ -521,21 +521,21 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"Es posible que se supervise el perfil"</string>
<string name="vpn_footer" msgid="3457155078010607471">"Puede que la red esté supervisada"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"Puede que la red esté supervisada"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"Tu organización administra este dispositivo y puede supervisar el tráfico de red"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> administra este dispositivo y puede supervisar el tráfico de red"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"Dispositivo administrado por tu organización y conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> administra este dispositivo, que está conectado a <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"Dispositivo administrado por tu organización"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> administra este dispositivo"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"Dispositivo administrado por tu organización y conectado a redes VPN"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> administra este dispositivo, que está conectado a redes VPN"</string>
+ <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"El dispositivo pertenece a tu organización, que puede supervisar su tráfico de red"</string>
+ <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"El dispositivo pertenece a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>, que puede supervisar su tráfico de red"</string>
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Este dispositivo pertenece a tu organización y está conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Este dispositivo pertenece a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> y está conectado a <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Este dispositivo pertenece a tu organización"</string>
+ <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Este dispositivo pertenece a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management_vpns" msgid="371835422690053154">"Este dispositivo pertenece a tu organización y está conectado a VPNs"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="4046375645500668555">"Este dispositivo pertenece a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> y está conectado a VPNs"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Tu organización puede supervisar el tráfico de red de tu perfil de trabajo"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> puede supervisar el tráfico de red de tu perfil de trabajo"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Puede que la red esté supervisada"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"Dispositivo conectado a redes VPN"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"Perfil de trabajo conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"Perfil personal conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"Dispositivo conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_vpns" msgid="7213546797022280246">"Este dispositivo está conectado a VPNs"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Tu perfil de trabajo está conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Tu perfil personal está conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Este dispositivo está conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Administración de dispositivos"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Supervisión del perfil"</string>
<string name="monitoring_title" msgid="4063890083735924568">"Supervisión de red"</string>
@@ -545,8 +545,8 @@
<string name="disable_vpn" msgid="482685974985502922">"Inhabilitar VPN"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"Desconectar VPN"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"Ver políticas"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"El dispositivo está administrado por <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nEl administrador puede supervisar y gestionar los ajustes, el acceso corporativo, las aplicaciones, los datos asociados a este dispositivo y su información de ubicación.\n\nPara obtener más información, ponte en contacto con el administrador."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"El dispositivo está administrado por tu organización.\n\nEl administrador puede supervisar y gestionar los ajustes, el acceso corporativo, las aplicaciones, los datos asociados a este dispositivo y su información de ubicación.\n\nPara obtener más información, ponte en contacto con el administrador."</string>
+ <string name="monitoring_description_named_management" msgid="505833016545056036">"El dispositivo pertenece a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nEl administrador de TI puede supervisar y gestionar los ajustes, el acceso corporativo, las aplicaciones, la información de ubicación del dispositivo y los datos asociados a él.\n\nPara obtener más información, ponte en contacto con el administrador de TI."</string>
+ <string name="monitoring_description_management" msgid="4308879039175729014">"El dispositivo pertenece a tu organización.\n\nEl administrador de TI puede supervisar y gestionar los ajustes, el acceso corporativo, las aplicaciones, la información de ubicación del dispositivo y los datos asociados a él.\n\nPara obtener más información, ponte en contacto con el administrador de TI."</string>
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Tu organización ha instalado una entidad de certificación en este dispositivo. Es posible que se supervise o se modifique tu tráfico de red seguro."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Tu organización ha instalado una entidad de certificación en tu perfil de trabajo. Es posible que se supervise o se modifique tu tráfico de red seguro."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Se ha instalado una entidad de certificación en este dispositivo. Es posible que se supervise o se modifique tu tráfico de red seguro."</string>
@@ -716,7 +716,7 @@
<string name="notification_channel_summary_default" msgid="3282930979307248890">"Es posible que suene o vibre según los ajustes del teléfono"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="1782419896613644568">"Es posible que suene o vibre según los ajustes del teléfono. Las conversaciones de <xliff:g id="APP_NAME">%1$s</xliff:g> aparecen como burbujas de forma predeterminada."</string>
<string name="notification_channel_summary_bubble" msgid="7235935211580860537">"Llama tu atención con un acceso directo flotante a este contenido."</string>
- <string name="notification_channel_summary_priority" msgid="7952654515769021553">"Se muestra en la parte superior de la sección de conversaciones en forma de burbuja flotante, y la imagen de perfil aparece en la pantalla de bloqueo"</string>
+ <string name="notification_channel_summary_priority" msgid="7952654515769021553">"Se muestra arriba en la sección de conversaciones en forma de burbuja flotante, y la imagen de perfil aparece en la pantalla de bloqueo"</string>
<string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Ajustes"</string>
<string name="notification_priority_title" msgid="2079708866333537093">"Prioridad"</string>
<string name="no_shortcut" msgid="8257177117568230126">"No se pueden usar funciones de conversación con <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
@@ -920,6 +920,7 @@
<string name="pip_pause" msgid="1139598607050555845">"Pausar"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"Saltar al siguiente"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"Volver al anterior"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"Cambiar tamaño"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"Teléfono apagado por calor"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"El teléfono ahora funciona con normalidad"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"El teléfono se había calentado demasiado y se ha apagado para enfriarse. Ahora funciona con normalidad.\n\nPuede calentarse demasiado si:\n • Usas aplicaciones que consumen muchos recursos (p. ej., apps de juegos, vídeos o navegación)\n • Descargas o subes archivos grandes\n • Lo usas a altas temperaturas"</string>
@@ -1003,10 +1004,10 @@
<string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Mover abajo a la izquierda."</string>
<string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Mover abajo a la derecha"</string>
<string name="bubble_dismiss_text" msgid="1314082410868930066">"Cerrar burbuja"</string>
- <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"No mostrar conversación en burbujas"</string>
+ <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"No mostrar conversación en burbuja"</string>
<string name="bubbles_user_education_title" msgid="5547017089271445797">"Chatea con burbujas"</string>
<string name="bubbles_user_education_description" msgid="1160281719576715211">"Las conversaciones nuevas aparecen como iconos flotantes llamadas \"burbujas\". Toca para abrir la burbuja. Arrastra para moverla."</string>
- <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Controla las burbujas en cualquier momento"</string>
+ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Controla las burbujas"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"Toca Gestionar para desactivar las burbujas de esta aplicación"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Entendido"</string>
<string name="bubbles_app_settings" msgid="5779443644062348657">"Ajustes de <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
@@ -1045,7 +1046,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Mantén pulsado y arrastra un control para reubicarlo"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"Todos los controles quitados"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"No se han guardado los cambios"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"No se ha podido cargar la lista de los controles."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"No se han podido cargar los controles. Comprueba que no hayan cambiado los ajustes de la aplicación <xliff:g id="APP">%s</xliff:g>."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"Los controles compatibles no están disponibles"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Otros"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"Añadir a control de dispositivos"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"Añadir"</string>
@@ -1061,16 +1063,19 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"Confirma el cambio de <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Desliza el dedo para ver más"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Cargando recomendaciones"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"Cerrar esta sesión multimedia"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"Multimedia"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"Ocultar la sesión."</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ocultar"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Reanudar"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"Ajustes"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inactivo, comprobar aplicación"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Error; reintentando…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"No se ha encontrado"</string>
- <string name="controls_error_removed_title" msgid="1207794911208047818">"El control no está disponible"</string>
- <string name="controls_error_removed_message" msgid="2885911717034750542">"No se ha podido acceder a <xliff:g id="DEVICE">%1$s</xliff:g>. Comprueba que el control siga disponible en la aplicación <xliff:g id="APPLICATION">%2$s</xliff:g> y que no se haya modificado su configuración."</string>
+ <string name="controls_error_removed_title" msgid="1207794911208047818">"Control no disponible"</string>
+ <string name="controls_error_removed_message" msgid="2885911717034750542">"No se ha podido acceder a <xliff:g id="DEVICE">%1$s</xliff:g>. Comprueba que el control siga disponible en la aplicación <xliff:g id="APPLICATION">%2$s</xliff:g> y que no se haya cambiado su configuración."</string>
<string name="controls_open_app" msgid="483650971094300141">"Abrir aplicación"</string>
<string name="controls_error_generic" msgid="352500456918362905">"No se ha podido cargar el estado"</string>
- <string name="controls_error_failed" msgid="960228639198558525">"Se ha producido un error. Vuelve a intentarlo."</string>
+ <string name="controls_error_failed" msgid="960228639198558525">"Error: Vuelve a intentarlo"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"En curso"</string>
<string name="controls_added_tooltip" msgid="4842812921719153085">"Mantén pulsado el botón de encendido para ver los controles nuevos"</string>
<string name="controls_menu_add" msgid="4447246119229920050">"Añadir controles"</string>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index 258bf5a581d0..c1aa9eb3eef0 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -454,8 +454,8 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Avamiseks puudutage uuesti"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Pühkige avamiseks üles"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Uuesti proovimiseks pühkige üles"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"Seda seadet haldab teie organisatsioon"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"Seda seadet haldab <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
+ <string name="do_disclosure_generic" msgid="4896482821974707167">"See seade kuulub teie organisatsioonile"</string>
+ <string name="do_disclosure_with_name" msgid="2091641464065004091">"Selle seadme omanik on <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="6682125338461375925">"Telefoni kasutamiseks pühkige ikoonilt eemale"</string>
<string name="voice_hint" msgid="7476017460191291417">"Häälabi kasutamiseks pühkige ikoonilt eemale"</string>
<string name="camera_hint" msgid="4519495795000658637">"Kaamera kasutamiseks pühkige ikoonilt eemale"</string>
@@ -521,21 +521,21 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"Profiili võidakse jälgida"</string>
<string name="vpn_footer" msgid="3457155078010607471">"Võrku võidakse jälgida"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"Võrku võidakse jälgida"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"Teie organisatsioon haldab seda seadet ja võib jälgida võrguliiklust"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> haldab seda seadet ja võib jälgida võrguliiklust"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"Seadet haldab teie organisatsioon ja see on ühendatud rakendusega <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"Seadet haldab <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ja see on ühendatud rakendusega <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"Seadet haldab teie organisatsioon"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"Seadet haldab <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"Seadet haldab teie organisatsioon ja see on ühendatud VPN-idega"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"Seadet haldab <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ja see on ühendatud VPN-idega"</string>
+ <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Teie organisatsioon on selle seadme omanik ja võib jälgida võrguliiklust"</string>
+ <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> on selle seadme omanik ja võib jälgida võrguliiklust"</string>
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"See seade kuulub teie organisatsioonile ja on ühendatud rakendusega <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"See seade kuulub organisatsioonile <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ja on ühendatud rakendusega <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"See seade kuulub teie organisatsioonile"</string>
+ <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Selle seadme omanik on <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management_vpns" msgid="371835422690053154">"See seade kuulub teie organisatsioonile ja on ühendatud VPN-idega"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="4046375645500668555">"See seade kuulub organisatsioonile <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ja on ühendatud VPN-idega"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Teie organisatsioon võib jälgida teie tööprofiilil võrguliiklust"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> võib jälgida võrguliiklust teie tööprofiilil"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Võrku võidakse jälgida"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"Seade on ühendatud VPN-idega"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"Tööprofiil on ühendatud rakendusega <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"Isiklik profiil on ühendatud rakendusega <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"Seade on ühendatud rakendusega <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_vpns" msgid="7213546797022280246">"See seade on ühendatud VPN-idega"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Teie tööprofiil on ühendatud rakendusega <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Teie isiklik profiil on ühendatud rakendusega <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"See seade on ühendatud rakendusega <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Seadmehaldus"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Profiili jälgimine"</string>
<string name="monitoring_title" msgid="4063890083735924568">"Võrgu jälgimine"</string>
@@ -545,8 +545,8 @@
<string name="disable_vpn" msgid="482685974985502922">"Keela VPN"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"Katkesta VPN-i ühendus"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"Kuva eeskirjad"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"Teie seadet haldab organisatsioon <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nAdministraator saab jälgida ning hallata seadeid, ettevõttesisest juurdepääsu, rakendusi, seadmega seotud andmeid ja seadme asukohateavet.\n\nLisateabe saamiseks võtke ühendust administraatoriga."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"Teie seadet haldab teie organisatsioon.\n\nAdministraator saab jälgida ning hallata seadeid, ettevõttesisest juurdepääsu, rakendusi, seadmega seotud andmeid ja seadme asukohateavet.\n\nLisateabe saamiseks võtke ühendust administraatoriga."</string>
+ <string name="monitoring_description_named_management" msgid="505833016545056036">"See seade kuulub organisatsioonile <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nIT-administraator saab jälgida ning hallata seadeid, ettevõttesisest juurdepääsu, rakendusi, seadmega seotud andmeid ja seadme asukohateavet.\n\nLisateabe saamiseks võtke ühendust IT-administraatoriga."</string>
+ <string name="monitoring_description_management" msgid="4308879039175729014">"See seade kuulub teie organisatsioonile.\n\nIT-administraator saab jälgida ning hallata seadeid, ettevõttesisest juurdepääsu, rakendusi, seadmega seotud andmeid ja seadme asukohateavet.\n\nLisateabe saamiseks võtke ühendust IT-administraatoriga."</string>
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Teie organisatsioon installis sellesse seadmesse sertifikaadi volituse. Teie turvalist võrguliiklust võidakse jälgida ja muuta."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Teie organisatsioon installis teie tööprofiilile sertifikaadi volituse. Teie turvalist võrguliiklust võidakse jälgida ja muuta."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Sertifikaadi volitus on sellesse seadmesse installitud. Teie turvalist võrguliiklust võidakse jälgida ja muuta."</string>
@@ -920,6 +920,7 @@
<string name="pip_pause" msgid="1139598607050555845">"Peata"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"Järgmise juurde"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"Eelmise juurde"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"Suuruse muutmine"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"Tel. lül. kuumuse tõttu välja"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"Telefon töötab nüüd tavapäraselt"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Telefon oli liiga kuum, seetõttu lülitus see jahtumiseks välja. Telefon töötab nüüd tavapäraselt.\n\nTelefon võib kuumaks minna:\n • ressursse koormavate rakenduste kasutamisel (nt mängu-, video- või navigatsioonirakendused)\n • suurte failide alla-/üleslaadimisel\n • telefoni kasutamisel kõrgel temperatuuril"</string>
@@ -1007,7 +1008,7 @@
<string name="bubbles_user_education_title" msgid="5547017089271445797">"Vestelge mullide abil"</string>
<string name="bubbles_user_education_description" msgid="1160281719576715211">"Uued vestlused kuvatakse hõljuvate ikoonidena ehk mullidena. Puudutage mulli avamiseks. Lohistage mulli, et seda liigutada."</string>
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Juhtige mulle igal ajal"</string>
- <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Selle rakenduse puhul mullide väljalülitamiseks puudutage valikut Haldamine"</string>
+ <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Selle rakenduse puhul mullide väljalülitamiseks puudutage valikut Halda"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Selge"</string>
<string name="bubbles_app_settings" msgid="5779443644062348657">"Rakenduse <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> seaded"</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Süsteemis navigeerimine on värskendatud. Muutmiseks avage jaotis Seaded."</string>
@@ -1045,7 +1046,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Juhtelementide ümberpaigutamiseks hoidke neid all ja lohistage"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"Kõik juhtelemendid eemaldati"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Muudatusi ei salvestatud"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"Kõikide juhtelementide loendit ei saanud laadida."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"Juhtelemente ei õnnestunud laadida. Kontrollige rakendust <xliff:g id="APP">%s</xliff:g> ja veenduge, et rakenduse seaded poleks muutunud."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"Ühilduvaid juhtelemente pole saadaval"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Muu"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"Seadmete juhtimisvidinate hulka lisamine"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"Lisa"</string>
@@ -1061,8 +1063,11 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"Kinnitage seadme <xliff:g id="DEVICE">%s</xliff:g> muudatus"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Pühkige sõrmega, et näha rohkem"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Soovituste laadimine"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"Sulge see meediaseanss"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"Meedia"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"Peidetakse praegune seanss."</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Peida"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Jätka"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"Seaded"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Passiivne, vaadake rakendust"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Viga, proovitakse uuesti …"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Ei leitud"</string>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index cb6f7967d3e8..74a0e126508c 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -454,8 +454,10 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Irekitzeko, ukitu berriro"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Pasatu hatza gora irekitzeko"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Berriro saiatzeko, pasatu hatza gora"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"Zure erakundeak kudeatzen du gailua"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> erakundeak kudeatzen du gailu hau"</string>
+ <!-- no translation found for do_disclosure_generic (4896482821974707167) -->
+ <skip />
+ <!-- no translation found for do_disclosure_with_name (2091641464065004091) -->
+ <skip />
<string name="phone_hint" msgid="6682125338461375925">"Pasatu hatza ikonotik, telefonoa irekitzeko"</string>
<string name="voice_hint" msgid="7476017460191291417">"Pasatu hatza ikonotik, ahots-laguntza irekitzeko"</string>
<string name="camera_hint" msgid="4519495795000658637">"Pasatu hatza ikonotik, kamera irekitzeko"</string>
@@ -521,21 +523,33 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"Baliteke profila kontrolatuta egotea"</string>
<string name="vpn_footer" msgid="3457155078010607471">"Baliteke sarea kontrolatuta egotea"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"Baliteke sarea kontrolatuta egotea"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"Erakundeak kudeatzen du gailua, eta baliteke sareko trafikoa gainbegiratzea"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> erakundeak kudeatzen du gailua eta baliteke sareko trafikoa gainbegiratzea"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"Erakundeak kudeatzen du gailua, zeina <xliff:g id="VPN_APP">%1$s</xliff:g> aplikaziotara konektatuta baitago"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> erakundeak kudeatzen du gailua, zeina <xliff:g id="VPN_APP">%2$s</xliff:g> aplikaziora konektatuta baitago"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"Erakundeak kudeatzen du gailua"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> erakundeak kudeatzen du gailu hau"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"Erakundeak kudeatzen du gailua, zeina bi VPN aplikaziotara konektatuta baitago"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> erakundeak kudeatzen du gailua, zeina bi VPN aplikaziotara konektatuta baitago"</string>
+ <!-- no translation found for quick_settings_disclosure_management_monitoring (8231336875820702180) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_monitoring (2831423806103479812) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_named_vpn (6096715329056415588) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (5302786161534380104) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management (5515296598440684962) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management (3476472755775165827) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_vpns (371835422690053154) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_vpns (4046375645500668555) -->
+ <skip />
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Baliteke erakundeak laneko profileko sareko trafikoa gainbegiratzea"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"Baliteke <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> erakundeak laneko profilaren sareko trafikoa gainbegiratzea"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Baliteke sarea gainbegiratuta egotea"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"Bi VPN aplikaziotara dago konektatuta gailua"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"<xliff:g id="VPN_APP">%1$s</xliff:g> aplikaziora dago konektatuta laneko profila"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"<xliff:g id="VPN_APP">%1$s</xliff:g> aplikaziora konektatuta dago profil pertsonala"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"<xliff:g id="VPN_APP">%1$s</xliff:g> aplikaziora konektatuta dago gailua"</string>
+ <!-- no translation found for quick_settings_disclosure_vpns (7213546797022280246) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (8117568745060010789) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (5481763430080807797) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_vpn (2350838218824492465) -->
+ <skip />
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Gailuaren kudeaketa"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Profila kontrolatzeko aukera"</string>
<string name="monitoring_title" msgid="4063890083735924568">"Sareen kontrola"</string>
@@ -545,8 +559,10 @@
<string name="disable_vpn" msgid="482685974985502922">"Desgaitu VPN konexioa"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"Deskonektatu VPN sarea"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"Ikusi gidalerroak"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> erakundeak kudeatzen dizu gailua.\n\nAdministratzaileak gainbegiratu eta kudea ditzake ezarpenak, enpresa-sarbidea, aplikazioak, gailuarekin erlazionatutako datuak eta gailuaren kokapen-informazioa.\n\nInformazio gehiago lortzeko, jarri administratzailearekin harremanetan."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"Erakundeak kudeatzen dizu gailua.\n\nAdministratzaileak gainbegiratu eta kudea ditzake ezarpenak, enpresa-sarbidea, aplikazioak, gailuarekin erlazionatutako datuak eta gailuaren kokapen-informazioa.\n\nInformazio gehiago lortzeko, jarri administratzailearekin harremanetan."</string>
+ <!-- no translation found for monitoring_description_named_management (505833016545056036) -->
+ <skip />
+ <!-- no translation found for monitoring_description_management (4308879039175729014) -->
+ <skip />
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Erakundeak ziurtagiri-emaile bat instalatu du gailuan. Baliteke sareko trafiko segurua gainbegiratzea edo aldatzea."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Erakundeak ziurtagiri-emaile bat instalatu dizu laneko profilean. Baliteke sareko trafiko segurua gainbegiratzea edo aldatzea."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Ziurtagiri-emaile bat dago instalatuta gailuan. Baliteke sareko trafiko segurua gainbegiratzea edo aldatzea."</string>
@@ -920,6 +936,7 @@
<string name="pip_pause" msgid="1139598607050555845">"Pausatu"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"Saltatu hurrengora"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"Saltatu aurrekora"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"Aldatu tamaina"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"Beroegi egoteagatik itzali da"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"Orain, ohiko moduan dabil telefonoa"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Telefonoa gehiegi berotu da, eta itzali egin da tenperatura jaisteko. Orain, ohiko moduan dabil.\n\nBerotzearen zergati posibleak:\n • Baliabide asko behar dituzten aplikazioak erabiltzea (adib., jokoak, bideoak edo nabigazio-aplikazioak).\n • Fitxategi handiak deskargatu edo kargatzea.\n • Telefonoa giro beroetan erabiltzea."</string>
@@ -1015,8 +1032,8 @@
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Egonean"</string>
<string name="priority_onboarding_title" msgid="2893070698479227616">"Lehentasunezko gisa ezarritako elkarrizketa"</string>
<string name="priority_onboarding_behavior" msgid="5342816047020432929">"Hau gertatuko da lehentasunezko elkarrizketekin:"</string>
- <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Erakutsi elkarrizketen atalaren goialdean"</string>
- <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Erakutsi profileko argazkia pantaila blokeatuan"</string>
+ <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Elkarrizketen atalaren goialdean erakutsiko dira."</string>
+ <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Profileko argazkia pantaila blokeatuan erakutsiko da."</string>
<string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Burbuila gainerakor gisa agertuko da aplikazioen gainean"</string>
<string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Eten ez molestatzeko modua"</string>
<string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Ados"</string>
@@ -1025,7 +1042,7 @@
<string name="magnification_window_title" msgid="4863914360847258333">"Lupa-leihoa"</string>
<string name="magnification_controls_title" msgid="8421106606708891519">"Lupa-leihoaren aukerak"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"Gailuak kontrolatzeko widgetak"</string>
- <string name="quick_controls_subtitle" msgid="1667408093326318053">"Gehitu kontrolatzeko aukerak konektatutako gailuetan"</string>
+ <string name="quick_controls_subtitle" msgid="1667408093326318053">"Gehitu konektatutako gailuak kontrolatzeko widgetak"</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"Konfiguratu gailuak kontrolatzeko widgetak"</string>
<string name="quick_controls_setup_subtitle" msgid="1681506617879773824">"Kontrol-aukerak atzitzeko, eduki sakatuta etengailua"</string>
<string name="controls_providers_title" msgid="6879775889857085056">"Aukeratu aplikazio bat kontrolatzeko aukerak gehitzeko"</string>
@@ -1045,7 +1062,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Kontrolatzeko aukerak antolatzeko, eduki itzazu sakatuta, eta arrastatu"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"Kendu dira kontrolatzeko aukera guztiak"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Ez dira gorde aldaketak"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"Ezin izan da kargatu kontrol guztien zerrenda."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"Ezin izan dira kargatu kontrolatzeko aukerak. Joan <xliff:g id="APP">%s</xliff:g> aplikaziora, eta ziurtatu aplikazioaren ezarpenak ez direla aldatu."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"Ez dago erabilgarri kontrolatzeko aukera bateragarririk"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Beste bat"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"Gehitu gailuak kontrolatzeko widgetetan"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"Gehitu"</string>
@@ -1061,8 +1079,11 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"Berretsi <xliff:g id="DEVICE">%s</xliff:g> gailuaren aldaketa"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Pasatu hatza aukera gehiago ikusteko"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Gomendioak kargatzen"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"Itxi multimedia-saio hau"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"Multimedia-edukia"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"Ezkutatu uneko saioa."</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ezkutatu"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Berrekin"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"Ezarpenak"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inaktibo; egiaztatu aplikazioa"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Errorea. Berriro saiatzen…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Ez da aurkitu"</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index ae98244cf415..7704ae2260ce 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -454,8 +454,8 @@
<string name="notification_tap_again" msgid="4477318164947497249">"دوباره ضربه بزنید تا باز شود"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"برای باز کردن، انگشتتان را تند به بالا بکشید"</string>
<string name="keyguard_retry" msgid="886802522584053523">"برای امتحان مجدد، انگشتتان را تند به بالا بکشید"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"سازمان شما این دستگاه را مدیریت می‌کند"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"این دستگاه توسط <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> مدیریت می‌شود"</string>
+ <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="phone_hint" msgid="6682125338461375925">"انگشتتان را از نماد تلفن تند بکشید"</string>
<string name="voice_hint" msgid="7476017460191291417">"برای «دستیار صوتی»، تند بکشید"</string>
<string name="camera_hint" msgid="4519495795000658637">"انگشتتان را از نماد دوربین تند بکشید"</string>
@@ -521,21 +521,21 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"شاید نمایه کنترل شود"</string>
<string name="vpn_footer" msgid="3457155078010607471">"ممکن است شبکه کنترل شود"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"ممکن است شبکه کنترل شود"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"سازمان شما این دستگاه را مدیریت می‌کند و ممکن است ترافیک شبکه را پایش کند"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> این دستگاه را مدیریت می‌کند و ممکن است ترافیک شبکه را پایش کند"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"دستگاه توسط سازمان شما مدیریت می‌شود و به <xliff:g id="VPN_APP">%1$s</xliff:g> متصل شده است"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"دستگاه توسط <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> مدیریت می‌شود و به <xliff:g id="VPN_APP">%2$s</xliff:g> متصل شده است"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"دستگاه توسط سازمان شما مدیریت می‌شود"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"دستگاه توسط <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> مدیریت می‌شود"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"‏دستگاه توسط سازمان شما مدیریت می‌شود و به چند VPN متصل شده است"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"‏دستگاه توسط <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> مدیریت می‌شود و به چند VPN متصل شده است"</string>
+ <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"مالک این دستگاه سازمان شما است و ممکن است ترافیک شبکه را پایش کند"</string>
+ <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"مالک این دستگاه <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> است و ممکن است ترافیک شبکه را پایش کند"</string>
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"این دستگاه به سازمان شما تعلق دارد و به <xliff:g id="VPN_APP">%1$s</xliff:g> متصل است"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"این دستگاه به <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> تعلق دارد و به <xliff:g id="VPN_APP">%2$s</xliff:g> متصل است"</string>
+ <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"این دستگاه به سازمان شما تعلق دارد"</string>
+ <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"این دستگاه به <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> تعلق دارد"</string>
+ <string name="quick_settings_disclosure_management_vpns" msgid="371835422690053154">"‏این دستگاه به سازمان شما تعلق دارد و به شبکه‌های VPN متصل است"</string>
+ <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_monitoring" msgid="8548019955631378680">"ممکن است شبکه پایش شود"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"‏دستگاه به چند VPN متصل شده است"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"نمایه کاری به <xliff:g id="VPN_APP">%1$s</xliff:g> متصل شده است"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"نمایه شخصی به <xliff:g id="VPN_APP">%1$s</xliff:g> متصل شده است"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"دستگاه به <xliff:g id="VPN_APP">%1$s</xliff:g> متصل شده است"</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>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"نمایه شخصی شما به <xliff:g id="VPN_APP">%1$s</xliff:g> متصل است"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"این دستگاه به <xliff:g id="VPN_APP">%1$s</xliff:g> متصل است"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"مدیریت دستگاه"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"کنترل نمایه"</string>
<string name="monitoring_title" msgid="4063890083735924568">"کنترل شبکه"</string>
@@ -545,8 +545,8 @@
<string name="disable_vpn" msgid="482685974985502922">"‏غیرفعال کردن VPN"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"‏قطع اتصال VPN"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"مشاهده خط‌مشی‌ها"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"دستگاه شما تحت مدیریت <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> است.\n\nسرپرست سیستم شما می‌تواند تنظیمات، دسترسی شرکتی، برنامه‌ها، داده‌های مرتبط با دستگاه شما و اطلاعات مکان دستگاهتان را پایش و مدیریت کند.\n\nبرای اطلاعات بیشتر، با سرپرست سیستم تماس بگیرید."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"دستگاه شما تحت مدیریت سازمان شما است.\n\nسرپرست سیستم شما می‌تواند تنظیمات، دسترسی شرکتی، برنامه‌ها، داده‌های مرتبط با دستگاه شما و اطلاعات مکان دستگاهتان را پایش و مدیریت کند.\n\nبرای اطلاعات بیشتر، با سرپرست سیستم تماس بگیرید."</string>
+ <string name="monitoring_description_named_management" msgid="505833016545056036">"این دستگاه به <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> تعلق دارد.\n\nسرپرست فناوری اطلاعات می‌تواند تنظیمات، دسترسی شرکتی، برنامه‌ها، داده‌های مرتبط با دستگاه، و اطلاعات مکان دستگاهتان را کنترل و مدیریت کند.\n\nبرای اطلاعات بیشتر، با سرپرست فناوری و اطلاعات تماس بگیرید."</string>
+ <string name="monitoring_description_management" msgid="4308879039175729014">"این دستگاه به سازمان شما تعلق دارد.\n\nسرپرست فناوری اطلاعات می‌تواند تنظیمات، دسترسی شرکتی، برنامه‌ها، و داده‌های مرتبط با دستگاه و اطلاعات مکان دستگاهتان را کنترل و مدیریت کند.\n\nبرای اطلاعات بیشتر، با سرپرست فناوری و اطلاعات تماس بگیرید."</string>
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"سازمان شما مرجع گواهینامه‌ای در این دستگاه نصب کرده است. ممکن است ترافیک امن شبکه شما پایش یا تغییر داده شود."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"سازمان شما مرجع گواهینامه‌ای در نمایه کاری شما نصب کرده است. ممکن است ترافیک امن شبکه شما پایش یا تغییر داده شود."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"مرجع گواهینامه‌ای در این دستگاه نصب شده است. ممکن است ترافیک امن شبکه شما پایش یا تغییر داده شود."</string>
@@ -920,6 +920,7 @@
<string name="pip_pause" msgid="1139598607050555845">"توقف موقت"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"رد شدن به بعدی"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"رد شدن به قبلی"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"تغییر اندازه"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"تلفن به علت گرم شدن خاموش شد"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"اکنون تلفنتان عملکرد معمولش را دارد"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"تلفنتان خیلی گرم شده بود، بنابراین خاموش شد تا خنک شود. اکنون تلفنتان عملکرد معمولش را دارد.\n\nتلفنتان خیلی گرم می‌شود، اگر:\n • از برنامه‌های نیازمند پردازش زیاد (مانند بازی، برنامه‌های ویدیویی یا پیمایشی) استفاده کنید\n • فایل‌های بزرگ بارگیری یا بارگذاری کنید\n • در دماهای بالا از تلفنتان استفاده کنید"</string>
@@ -1045,7 +1046,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"برای تغییر دادن ترتیب کنترل‌ها، آن‌ها را نگه دارید و بکشید"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"همه کنترل‌ها برداشته شده‌اند"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"تغییرات ذخیره نشد"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"فهرست همه کنترل‌ها را نمی‌توان بارگیری کرد."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"کنترل‌ها بار نشدند. برنامه <xliff:g id="APP">%s</xliff:g> را بررسی کنید تا مطمئن شوید تنظیمات برنامه تغییر نکرده باشد."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"کنترل‌های سازگار دردسترس نیستند"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"موارد دیگر"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"افزودن به کنترل‌های دستگاه"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"افزودن"</string>
@@ -1061,8 +1063,11 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"تأیید تغییر مربوط به <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"برای دیدن موارد بیشتر، تند بکشید"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"درحال بار کردن توصیه‌ها"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"بستن این جلسه رسانه"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"رسانه"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"جلسه فعلی پنهان شود."</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"پنهان کردن"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"ازسرگیری"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"تنظیمات"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"غیرفعال، برنامه را بررسی کنید"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"خطا، درحال تلاش مجدد…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"پیدا نشد"</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 05a88f4cc6ee..efdd81bfbbac 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -454,8 +454,8 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Avaa napauttamalla uudelleen"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Avaa pyyhkäisemällä ylös"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Yritä uudelleen pyyhkäisemällä ylös"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"Organisaatiosi hallinnoi laitetta"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"Tätä laitetta hallinnoi <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>."</string>
+ <string name="do_disclosure_generic" msgid="4896482821974707167">"Organisaatiosi omistaa tämän laitteen"</string>
+ <string name="do_disclosure_with_name" msgid="2091641464065004091">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> omistaa tämän laitteen"</string>
<string name="phone_hint" msgid="6682125338461375925">"Avaa puhelu pyyhkäisemällä."</string>
<string name="voice_hint" msgid="7476017460191291417">"Avaa ääniapuri pyyhkäisemällä kuvakkeesta."</string>
<string name="camera_hint" msgid="4519495795000658637">"Avaa kamera pyyhkäisemällä."</string>
@@ -521,21 +521,21 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"Profiilia saatetaan valvoa"</string>
<string name="vpn_footer" msgid="3457155078010607471">"Verkkoa saatetaan valvoa"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"Verkkoa saatetaan valvoa"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"Organisaatiosi hallinnoi tätä laitetta ja voi valvoa verkkoliikennettä."</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> hallinnoi tätä laitetta ja voi valvoa verkkoliikennettä."</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"Organisaatiosi hallinnoi tätä laitetta, joka on yhteydessä sovellukseen <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> hallinnoi tätä laitetta, joka on yhteydessä sovellukseen <xliff:g id="VPN_APP">%2$s</xliff:g>."</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"Organisaatiosi hallinnoi laitetta."</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> hallinnoi tätä laitetta."</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"Organisaatiosi hallinnoi tätä laitetta, joka on yhteydessä VPN:iin."</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> hallinnoi tätä laitetta, joka on yhteydessä VPN:iin."</string>
+ <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Organisaatiosi omistaa laitteen ja voi valvoa verkkoliikennettä"</string>
+ <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> omistaa laitteen ja voi valvoa verkkoliikennettä"</string>
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Organisaatiosi omistaa laitteen, joka on yhdistetty tähän: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> omistaa laitteen, joka on yhdistetty tähän: <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Organisaatiosi omistaa tämän laitteen"</string>
+ <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> omistaa tämän laitteen"</string>
+ <string name="quick_settings_disclosure_management_vpns" msgid="371835422690053154">"Organisaatiosi omistaa tämän laitteen, joka on yhdistetty VPN:iin"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="4046375645500668555">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> omistaa tämän laitteen, joka on yhdistetty VPN:iin"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Organisaatiosi voi valvoa työprofiilisi verkkoliikennettä."</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> voi valvoa työprofiilisi verkkoliikennettä."</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Verkkoa saatetaan valvoa"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"Laite on yhteydessä VPN:iin."</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"Työprofiili on yhteydessä sovellukseen <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"Henkilökohtainen profiili on yhteydessä sovellukseen <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"Laite on yhteydessä sovellukseen <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
+ <string name="quick_settings_disclosure_vpns" msgid="7213546797022280246">"Tämä laite on yhdistetty VPN:iin"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Työprofiilisi on yhdistetty tähän: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Henkilökohtainen profiilisi on yhdistetty tähän: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Laite on yhdistetty tähän: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Laitehallinta"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Profiilin valvonta"</string>
<string name="monitoring_title" msgid="4063890083735924568">"Verkon valvonta"</string>
@@ -545,8 +545,8 @@
<string name="disable_vpn" msgid="482685974985502922">"Poista VPN käytöstä"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"Katkaise VPN-yhteys"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"Näytä säännöt"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> hallinnoi tätä laitetta.\n\nJärjestelmänvalvoja voi valvoa ja hallinnoida asetuksiasi, yrityskäyttöä, sovelluksia, laitteeseesi yhdistettyjä tietoja sekä laitteesi sijaintitietoja.\n\nSaat lisätietoja järjestelmänvalvojalta."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"Organisaatiosi hallinnoi tätä laitetta.\n\nJärjestelmänvalvoja voi valvoa ja hallinnoida asetuksiasi, yrityskäyttöä, sovelluksia, laitteeseesi yhdistettyjä tietoja sekä laitteesi sijaintitietoja.\n\nSaat lisätietoja järjestelmänvalvojalta."</string>
+ <string name="monitoring_description_named_management" msgid="505833016545056036">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> omistaa tämän laitteen.\n\nJärjestelmänvalvoja voi valvoa ja muuttaa asetuksia, yrityskäyttöä, sovelluksia sekä laitteeseen yhdistettyjä tietoja ja sen sijaintitietoja.\n\nSaat lisätietoja järjestelmänvalvojalta."</string>
+ <string name="monitoring_description_management" msgid="4308879039175729014">"Organisaatiosi omistaa tämän laitteen.\n\nJärjestelmänvalvoja voi valvoa ja muuttaa asetuksia, yrityskäyttöä, sovelluksia sekä laitteeseen yhdistettyjä tietoja ja sen sijaintitietoja.\n\nSaat lisätietoja järjestelmänvalvojalta."</string>
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Organisaatiosi asensi laitteeseen varmenteen myöntäjän. Suojattua verkkoliikennettäsi voidaan valvoa tai muuttaa."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Organisaatiosi lisäsi työprofiiliin varmenteen myöntäjän. Suojattua verkkoliikennettäsi voidaan valvoa tai muuttaa."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Laitteeseen on asennettu varmenteen myöntäjä. Suojattua verkkoliikennettäsi voidaan valvoa tai muuttaa."</string>
@@ -920,6 +920,7 @@
<string name="pip_pause" msgid="1139598607050555845">"Keskeytä"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"Siirry seuraavaan"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"Siirry edelliseen"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"Muuta kokoa"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"Puhelin sammui kuumuuden takia"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"Puhelimesi toimii nyt normaalisti."</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Puhelimesi oli liian kuuma, joten se sammui. Puhelimesi toimii nyt normaalisti.\n\nPuhelimesi voi kuumentua liikaa, jos\n • käytät paljon resursseja vaativia sovelluksia (esim. pelejä, videoita tai navigointisovelluksia)\n • lataat tai lähetät suuria tiedostoja\n • käytät puhelintasi korkeissa lämpötiloissa."</string>
@@ -1007,7 +1008,7 @@
<string name="bubbles_user_education_title" msgid="5547017089271445797">"Chattaile kuplien avulla"</string>
<string name="bubbles_user_education_description" msgid="1160281719576715211">"Uudet keskustelut näkyvät kelluvina kuvakkeina tai kuplina. Avaa kupla napauttamalla. Siirrä sitä vetämällä."</string>
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Muuta kuplien asetuksia milloin tahansa"</string>
- <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Valitse Hallinnoi, jos haluat poistaa kuplat käytöstä tästä sovelluksesta"</string>
+ <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Valitse Ylläpidä, jos haluat poistaa kuplat käytöstä tästä sovelluksesta"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Selvä"</string>
<string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>: asetukset"</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Järjestelmän navigointitapa vaihdettu. Voit muuttaa sitä asetuksista."</string>
@@ -1025,7 +1026,7 @@
<string name="magnification_window_title" msgid="4863914360847258333">"Suurennusikkuna"</string>
<string name="magnification_controls_title" msgid="8421106606708891519">"Suurennusikkunan ohjaimet"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"Laitteiden hallinta"</string>
- <string name="quick_controls_subtitle" msgid="1667408093326318053">"Lisää säätimiä yhdistettyihin laitteisiisi"</string>
+ <string name="quick_controls_subtitle" msgid="1667408093326318053">"Lisää ohjaimia yhdistettyjä laitteita varten"</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"Laitteiden hallinnan käyttöönotto"</string>
<string name="quick_controls_setup_subtitle" msgid="1681506617879773824">"Voit käyttää säätimiä painamalla virtapainiketta"</string>
<string name="controls_providers_title" msgid="6879775889857085056">"Valitse sovellus lisätäksesi säätimiä"</string>
@@ -1045,7 +1046,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Järjestele säätimiä koskettamalla pitkään ja vetämällä"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"Kaikki säätimet poistettu"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Muutoksia ei tallennettu"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"Kaikkien säätimien luetteloa ei voitu ladata."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"Säätimiä ei voitu ladata. Avaa <xliff:g id="APP">%s</xliff:g> ja tarkista, että sovelluksen asetukset eivät ole muuttuneet."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"Yhteensopivat säätimet eivät käytettävissä"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Muu"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"Lisää laitteiden hallintaan"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"Lisää"</string>
@@ -1061,8 +1063,11 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"Vahvista muutos: <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Pyyhkäise nähdäksesi lisää"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Ladataan suosituksia"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"Sulje tämä median käyttökerta"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"Media"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"Piilota nykyinen käyttökerta."</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Piilota"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Jatka"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"Asetukset"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Epäaktiivinen, tarkista sovellus"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Virhe, yritetään uudelleen…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Ei löydy"</string>
diff --git a/packages/SystemUI/res/values-fi/strings_tv.xml b/packages/SystemUI/res/values-fi/strings_tv.xml
index 3a80561e702f..e22a1660db0c 100644
--- a/packages/SystemUI/res/values-fi/strings_tv.xml
+++ b/packages/SystemUI/res/values-fi/strings_tv.xml
@@ -24,5 +24,5 @@
<string name="pip_close" msgid="5775212044472849930">"Sulje PIP"</string>
<string name="pip_fullscreen" msgid="3877997489869475181">"Koko näyttö"</string>
<string name="mic_active" msgid="5766614241012047024">"Mikrofoni aktiivinen"</string>
- <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s käytti mikrofoniasi"</string>
+ <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s sai pääsyn mikrofoniisi"</string>
</resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index e7ef0824539f..5588cf59fde9 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -454,8 +454,10 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Touchez à nouveau pour ouvrir"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Balayez l\'écran vers le haut pour ouvrir"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Balayez l\'écran vers le haut pour réessayer"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"Cet appareil est géré par votre organisation"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"Cet appareil est géré par <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for do_disclosure_generic (4896482821974707167) -->
+ <skip />
+ <!-- no translation found for do_disclosure_with_name (2091641464065004091) -->
+ <skip />
<string name="phone_hint" msgid="6682125338461375925">"Balayez à partir de l\'icône pour accéder au téléphone"</string>
<string name="voice_hint" msgid="7476017460191291417">"Balayez à partir de l\'icône pour accéder à l\'assist. vocale"</string>
<string name="camera_hint" msgid="4519495795000658637">"Balayez à partir de l\'icône pour accéder à l\'appareil photo"</string>
@@ -521,21 +523,33 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"le profil peut être contrôlé"</string>
<string name="vpn_footer" msgid="3457155078010607471">"Le réseau peut être surveillé"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"Le réseau peut être surveillé"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"Votre organisation gère cet appareil et peut contrôler le trafic réseau."</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> gère cet appareil et peut contrôler le trafic réseau"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"Cet appareil est géré par votre organisation et connecté à <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"Cet appareil est géré par <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> et connecté à <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"Cet appareil est géré par votre organisation"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"Cet appareil est géré par <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>."</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"Cet appareil est géré par votre organisation et connecté à des RPV"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"Cet appareil est géré par <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> et connecté à des RPV"</string>
+ <!-- no translation found for quick_settings_disclosure_management_monitoring (8231336875820702180) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_monitoring (2831423806103479812) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_named_vpn (6096715329056415588) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (5302786161534380104) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management (5515296598440684962) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management (3476472755775165827) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_vpns (371835422690053154) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_vpns (4046375645500668555) -->
+ <skip />
<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>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Le réseau peut être surveillé"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"L\'appareil est connecté à des RPV"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"Profil professionnel connecté à <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"Profil personnel connecté à <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"Appareil connecté à <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <!-- no translation found for quick_settings_disclosure_vpns (7213546797022280246) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (8117568745060010789) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (5481763430080807797) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_vpn (2350838218824492465) -->
+ <skip />
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Gestion d\'appareils"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Contrôle de profil"</string>
<string name="monitoring_title" msgid="4063890083735924568">"Surveillance réseau"</string>
@@ -545,8 +559,10 @@
<string name="disable_vpn" msgid="482685974985502922">"Désactiver le RPV"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"Déconnecter le RPV"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"Afficher les politiques"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"Votre appareil est géré par <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nVotre administrateur peut contrôler et gérer les paramètres, l\'accès aux données d\'entreprise, les applications, les données associées à l\'appareil et les renseignements sur sa localisation.\n\nPour plus d\'information, communiquez avec votre administrateur."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"Votre appareil est géré par votre organisation.\n\nVotre administrateur peut contrôler et gérer les paramètres, l\'accès aux données d\'entreprise, les applications, les données associées à l\'appareil et les renseignements sur sa localisation.\n\nPour plus d\'information, communiquez avec votre administrateur."</string>
+ <!-- no translation found for monitoring_description_named_management (505833016545056036) -->
+ <skip />
+ <!-- no translation found for monitoring_description_management (4308879039175729014) -->
+ <skip />
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Votre entreprise a installé une autorité de certification sur cet appareil. Votre trafic sur le réseau sécurisé peut être contrôlé ou modifié."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Votre entreprise a installé une autorité de certification dans votre profil professionnel. Votre trafic sur le réseau sécurisé peut être contrôlé ou modifié."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Une autorité de certification est installée sur cet appareil. Votre trafic sur le réseau sécurisé peut être contrôlé ou modifié."</string>
@@ -920,6 +936,7 @@
<string name="pip_pause" msgid="1139598607050555845">"Interrompre"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"Passer au suivant"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"Revenir au précédent"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"Redimensionner"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"Tél. éteint car il surchauffait"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"Votre téléphone fonctionne maintenant normalement"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Votre téléphone s\'est éteint, car il surchauffait. Il s\'est refroidi et fonctionne normalement.\n\nIl peut surchauffer si vous :\n • Util. des applis utilisant beaucoup de ressources (jeux, vidéo, navigation, etc.)\n • Téléchargez ou téléversez de gros fichiers\n • Utilisez téléphone dans des températures élevées"</string>
@@ -1006,7 +1023,7 @@
<string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Ne pas afficher les conversations dans des bulles"</string>
<string name="bubbles_user_education_title" msgid="5547017089271445797">"Clavarder en utilisant des bulles"</string>
<string name="bubbles_user_education_description" msgid="1160281719576715211">"Les nouvelles conversations s\'affichent sous forme d\'icônes flottantes (de bulles). Touchez une bulle pour l\'ouvrir. Faites-la glisser pour la déplacer."</string>
- <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Gérer les paramètres des bulles"</string>
+ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Paramètres des bulles"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"Toucher Gérer pour désactiver les bulles de cette application"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string>
<string name="bubbles_app_settings" msgid="5779443644062348657">"Paramètres <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
@@ -1014,9 +1031,9 @@
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Accédez au menu Paramètres pour mettre à jour la navigation système"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Veille"</string>
<string name="priority_onboarding_title" msgid="2893070698479227616">"La conversation a été définie comme prioritaire"</string>
- <string name="priority_onboarding_behavior" msgid="5342816047020432929">"Les conversations prioritaires :"</string>
- <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Afficher dans le haut de la section des conversations"</string>
- <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Afficher la photo de profil sur l\'écran verrouillé"</string>
+ <string name="priority_onboarding_behavior" msgid="5342816047020432929">"Pour les conversations prioritaires :"</string>
+ <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"afficher dans le haut de la section des conversations"</string>
+ <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"afficher la photo de profil sur l\'écran verrouillé"</string>
<string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Sous forme de bulle flottante, par-dessus les applis"</string>
<string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Interrompre le mode Ne pas déranger"</string>
<string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"OK"</string>
@@ -1045,7 +1062,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Maintenez le doigt sur l\'écran, puis glissez-le pour réorganiser les commandes"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"Toutes les commandes ont été supprimées"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Modifications non enregistrées"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"Impossible de charger la liste des commandes."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"Impossible de charger les commandes. Vérifiez l\'application <xliff:g id="APP">%s</xliff:g> pour vous assurer que les paramètres de l\'application n\'ont pas changé."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"Les commandes compatibles ne sont pas accessibles"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Autre"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"Ajouter aux commandes des appareils"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"Ajouter"</string>
@@ -1061,8 +1079,15 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"Confirmer la modification pour <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Balayez l\'écran pour en afficher davantage"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Chargement des recommandations…"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"Fermer cette session multimédia"</string>
+ <!-- no translation found for controls_media_title (1746947284862928133) -->
+ <skip />
+ <!-- no translation found for controls_media_close_session (3957093425905475065) -->
+ <skip />
+ <!-- no translation found for controls_media_dismiss_button (4485675693008031646) -->
+ <skip />
<string name="controls_media_resume" msgid="1933520684481586053">"Reprendre"</string>
+ <!-- no translation found for controls_media_settings_button (5815790345117172504) -->
+ <skip />
<string name="controls_error_timeout" msgid="794197289772728958">"Délai expiré, vérifiez l\'appli"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Erreur, nouvelle tentative…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Introuvable"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index c7d88720a9df..6a7e94c65973 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -454,8 +454,10 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Appuyer à nouveau pour ouvrir"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Balayer vers le haut pour ouvrir"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Balayez l\'écran vers le haut pour réessayer"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"Cet appareil est géré par votre entreprise"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"Cet appareil est géré par <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for do_disclosure_generic (4896482821974707167) -->
+ <skip />
+ <!-- no translation found for do_disclosure_with_name (2091641464065004091) -->
+ <skip />
<string name="phone_hint" msgid="6682125338461375925">"Balayer pour téléphoner"</string>
<string name="voice_hint" msgid="7476017460191291417">"Balayer l\'écran depuis l\'icône pour l\'assistance vocale"</string>
<string name="camera_hint" msgid="4519495795000658637">"Balayer pour prendre une photo"</string>
@@ -521,21 +523,33 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"Le profil peut être contrôlé."</string>
<string name="vpn_footer" msgid="3457155078010607471">"Il est possible que le réseau soit surveillé."</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"Il est possible que le réseau soit surveillé."</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"Votre organisation gère cet appareil et peut contrôler votre trafic réseau"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> gère cet appareil et peut contrôler votre trafic réseau"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"Appareil géré par votre organisation et connecté à <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"Appareil géré par <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> et connecté à <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"Appareil géré par votre organisation"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"Appareil géré par <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"Appareil géré par votre organisation et connecté à des VPN"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"Appareil géré par <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> et connecté à des VPN"</string>
+ <!-- no translation found for quick_settings_disclosure_management_monitoring (8231336875820702180) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_monitoring (2831423806103479812) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_named_vpn (6096715329056415588) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (5302786161534380104) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management (5515296598440684962) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management (3476472755775165827) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_vpns (371835422690053154) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_vpns (4046375645500668555) -->
+ <skip />
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Votre entreprise peut contrôler votre 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>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Il est possible que le réseau soit surveillé"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"Appareil connecté à des VPN"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"Profil professionnel connecté à <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"Profil personnel connecté à <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"Appareil connecté à <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <!-- no translation found for quick_settings_disclosure_vpns (7213546797022280246) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (8117568745060010789) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (5481763430080807797) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_vpn (2350838218824492465) -->
+ <skip />
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Gestion des appareils"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Contrôle du profil"</string>
<string name="monitoring_title" msgid="4063890083735924568">"Contrôle du réseau"</string>
@@ -545,8 +559,10 @@
<string name="disable_vpn" msgid="482685974985502922">"Désactiver le VPN"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"Déconnecter le VPN"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"Afficher les règles"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"Votre appareil est géré par <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nVotre administrateur peut contrôler et gérer les paramètres, l\'accès aux données d\'entreprise, les applications, les données associées à l\'appareil et les informations sur sa localisation.\n\nPour plus d\'informations, contactez votre administrateur."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"Votre appareil est géré par votre organisation.\n\nVotre administrateur peut contrôler et gérer les paramètres, l\'accès aux données d\'entreprise, les applications, les données associées à l\'appareil et les informations sur sa localisation.\n\nPour plus d\'informations, contactez votre administrateur."</string>
+ <!-- no translation found for monitoring_description_named_management (505833016545056036) -->
+ <skip />
+ <!-- no translation found for monitoring_description_management (4308879039175729014) -->
+ <skip />
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Votre entreprise a installé une autorité de certification sur cet appareil. Votre trafic sur le réseau sécurisé peut être contrôlé ou modifié."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Votre entreprise a installé une autorité de certification dans votre profil professionnel. Votre trafic sur le réseau sécurisé peut être contrôlé ou modifié."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Une autorité de certification est installée sur cet appareil. Votre trafic sur le réseau sécurisé peut être contrôlé ou modifié."</string>
@@ -920,6 +936,7 @@
<string name="pip_pause" msgid="1139598607050555845">"Suspendre"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"Passer au contenu suivant"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"Passer au contenu précédent"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"Redimensionner"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"Tél. éteint car il surchauffait"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"À présent, votre téléphone fonctionne normalement"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Votre téléphone s\'est éteint, car il surchauffait. Il s\'est refroidi et fonctionne normalement.\n\nIl peut surchauffer si vous :\n • exécutez applis utilisant beaucoup de ressources (jeux, vidéo, navigation, etc.) ;\n • téléchargez ou importez gros fichiers ;\n • utilisez téléphone à des températures élevées."</string>
@@ -1003,7 +1020,7 @@
<string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Déplacer en bas à gauche"</string>
<string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Déplacer en bas à droite"</string>
<string name="bubble_dismiss_text" msgid="1314082410868930066">"Fermer la bulle"</string>
- <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Ne pas afficher la conversations dans des bulles"</string>
+ <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Ne pas afficher la conversation dans une bulle"</string>
<string name="bubbles_user_education_title" msgid="5547017089271445797">"Chatter en utilisant des bulles"</string>
<string name="bubbles_user_education_description" msgid="1160281719576715211">"Les nouvelles conversations s\'affichent sous forme d\'icônes flottantes ou bulles. Appuyez sur la bulle pour l\'ouvrir. Faites-la glisser pour la déplacer."</string>
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Contrôler les paramètres des bulles"</string>
@@ -1015,9 +1032,9 @@
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Mode Veille imminent"</string>
<string name="priority_onboarding_title" msgid="2893070698479227616">"Conversation définie comme prioritaire"</string>
<string name="priority_onboarding_behavior" msgid="5342816047020432929">"Les conversations prioritaires :"</string>
- <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"En haut de la liste des conversations"</string>
- <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Photo de profil sur l\'écran de verrouillage"</string>
- <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Sous forme d\'info-bulle au-dessus des applications"</string>
+ <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Apparaîtront en haut de la liste des conversations"</string>
+ <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Afficheront la photo de profil sur l\'écran de verrouillage"</string>
+ <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Apparaîtront sous forme de bulle au-dessus des applications"</string>
<string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Interrompre Ne pas déranger"</string>
<string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"OK"</string>
<string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Paramètres"</string>
@@ -1045,7 +1062,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Appuyez et faites glisser pour réorganiser les commandes"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"Toutes les commandes ont été supprimées"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Les modifications n\'ont pas été enregistrées"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"Impossible de charger toutes les commandes."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"Impossible de charger les commandes. Vérifiez l\'application <xliff:g id="APP">%s</xliff:g> pour vous assurer que les paramètres de l\'application n\'ont pas changé."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"Commandes compatibles indisponibles"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Autre"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"Ajouter aux commandes de contrôle des appareils"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"Ajouter"</string>
@@ -1061,8 +1079,11 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"Confirmer la modification pour <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Balayer l\'écran pour voir plus d\'annonces"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Chargement des recommandations"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"Fermer cette session multimédia"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"Multimédia"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"Masquer la session en cours."</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Masquer"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Reprendre"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"Paramètres"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Délai expiré, vérifier l\'appli"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Erreur. Nouvelle tentative…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Introuvable"</string>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index 93524f8492d8..cfe6d28c46cb 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -454,8 +454,8 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Toca de novo para abrir"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Pasa o dedo cara arriba para abrir"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Pasa o dedo cara arriba para tentalo de novo"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"Este dispositivo está xestionado pola túa organización"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"Este dispositivo está xestionado por <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
+ <string name="do_disclosure_generic" msgid="4896482821974707167">"Este dispositivo pertence á túa organización"</string>
+ <string name="do_disclosure_with_name" msgid="2091641464065004091">"Este dispositivo pertence a <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="6682125338461375925">"Pasa o dedo desde a icona para acceder ao teléfono"</string>
<string name="voice_hint" msgid="7476017460191291417">"Pasa o dedo desde a icona para acceder ao asistente de voz"</string>
<string name="camera_hint" msgid="4519495795000658637">"Pasa o dedo desde a icona para acceder á cámara"</string>
@@ -521,21 +521,21 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"O perfil pódese supervisar"</string>
<string name="vpn_footer" msgid="3457155078010607471">"É posible que se supervise a rede"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"É posible que se supervise a rede"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"A túa organización xestiona este dispositivo e pode controlar o tráfico de rede"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> xestiona este dispositivo e pode controlar o tráfico de rede"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"A túa organización xestiona o dispositivo, que está conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> xestiona o dispositivo, que está conectado a <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"A túa organización xestiona o dispositivo"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> xestiona o dispositivo."</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"A túa organización xestiona o dispositivo, que está conectado a dúas VPN"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> xestiona o dispositivo, que está conectado a dúas VPN"</string>
+ <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"A túa organización é propietaria deste dispositivo e pode controlar o tráfico de rede"</string>
+ <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> é a organización propietaria deste dispositivo e pode controlar o tráfico de rede"</string>
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Este dispositivo pertence á túa organización e está conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Este dispositivo pertence a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> e está conectado a <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Este dispositivo pertence á túa organización"</string>
+ <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Este dispositivo pertence a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management_vpns" msgid="371835422690053154">"Este dispositivo pertence á túa organización e está conectado a varias VPN"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="4046375645500668555">"Este dispositivo pertence a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> e está conectado a varias VPN"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"A túa organización pode controlar o tráfico de rede do teu perfil de traballo"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> pode controlar o tráfico de rede do teu perfil de traballo"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"É posible que se controle a rede"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"O dispositivo está conectado a dúas VPN"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"O perfil de traballo está conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"O perfil persoal está conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"O dispositivo está conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_vpns" msgid="7213546797022280246">"Este dispositivo está conectado a varias VPN"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"O teu perfil de traballo está conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"O teu perfil persoal está conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Este dispositivo está conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Xestión de dispositivos"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Supervisión do perfil"</string>
<string name="monitoring_title" msgid="4063890083735924568">"Supervisión de rede"</string>
@@ -545,8 +545,8 @@
<string name="disable_vpn" msgid="482685974985502922">"Desactivar VPN"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"Desconectar VPN"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"Ver políticas"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"O teu dispositivo está xestionado por <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nO administrador pode controlar e xestionar a configuración, o acceso corporativo, as aplicacións, os datos asociados co dispositivo e a información de localización deste último.\n\nPara obter máis información, ponte en contacto co teu administrador."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"A túa organización xestiona o teu dispositivo.\n\nO administrador pode controlar e xestionar a configuración, o acceso corporativo, as aplicacións, os datos asociados co dispositivo e a información de localización deste último.\n\nPara obter máis información, ponte en contacto co teu administrador."</string>
+ <string name="monitoring_description_named_management" msgid="505833016545056036">"Este dispositivo pertence a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nO teu administrador de TI pode supervisar e xestionar a configuración, o acceso corporativo, as aplicacións, os datos asociados co teu dispositivo e a información de localización deste último.\n\nPara obter máis información, contacta co teu administrador de TI."</string>
+ <string name="monitoring_description_management" msgid="4308879039175729014">"Este dispositivo pertence á túa organización.\n\nO teu administrador de TI pode supervisar e xestionar a configuración, o acceso corporativo, as aplicacións, os datos asociados co teu dispositivo e a información de localización deste último.\n\nPara obter máis información, contacta co teu administrador de TI."</string>
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"A túa organización instalou unha autoridade de certificación neste dispositivo. É posible que se controle ou se modifique o teu tráfico de rede segura."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"A túa organización instalou unha autoridade de certificación no teu perfil de traballo. É posible que se controle ou se modifique o teu tráfico de rede segura."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Este dispositivo ten unha autoridade de certificación instalada. É posible que se controle ou se modifique o teu tráfico de rede segura."</string>
@@ -920,6 +920,7 @@
<string name="pip_pause" msgid="1139598607050555845">"Pausar"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"Ir ao seguinte"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"Ir ao anterior"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"Cambiar tamaño"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"O teléfono apagouse pola calor"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"O teu teléfono funciona agora con normalidade"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"O teléfono estaba moi quente, apagouse para que arrefríe e agora funciona con normalidade.\n\nÉ posible que estea moi quente se:\n • Usas aplicacións que requiren moitos recursos (como aplicacións de navegación, vídeos e xogos)\n • Descargas/cargas ficheiros grandes\n • Usas o teléfono a alta temperatura"</string>
@@ -1006,7 +1007,7 @@
<string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Non mostrar a conversa como burbulla"</string>
<string name="bubbles_user_education_title" msgid="5547017089271445797">"Chatear usando burbullas"</string>
<string name="bubbles_user_education_description" msgid="1160281719576715211">"As conversas novas aparecen como iconas flotantes ou burbullas. Toca para abrir a burbulla e arrastra para movela."</string>
- <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Controlar as burbullas en calquera momento"</string>
+ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Controla as burbullas"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"Para desactivar as burbullas nesta aplicación, toca Xestionar"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Entendido"</string>
<string name="bubbles_app_settings" msgid="5779443644062348657">"Configuración de <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
@@ -1015,8 +1016,8 @@
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Modo de espera"</string>
<string name="priority_onboarding_title" msgid="2893070698479227616">"A conversa definiuse como prioritaria"</string>
<string name="priority_onboarding_behavior" msgid="5342816047020432929">"As conversas prioritarias farán o seguinte:"</string>
- <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Mostrar na parte superior da sección de conversas"</string>
- <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Mostrar imaxe do perfil na pantalla de bloqueo"</string>
+ <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Mostraranse na parte superior da sección de conversas"</string>
+ <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Mostrarán a imaxe do perfil na pantalla de bloqueo"</string>
<string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Mostrar como burbulla flotante sobre outras apps"</string>
<string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Interromper modo Non molestar"</string>
<string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Entendido"</string>
@@ -1045,7 +1046,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Para reorganizar os controis, mantenos premidos e arrástraos"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"Quitáronse todos os controis"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Non se gardaron os cambios"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"Non se puido cargar a lista de todos os controis."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"Non se puideron cargar os controis. Comproba a aplicación <xliff:g id="APP">%s</xliff:g> para asegurarte de que non se modificase a súa configuración."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"Non hai controis compatibles que estean dispoñibles"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Outra"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"Engadir ao control de dispositivos"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"Engadir"</string>
@@ -1061,8 +1063,11 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"Confirma o cambio para <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Pasar o dedo para ver máis"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Cargando recomendacións"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"Pechar esta sesión multimedia"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"Contido multimedia"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"Oculta a sesión actual."</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ocultar"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Retomar"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"Configuración"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inactivo. Comproba a app"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Erro. Tentando de novo…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Non se atopou"</string>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index 473f6de00c89..23f784557c76 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -454,8 +454,10 @@
<string name="notification_tap_again" msgid="4477318164947497249">"ખોલવા માટે ફરીથી ટૅપ કરો"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"ખોલવા માટે ઉપરની તરફ સ્વાઇપ કરો"</string>
<string name="keyguard_retry" msgid="886802522584053523">"ફરી પ્રયાસ કરવા માટે ઉપરની તરફ સ્વાઇપ કરો"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"આ ઉપકરણ તમારી સંસ્થા દ્વારા સંચાલિત છે"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"આ ઉપકરણ <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> દ્વારા સંચાલિત થાય છે"</string>
+ <!-- no translation found for do_disclosure_generic (4896482821974707167) -->
+ <skip />
+ <!-- no translation found for do_disclosure_with_name (2091641464065004091) -->
+ <skip />
<string name="phone_hint" msgid="6682125338461375925">"ફોન માટે આયકનમાંથી સ્વાઇપ કરો"</string>
<string name="voice_hint" msgid="7476017460191291417">"વૉઇસ સહાય માટે આયકનમાંથી સ્વાઇપ કરો"</string>
<string name="camera_hint" msgid="4519495795000658637">"કૅમેરા માટે આયકનમાંથી સ્વાઇપ કરો"</string>
@@ -521,21 +523,33 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"પ્રોફાઇલ મૉનિટર કરી શકાય છે"</string>
<string name="vpn_footer" msgid="3457155078010607471">"નેટવર્ક મૉનિટર કરી શકાય છે"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"નેટવર્ક મૉનિટર કરવામાં આવી શકે છે"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"તમારી સંસ્થા આ ઉપકરણનું સંચાલન કરે છે અને નેટવર્ક ટ્રાફિકનું નિયમન કરી શકે છે"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> આ ઉપકરણનું સંચાલન કરે છે અને નેટવર્ક ટ્રાફિકનું નિયમન કરી શકે છે"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"આ ઉપકરણ તમારી સંસ્થા દ્વારા સંચાલિત થાય છે અને <xliff:g id="VPN_APP">%1$s</xliff:g> સાથે કનેક્ટ કરેલ છે"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"આ ઉપકરણ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> દ્વારા સંચાલિત થાય છે અને <xliff:g id="VPN_APP">%2$s</xliff:g> સાથે કનેક્ટ કરેલ છે"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"આ ઉપકરણ તમારી સંસ્થા દ્વારા સંચાલિત થાય છે"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"આ ઉપકરણનું સંચાલન <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> દ્વારા થાય છે"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"આ ઉપકરણ તમારી સંસ્થા દ્વારા સંચાલિત થાય છે અને બે VPN સાથે કનેક્ટ કરેલ છે"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"આ ઉપકરણ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> દ્વારા સંચાલિત થાય છે અને બે VPN સાથે કનેક્ટ કરેલ છે"</string>
+ <!-- no translation found for quick_settings_disclosure_management_monitoring (8231336875820702180) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_monitoring (2831423806103479812) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_named_vpn (6096715329056415588) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (5302786161534380104) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management (5515296598440684962) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management (3476472755775165827) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_vpns (371835422690053154) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_vpns (4046375645500668555) -->
+ <skip />
<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_monitoring" msgid="8548019955631378680">"નેટવર્કનું નિયમન કરવામાં આવી શકે છે"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"આ ઉપકરણ બે VPN સાથે કનેક્ટ કરેલ છે"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"કાર્યાલયની પ્રોફાઇલ <xliff:g id="VPN_APP">%1$s</xliff:g> સાથે કનેક્ટ કરેલ છે"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"વ્યક્તિગત પ્રોફાઇલ <xliff:g id="VPN_APP">%1$s</xliff:g> સાથે કનેક્ટ કરેલ છે"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"આ ઉપકરણ <xliff:g id="VPN_APP">%1$s</xliff:g> સાથે કનેક્ટ કરેલ છે"</string>
+ <!-- no translation found for quick_settings_disclosure_vpns (7213546797022280246) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (8117568745060010789) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (5481763430080807797) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_vpn (2350838218824492465) -->
+ <skip />
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"ઉપકરણનું સંચાલન"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"પ્રોફાઇલ નિરીક્ષણ"</string>
<string name="monitoring_title" msgid="4063890083735924568">"નેટવર્ક મૉનિટરિંગ"</string>
@@ -545,8 +559,10 @@
<string name="disable_vpn" msgid="482685974985502922">"VPN અક્ષમ કરો"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"VPN ડિસ્કનેક્ટ કરો"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"નીતિઓ જુઓ"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"તમારું ઉપકરણ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> દ્વારા સંચાલિત કરવામાં આવે છે.\n\nતમારા વ્યવસ્થાપક સેટિંગ્સ, કૉર્પોરેટ ઍક્સેસ, ઍપ્લિકેશનો, તમારા ઉપકરણ સાથે સંકળાયેલ ડેટા અને તમારા ઉપકરણની સ્થાન માહિતીનું નિરીક્ષણ અને સંચાલન કરી શકે છે.\n\nવધુ માહિતી માટે, તમારા વ્યવસ્થાપકનો સંપર્ક કરો."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"તમારું ઉપકરણ તમારી સંસ્થા દ્વારા સંચાલિત કરવામાં આવે છે.\n\nતમારા વ્યવસ્થાપક સેટિંગ્સ, કૉર્પોરેટ ઍક્સેસ, ઍપ્લિકેશનો, તમારા ઉપકરણ સાથે સંકળાયેલ ડેટા અને તમારા ઉપકરણની સ્થાન માહિતીનું નિરીક્ષણ અને સંચાલન કરી શકે છે.\n\nવધુ માહિતી માટે, તમારા વ્યવસ્થાપકનો સંપર્ક કરો."</string>
+ <!-- no translation found for monitoring_description_named_management (505833016545056036) -->
+ <skip />
+ <!-- no translation found for monitoring_description_management (4308879039175729014) -->
+ <skip />
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"તમારી સંસ્થાએ આ ઉપકરણ પર પ્રમાણપત્ર સત્તાધિકારી ઇન્સ્ટૉલ કર્યું છે. તમારા સુરક્ષિત નેટવર્ક ટ્રાફિકનું નિયમન થઈ શકે છે અથવા તેમાં ફેરફાર કરવામાં આવી શકે છે."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"તમારી સંસ્થાએ તમારી કાર્ય પ્રોફાઇલમાં પ્રમાણપત્ર સત્તાધિકારી ઇન્સ્ટૉલ કર્યું છે. તમારા સુરક્ષિત નેટવર્ક ટ્રાફિકનું નિયમન થઈ શકે છે અથવા તેમાં ફેરફાર કરવામાં આવી શકે છે."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"આ ઉપકરણ પર પ્રમાણપત્ર સત્તાધિકારી ઇન્સ્ટૉલ કરેલ છે. તમારા સુરક્ષિત નેટવર્ક ટ્રાફિકનું નિયમન થઈ શકે છે અથવા તેમાં ફેરફાર કરવામાં આવી શકે છે."</string>
@@ -920,6 +936,7 @@
<string name="pip_pause" msgid="1139598607050555845">"થોભાવો"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"આગલા પર જાઓ"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"પહેલાંના પર જાઓ"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"કદ બદલો"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"ફોન વધુ પડતી ગરમીને લીધે બંધ થઇ ગયો છે"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"તમારો ફોન હવે સામાન્યપણે કાર્ય કરી રહ્યો છે"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"તમારો ફોન અત્યંત ગરમ હતો, તેથી તે ઠંડો થવા આપમેળે બંધ થઇ ગયો છે. તમારો ફોન હવે સામાન્યપણે કાર્ય કરી રહ્યો છે.\n\nતમારો ફોન અત્યંત ગરમ થઇ શકે છે, જો તમે:\n • એવી ઍપ્લિકેશન વાપરતા હો જે સંસાધન સઘન રીતે વાપરતી હોય (જેમ કે ગેમિંગ, વીડિઓ, અથવા નેવિગેટ કરતી ઍપ્લિકેશનો)\n • મોટી ફાઇલો અપલોડ અથવા ડાઉનલોડ કરતા હો\n • તમારા ફોનનો ઉપયોગ ઉચ્ચ તાપમાનમાં કરતા હો"</string>
@@ -1045,7 +1062,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"નિયંત્રણોને ફરીથી ગોઠવવા માટે તેમને હોલ્ડ કરીને ખેંચો"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"બધા નિયંત્રણો કાઢી નાખ્યા"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"ફેરફારો સાચવ્યા નથી"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"બધા નિયંત્રણોની સૂચિ લોડ કરી શકાઈ નથી."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"નિયંત્રણો લોડ કરી શકાયા નથી. ઍપના સેટિંગ બદલાયા નથી તેની ખાતરી કરવા માટે <xliff:g id="APP">%s</xliff:g> ઍપ ચેક કરો."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"સુસંગત નિયંત્રણો ઉપલબ્ધ નથી"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"અન્ય"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"ડિવાઇસનાં નિયંત્રણોમાં ઉમેરો"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"ઉમેરો"</string>
@@ -1061,8 +1079,11 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"<xliff:g id="DEVICE">%s</xliff:g> માટે ફેરફાર કન્ફર્મ કરો"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"વધુ જોવા માટે સ્વાઇપ કરો"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"સુઝાવ લોડ કરી રહ્યાં છીએ"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"આ મીડિયા સત્રને બંધ કરો"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"મીડિયા"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"હાલનું સત્ર છુપાવો."</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"છુપાવો"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"ફરી શરૂ કરો"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"સેટિંગ"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"નિષ્ક્રિય, ઍપને ચેક કરો"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"ભૂલ, ફરી પ્રયાસ કરી રહ્યા છીએ…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"મળ્યું નથી"</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 00389073626b..28b7f167c0fc 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -456,8 +456,10 @@
<string name="notification_tap_again" msgid="4477318164947497249">"खोलने के लिए फिर से टैप करें"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"खोलने के लिए ऊपर स्वाइप करें"</string>
<string name="keyguard_retry" msgid="886802522584053523">"फिर से कोशिश करने के लिए ऊपर की ओर स्वाइप करें"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"इस डिवाइस का प्रबंधन आपका संगठन करता है"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"इस डिवाइस के प्रबंधक <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> हैं"</string>
+ <!-- no translation found for do_disclosure_generic (4896482821974707167) -->
+ <skip />
+ <!-- no translation found for do_disclosure_with_name (2091641464065004091) -->
+ <skip />
<string name="phone_hint" msgid="6682125338461375925">"फ़ोन के लिए आइकॉन से स्वाइप करें"</string>
<string name="voice_hint" msgid="7476017460191291417">"\'आवाज़ से डिवाइस का इस्तेमाल\' आइकॉन से स्वाइप करें"</string>
<string name="camera_hint" msgid="4519495795000658637">"कैमरे के लिए आइकॉन से स्वाइप करें"</string>
@@ -523,21 +525,33 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"प्रोफ़ाइल को मॉनीटर किया जा सकता है"</string>
<string name="vpn_footer" msgid="3457155078010607471">"नेटवर्क को मॉनीटर किया जा सकता है"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"नेटवर्क को मॉनिटर किया जा सकता है"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"आपका संगठन इस डिवाइस का प्रबंधन करता है और वह नेटवर्क ट्रैफ़िक की निगरानी कर सकता है"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> इस डिवाइस का प्रबंधन करता है और वह नेटवर्क ट्रैफ़िक की निगरानी कर सकता है"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"डिवाइस का प्रबंधन आपका संगठन करता है और वह <xliff:g id="VPN_APP">%1$s</xliff:g> से कनेक्ट है"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"डिवाइस का प्रबंधन <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> करता है और वह <xliff:g id="VPN_APP">%2$s</xliff:g> से कनेक्ट है"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"डिवाइस का प्रबंधन आपका संगठन करता है"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"डिवाइस का प्रबंधन <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> करता है"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"डिवाइस का प्रबंधन आपका संगठन करता है और वह VPNs से कनेक्ट है"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"डिवाइस का प्रबंधन <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> करता है और वह VPNs से कनेक्ट है"</string>
+ <!-- no translation found for quick_settings_disclosure_management_monitoring (8231336875820702180) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_monitoring (2831423806103479812) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_named_vpn (6096715329056415588) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (5302786161534380104) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management (5515296598440684962) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management (3476472755775165827) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_vpns (371835422690053154) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_vpns (4046375645500668555) -->
+ <skip />
<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_monitoring" msgid="8548019955631378680">"नेटवर्क की निगरानी की जा सकती है"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"डिवाइस VPNs से कनेक्ट है"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"वर्क प्रोफ़ाइल <xliff:g id="VPN_APP">%1$s</xliff:g> से कनेक्ट है"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"व्यक्तिगत प्रोफ़ाइल <xliff:g id="VPN_APP">%1$s</xliff:g> से कनेक्ट है"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"डिवाइस <xliff:g id="VPN_APP">%1$s</xliff:g> से कनेक्ट है"</string>
+ <!-- no translation found for quick_settings_disclosure_vpns (7213546797022280246) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (8117568745060010789) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (5481763430080807797) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_vpn (2350838218824492465) -->
+ <skip />
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"डिवाइस प्रबंधन"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"प्रोफ़ाइल को मॉनीटर करना"</string>
<string name="monitoring_title" msgid="4063890083735924568">"नेटवर्क को मॉनीटर करना"</string>
@@ -547,8 +561,10 @@
<string name="disable_vpn" msgid="482685974985502922">"VPN अक्षम करें"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"VPN डिस्‍कनेक्‍ट करें"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"नीतियां देखें"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> आपके डिवाइस का प्रबंधन करता है.\n\nआपका एडमिन सेटिंग, कॉर्पोरेट पहुंच, ऐप्लिकेशन, आपके डिवाइस से जुड़े डेटा और आपके डिवाइस की जगह की जानकारी की निगरानी कर सकता है और उन्हें प्रबंधित कर सकता है.\n\n और जानकारी के लिए, अपने एडमिन से संपर्क करें."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"आपका संगठन आपके डिवाइस का प्रबंधन करता है.\n\nआपका एडमिन सेटिंग, कॉर्पोरेट पहुंच, ऐप्लिकेशन, आपके डिवाइस से जुड़े डेटा और आपके डिवाइस की जगह की जानकारी की निगरानी कर सकता है और उन्हें प्रबंधित कर सकता है.\n\nऔर जानकारी के लिए, अपने एडमिन से संपर्क करें."</string>
+ <!-- no translation found for monitoring_description_named_management (505833016545056036) -->
+ <skip />
+ <!-- no translation found for monitoring_description_management (4308879039175729014) -->
+ <skip />
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"आपके संगठन ने इस डिवाइस पर एक प्रमाणपत्र अनुमति इंस्टॉल की है. आपके सुरक्षित नेटवर्क पर ट्रेफ़िक की निगरानी या उसमें बदलाव किया जा सकता है."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"आपके संगठन ने आपकी वर्क प्रोफ़ाइल में एक प्रमाणपत्र अनुमति इंस्टॉल की है. आपके सुरक्षित नेटवर्क ट्रैफ़िक की निगरानी या उसमें बदलाव किया जा सकता है."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"इस डिवाइस पर एक प्रमाणपत्र अनुमति इंस्टॉल की है. आपके सुरक्षित नेटवर्क ट्रैफ़िक की निगरानी या उसमें बदलाव किया जा सकता है."</string>
@@ -922,6 +938,7 @@
<string name="pip_pause" msgid="1139598607050555845">"रोकें"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"अगले पर जाएं"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"पिछले पर जाएं"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"आकार बदलें"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"गर्म होने की वजह से फ़ोन बंद हुआ"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"आपका फ़ोन अब सामान्य रूप से चल रहा है"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"फ़ोन बहुत गर्म हो गया था, इसलिए ठंडा होने के लिए बंद हो गया. फ़ोन अब अच्छे से चल रहा है.\n\nफ़ोन तब बहुत गर्म हो सकता है जब आप:\n • ज़्यादा रिसॉर्स का इस्तेमाल करने वाले ऐप्लिकेशन चलाते हैं (जैसे गेमिंग, वीडियो या नेविगेशन ऐप्लिकेशन)\n • बड़ी फ़ाइलें डाउनलोड या अपलोड करते हैं\n • ज़्यादा तापमान में फ़ोन का इस्तेमाल करते हैं"</string>
@@ -1015,7 +1032,7 @@
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"सिस्टम नेविगेशन अपडेट हो गया. बदलाव करने के लिए \'सेटिंग\' पर जाएं."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"सिस्टम नेविगेशन अपडेट करने के लिए \'सेटिंग\' में जाएं"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"स्टैंडबाई"</string>
- <string name="priority_onboarding_title" msgid="2893070698479227616">"बातचीत को अहम बातचीत के तौर पर सेट किया गया है"</string>
+ <string name="priority_onboarding_title" msgid="2893070698479227616">"बातचीत को \'अहम बातचीत\' के तौर पर सेट किया गया है"</string>
<string name="priority_onboarding_behavior" msgid="5342816047020432929">"अहम बातचीत यहां दिखेगी:"</string>
<string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"बातचीत सेक्शन में सबसे ऊपर दिखाएं"</string>
<string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"लॉक स्क्रीन पर प्रोफ़ाइल फ़ोटो दिखाएं"</string>
@@ -1047,7 +1064,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"कंट्रोल का क्रम फिर से बदलने के लिए उन्हें दबाकर रखें और खींचें"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"सभी कंट्रोल हटा दिए गए"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"बदलाव सेव नहीं किए गए"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"सभी कंट्रोल की सूची लोड नहीं हो सकी."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"कंट्रोल लोड नहीं किए जा सके. <xliff:g id="APP">%s</xliff:g> ऐप्लिकेशन देखें, ताकि यह पक्का किया जा सके कि ऐप्लिकेशन की सेटिंग में कोई बदलाव नहीं हुआ है."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"इस सेटिंग के साथ काम करने वाले कंट्रोल उपलब्ध नहीं हैं"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"अन्य"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"डिवाइस कंट्रोल में जोड़ें"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"जोड़ें"</string>
@@ -1063,11 +1081,14 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"<xliff:g id="DEVICE">%s</xliff:g> में बदलाव के लिए पुष्टि करें"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"ज़्यादा देखने के लिए स्वाइप करें"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"सुझाव लोड हो रहे हैं"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"इस मीडिया सेशन को बंद करें"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"मीडिया"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"इस मीडिया सेशन को छिपाएं."</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"छिपाएं"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"फिर से शुरू करें"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"सेटिंग"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"काम नहीं कर रहा, ऐप जांचें"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"कोई गड़बड़ी हुई, फिर से कोशिश की जा रही है…"</string>
- <string name="controls_error_removed" msgid="6675638069846014366">"कंट्रोल मौजूद नहीं है"</string>
+ <string name="controls_error_removed" msgid="6675638069846014366">"कंट्रोल नहीं है"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"कंट्रोल मौजूद नहीं है"</string>
<string name="controls_error_removed_message" msgid="2885911717034750542">"<xliff:g id="DEVICE">%1$s</xliff:g> को ऐक्सेस नहीं किया जा सका. <xliff:g id="APPLICATION">%2$s</xliff:g> ऐप्लिकेशन देखें, ताकि यह पक्का किया जा सके कि कंट्रोल अब भी मौजूद है और सेटिंग में कोई बदलाव नहीं हुआ है."</string>
<string name="controls_open_app" msgid="483650971094300141">"ऐप्लिकेशन खोलें"</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index b0e6b51e8f6a..48be21a292ff 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -456,8 +456,8 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Dodirnite opet za otvaranje"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Prijeđite prstom prema gore da biste otvorili"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Prijeđite prstom prema gore za ponovni pokušaj"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"Ovim uređajem upravlja vaša organizacija"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"Ovim uređajem upravlja <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
+ <string name="do_disclosure_generic" msgid="4896482821974707167">"Ovaj uređaj pripada vašoj organizaciji"</string>
+ <string name="do_disclosure_with_name" msgid="2091641464065004091">"Ovaj uređaj pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="6682125338461375925">"Prijeđite prstom od ikone za telefon"</string>
<string name="voice_hint" msgid="7476017460191291417">"Prijeđite prstom od ikone za glasovnu pomoć"</string>
<string name="camera_hint" msgid="4519495795000658637">"Prijeđite prstom od ikone za fotoaparat"</string>
@@ -524,21 +524,21 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"Profil se možda nadzire"</string>
<string name="vpn_footer" msgid="3457155078010607471">"Mreža se možda nadzire"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"Mreža se možda nadzire"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"Vaša organizacija upravlja ovim uređajem i može nadzirati mrežni promet."</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"Organizacija <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> upravlja ovim uređajem i može nadzirati mrežni promet"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"Uređajem upravlja vaša organizacija i povezan je s aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"Uređajem upravlja organizacija <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> i povezan je s aplikacijom <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"Uređajem upravlja vaša organizacija"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"Uređajem upravlja organizacija <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"Uređajem upravlja vaša organizacija i povezan je s VPN-ovima"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"Uređajem upravlja organizacija <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> i povezan je s VPN-ovima"</string>
+ <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Vaša je organizacija vlasnik ovog uređaja i može nadzirati mrežni promet"</string>
+ <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Organizacija <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> vlasnik je ovog uređaja i može nadzirati mrežni promet"</string>
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Ovaj uređaj pripada vašoj organizaciji i povezan je s mrežom <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Ovaj uređaj pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> i povezan je s mrežom <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Ovaj uređaj pripada vašoj organizaciji"</string>
+ <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Ovaj uređaj pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management_vpns" msgid="371835422690053154">"Ovaj uređaj pripada vašoj organizaciji i povezan je s VPN-ovima"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="4046375645500668555">"Ovaj uređaj pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> i povezan je s VPN-ovima"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Vaša organizacija može nadzirati mrežni promet na vašem radnom profilu"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"Organizacija <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> može nadzirati mrežni promet na vašem radnom profilu"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Mreža se možda nadzire"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"Uređaj je povezan s VPN-ovima"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"Radni profil povezan je s aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"Osobni profil povezan je s aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"Uređaj je povezan s aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_vpns" msgid="7213546797022280246">"Ovaj je uređaj povezan s VPN-ovima"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Vaš poslovni profil povezan je s mrežom <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Vaš osobni profil povezan je s mrežom <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Ovaj uređaj povezan je s mrežom <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Upravljanje uređajem"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Nadzor profila"</string>
<string name="monitoring_title" msgid="4063890083735924568">"Nadzor mreže"</string>
@@ -548,8 +548,8 @@
<string name="disable_vpn" msgid="482685974985502922">"Onemogući VPN"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"Prekini vezu s VPN-om"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"Prikaži pravila"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"Uređajem upravlja organizacija <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nAdministrator može nadzirati postavke, korporacijski pristup, aplikacije, podatke o uređaju i lokaciji uređaja te upravljati njima.\n\nZa više informacija obratite se administratoru."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"Uređajem upravlja vaša organizacija.\n\nAdministrator može nadzirati postavke, korporacijski pristup, aplikacije, podatke o uređaju i lokaciji uređaja te upravljati njima.\n\nZa više informacija obratite se administratoru."</string>
+ <string name="monitoring_description_named_management" msgid="505833016545056036">"Ovaj uređaj pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nVaš IT administrator može nadzirati postavke, korporacijski pristup, aplikacije, podatke o uređaju i lokaciji uređaja te upravljati njima.\n\nZa više informacija obratite se IT administratoru."</string>
+ <string name="monitoring_description_management" msgid="4308879039175729014">"Ovaj uređaj pripada vašoj organizaciji.\n\nVaš IT administrator može nadzirati postavke, korporacijski pristup, aplikacije, podatke o uređaju i lokaciji uređaja te upravljati njima.\n\nZa više informacija obratite se IT administratoru."</string>
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Vaša je organizacija instalirala izdavač certifikata na ovom uređaju. Vaš sigurni mrežni promet možda se nadzire ili modificira."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Vaša je organizacija instalirala izdavač certifikata na vašem radnom profilu. Vaš sigurni mrežni promet možda se nadzire ili modificira."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Na ovom je uređaju instaliran izdavač certifikata. Vaš sigurni mrežni promet možda se nadzire ili modificira."</string>
@@ -925,6 +925,7 @@
<string name="pip_pause" msgid="1139598607050555845">"Pauziraj"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"Preskoči na sljedeće"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"Preskoči na prethodno"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"Promjena veličine"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"Telefon se isključio zbog vrućine"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"Telefon sada radi normalno"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Telefon se pregrijao, stoga se isključio kako bi se ohladio Telefon sada radi normalno.\n\nTelefon se može pregrijati ako:\n • upotrebljavate zahtjevne aplikacije (kao što su igre, aplikacije za videozapise ili navigaciju)\n • preuzimate ili prenosite velike datoteke\n • upotrebljavate telefon na visokim temperaturama."</string>
@@ -1019,9 +1020,9 @@
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Navigaciju sustavom možete ažurirati u Postavkama"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Stanje mirovanja"</string>
<string name="priority_onboarding_title" msgid="2893070698479227616">"Razgovor postavljen na prioritetan"</string>
- <string name="priority_onboarding_behavior" msgid="5342816047020432929">"Prioritetni razgovori će sljedeće:"</string>
- <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Prikazuje se pri vrhu odjeljka razgovora"</string>
- <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Prikazuje profilnu sliku na zaključanom zaslonu"</string>
+ <string name="priority_onboarding_behavior" msgid="5342816047020432929">"Prioritetni razgovori:"</string>
+ <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Prikazuju se pri vrhu odjeljka razgovora"</string>
+ <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Prikazuju profilnu sliku na zaključanom zaslonu"</string>
<string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Prikazuje se kao lebdeći oblačić iznad aplikacija"</string>
<string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Prekida Ne uznemiravaj"</string>
<string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Shvaćam"</string>
@@ -1051,7 +1052,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Zadržite i povucite da biste promijenili raspored kontrola"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"Sve su kontrole uklonjene"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Promjene nisu spremljene"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"Popis svih kontrola nije se učitao."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"Kontrole se ne mogu učitati. U aplikaciji <xliff:g id="APP">%s</xliff:g> provjerite da se postavke aplikacije nisu promijenile."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"Kompatibilne kontrole nisu dostupne"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Drugo"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"Dodavanje kontrolama uređaja"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"Dodaj"</string>
@@ -1067,8 +1069,11 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"Potvrdite promjenu za uređaj <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Prijeđite prstom da vidite više"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Učitavanje preporuka"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"Zatvorite ovu medijsku sesiju"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"Mediji"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"Sakrij trenutačnu sesiju."</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Sakrij"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Nastavi"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"Postavke"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Neaktivno, provjerite aplik."</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Pogreška, pokušavamo ponovo…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Nije pronađeno"</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 64e7011a63a9..b311c27a2daf 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -454,8 +454,10 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Koppintson ismét a megnyitáshoz"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Csúsztasson felfelé a megnyitáshoz"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Az újrapróbálkozáshoz csúsztassa felfelé az ujját"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"Az eszközt az Ön szervezete kezeli"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"Az eszközt a(z) <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> felügyeli."</string>
+ <!-- no translation found for do_disclosure_generic (4896482821974707167) -->
+ <skip />
+ <!-- no translation found for do_disclosure_with_name (2091641464065004091) -->
+ <skip />
<string name="phone_hint" msgid="6682125338461375925">"A telefonhoz csúsztasson az ikonról"</string>
<string name="voice_hint" msgid="7476017460191291417">"A hangsegéd eléréséhez csúsztassa ujját az ikonról"</string>
<string name="camera_hint" msgid="4519495795000658637">"A fényképezőhöz csúsztasson az ikonról"</string>
@@ -521,21 +523,33 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"Profilját felügyelhetik"</string>
<string name="vpn_footer" msgid="3457155078010607471">"Lehet, hogy a hálózatot figyelik"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"Lehet, hogy a hálózat felügyelt"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"Az eszközt az Ön szervezete kezeli, és lehetséges, hogy a hálózati forgalmat is figyelik"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"Az eszközt a(z) <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> kezeli, és lehetséges, hogy a hálózati forgalmat is figyelik"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"Az eszközt az Ön szervezete kezeli; és csatlakozik a következőhöz: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"Az eszközt a(z) <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> kezeli, és csatlakozik a következőhöz: <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"Az eszközt az Ön szervezete kezeli"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"Az eszközt a következő szervezet kezeli: <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"Az eszközt az Ön szervezete kezeli; és VPN-ekhez csatlakozik"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"Az eszközt a(z) <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> kezeli, és VPN-ekhez csatlakozik"</string>
+ <!-- no translation found for quick_settings_disclosure_management_monitoring (8231336875820702180) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_monitoring (2831423806103479812) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_named_vpn (6096715329056415588) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (5302786161534380104) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management (5515296598440684962) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management (3476472755775165827) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_vpns (371835422690053154) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_vpns (4046375645500668555) -->
+ <skip />
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Szervezete figyelheti a munkaprofil hálózati forgalmát"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"A(z) <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> figyelheti a munkaprofil hálózati forgalmát"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Elképzelhető, hogy a hálózatot figyelik"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"Az eszköz VPN-ekhez csatlakozik"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"A munkaprofil csatlakozik a következőhöz: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"A személyes profil a következőhöz csatlakozik: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"Az eszköz a következőhöz csatlakozik: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <!-- no translation found for quick_settings_disclosure_vpns (7213546797022280246) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (8117568745060010789) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (5481763430080807797) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_vpn (2350838218824492465) -->
+ <skip />
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Eszközkezelés"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Profilfelügyelet"</string>
<string name="monitoring_title" msgid="4063890083735924568">"Hálózatfigyelés"</string>
@@ -545,8 +559,10 @@
<string name="disable_vpn" msgid="482685974985502922">"VPN letiltása"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"VPN-kapcsolat bontása"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"Házirendek megtekintése"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"Az eszközt a(z) <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> felügyeli.\n\nA rendszergazda figyelheti és kezelheti a beállításokat, a vállalati hozzáférést, az alkalmazásokat, az eszközhöz tartozó adatokat, valamint az eszköz helyadatait.\n\nHa további információra van szüksége, vegye fel a kapcsolatot a rendszergazdával."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"Az eszközt az Ön szervezete felügyeli.\n\nA rendszergazda figyelheti és kezelheti a beállításokat, a vállalati hozzáférést, az alkalmazásokat, az eszközhöz tartozó adatokat, valamint az eszköz helyadatait.\n\nHa további információra van szüksége, vegye fel a kapcsolatot a rendszergazdával."</string>
+ <!-- no translation found for monitoring_description_named_management (505833016545056036) -->
+ <skip />
+ <!-- no translation found for monitoring_description_management (4308879039175729014) -->
+ <skip />
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Szervezete tanúsítványkibocsátót telepített az eszközre. Ezáltal figyelhetik és befolyásolhatják az Ön biztonságos hálózati forgalmát."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Szervezete tanúsítványkibocsátót telepített a munkaprofilba. Ezáltal figyelhetik és befolyásolhatják az Ön biztonságos hálózati forgalmát."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Az eszközre tanúsítványkibocsátó van telepítve. Ezáltal figyelhetik és befolyásolhatják az Ön biztonságos hálózati forgalmát."</string>
@@ -920,6 +936,7 @@
<string name="pip_pause" msgid="1139598607050555845">"Szüneteltetés"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"Ugrás a következőre"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"Ugrás az előzőre"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"Átméretezés"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"A meleg miatt kikapcsolt"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"A telefon most már megfelelően működik"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Telefonja túlmelegedett, így kikapcsolt, hogy lehűlhessen. Most már megfelelően működik.\n\nA telefon akkor melegedhet túl, ha Ön:\n • Energiaigényes alkalmazásokat használ (például játékokat, videókat vagy navigációs alkalmazásokat)\n • Nagy fájlokat tölt le vagy fel\n • Melegben használja a telefonját"</string>
@@ -1045,7 +1062,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Tartsa lenyomva, és húzza a vezérlők átrendezéséhez"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"Minden vezérlő eltávolítva"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"A rendszer nem mentette a módosításokat"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"Nem sikerült betölteni az összes vezérlő listáját."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"Nem sikerült betölteni a vezérlőket. Ellenőrizze a(z) <xliff:g id="APP">%s</xliff:g> alkalmazást, és győződjön meg arról, hogy nem változtak az alkalmazásbeállítások."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"Nem állnak rendelkezésre kompatibilis vezérlők"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Más"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"Hozzáadás az eszközvezérlőkhöz"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"Hozzáadás"</string>
@@ -1061,8 +1079,11 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"A(z) <xliff:g id="DEVICE">%s</xliff:g> módosításának megerősítése"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Továbbiak megtekintéséhez csúsztasson"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Javaslatok betöltése…"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"Médiamunkamenet bezárása"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"Média"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"Jelenlegi munkamenet elrejtése."</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Elrejtés"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Folytatás"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"Beállítások"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inaktív, ellenőrizze az appot"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Hiba, újrapróbálkozás…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Nem található"</string>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index a337cc22390b..cbc3268115fc 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -454,8 +454,10 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Կրկին հպեք՝ բացելու համար"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Բացելու համար սահեցրեք վերև"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Սահեցրեք վերև՝ նորից փորձելու համար"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"Այս սարքը կառավարում է ձեր կազմակերպությունը"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"Այս սարքը կառավարվում է <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>-ի կողմից"</string>
+ <!-- no translation found for do_disclosure_generic (4896482821974707167) -->
+ <skip />
+ <!-- no translation found for do_disclosure_with_name (2091641464065004091) -->
+ <skip />
<string name="phone_hint" msgid="6682125338461375925">"Սահահարվածեք հեռախոսի պատկերակից"</string>
<string name="voice_hint" msgid="7476017460191291417">"Սահահարվածեք ձայնային հուշման պատկերակից"</string>
<string name="camera_hint" msgid="4519495795000658637">"Սահահարվածեք խցիկի պատկերակից"</string>
@@ -521,21 +523,33 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"Պրոֆիլը կարող է վերահսկվել"</string>
<string name="vpn_footer" msgid="3457155078010607471">"Ցանցը կարող է վերահսկվել"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"Ցանցը կարող է վերահսկվել"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"Ձեր կազմակերպությունը կառավարում է այս սարքը և կարող է վերահսկել ցանցային թրաֆիկը"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> կազմակերպությունը կառավարում է այս սարքը և կարող է վերահսկել ցանցային թրաֆիկը"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"Սարքը կառավարվում է ձեր կազմակերպության կողմից և կապակցված է <xliff:g id="VPN_APP">%1$s</xliff:g> հավելվածին"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"Սարքը կառավարվում է <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> կազմակերպության կողմից և կապակցված է <xliff:g id="VPN_APP">%2$s</xliff:g> հավելվածին"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"Սարքը կառավարում է ձեր կազմակերպությունը"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"Այս սարքի կառավարիչը <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> կազմակերպությունն է"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"Սարքը կառավարվում է ձեր կազմակերպության կողմից և կապակցված է VPN-ներին"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"Սարքը կառավարվում է <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> կազմակերպության կողմից և կապակցված է VPN-ներին"</string>
+ <!-- no translation found for quick_settings_disclosure_management_monitoring (8231336875820702180) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_monitoring (2831423806103479812) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_named_vpn (6096715329056415588) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (5302786161534380104) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management (5515296598440684962) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management (3476472755775165827) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_vpns (371835422690053154) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_vpns (4046375645500668555) -->
+ <skip />
<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_monitoring" msgid="8548019955631378680">"Ցանցը կարող է վերահսկվել"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"Սարքը կապակցված է VPN-ներին"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"Աշխատանքային պրոֆիլը կապակցված է <xliff:g id="VPN_APP">%1$s</xliff:g> հավելվածին"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"Անձնական պրոֆիլը կապակցված է <xliff:g id="VPN_APP">%1$s</xliff:g> հավելվածին"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"Սարքը կապակցված է <xliff:g id="VPN_APP">%1$s</xliff:g> հավելվածին"</string>
+ <!-- no translation found for quick_settings_disclosure_vpns (7213546797022280246) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (8117568745060010789) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (5481763430080807797) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_vpn (2350838218824492465) -->
+ <skip />
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Սարքերի կառավարում"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Պրոֆիլի վերահսկում"</string>
<string name="monitoring_title" msgid="4063890083735924568">"Ցանցի մշտադիտարկում"</string>
@@ -545,8 +559,10 @@
<string name="disable_vpn" msgid="482685974985502922">"Անջատել VPN-ը"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"Անջատել VPN-ը"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"Դիտել քաղաքականությունները"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"Ձեր սարքը կառավարվում է <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\n-ի կողմից: Ձեր ադմինիստրատորը կարող է վերահսկել և կառավարել կարգավորումները, կորպորատիվ օգտագործման թույլտվությունները, հավելվածները, սարքին կապված տվյալները և սարքի տեղադրման մասին տեղեկատվությունը:\n\nՄանրամասների համար դիմեք ձեր ադմինիստրատորին:"</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"Ձեր շարժական սարքը կառավարվում է ձեր կազմակերպության կողմից։\n\nՁեր ադմինիստրատորը կարող է վերահսկել և կառավարել կարգավորումները, կորպորատիվ օգտագործման թույլտվությունները, հավելվածները, սարքին կապված տվյալները և սարքի տեղադրման մասին տեղեկատվությունը:\n\nՄանրամասների համար դիմեք ձեր ադմինիստրատորին:"</string>
+ <!-- no translation found for monitoring_description_named_management (505833016545056036) -->
+ <skip />
+ <!-- no translation found for monitoring_description_management (4308879039175729014) -->
+ <skip />
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Ձեր կազմակերպությունը այս սարքում տեղադրել է վկայագրման կենտրոն։ Ձեր ցանցի ապահով թրաֆիկը կարող է վերահսկվել կամ փոփոխվել։"</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Ձեր կազմակերպությունը ձեր աշխատանքային պրոֆիլում տեղադրել է վկայագրման կենտրոն։ Ձեր ցանցի ապահով թրաֆիկը կարող է վերահսկվել կամ փոփոխվել։"</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Այս սարքում տեղադրված է վկայագրման կենտրոն։ Ձեր ցանցի ապահով թրաֆիկը կարող է վերահսկվել կամ փոփոխվել։"</string>
@@ -920,6 +936,7 @@
<string name="pip_pause" msgid="1139598607050555845">"Դադարեցնել"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"Անցնել հաջորդին"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"Վերադառնալ նախորդին"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"Փոխել չափը"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"Հեռախոսն անջատվել է տաքանալու պատճառով"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"Հեռախոսն այժմ նորմալ աշխատում է"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Ձեր հեռախոսը չափազանց տաք էր, այդ պատճառով այն անջատվել է՝ հովանալու համար: Հեռախոսն այժմ նորմալ աշխատում է:\n\nՀեռախոսը կարող է տաքանալ, եթե՝\n • Օգտագործում եք ռեսուրսատար հավելվածներ (օրինակ՝ խաղեր, տեսանյութեր կամ նավարկման հավելվածներ)\n • Ներբեռնում կամ վերբեռնում եք ծանր ֆայլեր\n • Օգտագործում եք ձեր հեռախոսը բարձր ջերմային պայմաններում"</string>
@@ -1045,7 +1062,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Պահեք և քաշեք՝ կառավարման տարրերը վերադասավորելու համար"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"Կառավարման բոլոր տարրերը հեռացվեցին"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Փոփոխությունները չեն պահվել"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"Չհաջողվեց բեռնել բոլոր կառավարների ցանկը։"</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"Չհաջողվեց բեռնել կառավարման տարրերը։ Ստուգեք <xliff:g id="APP">%s</xliff:g> հավելվածը՝ համոզվելու, որ հավելվածի կարգավորումները չեն փոխվել։"</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"Համատեղելի կառավարման տարրերը հասանելի չեն"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Այլ"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"Ավելացրեք սարքերի կառավարման տարրերում"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"Ավելացնել"</string>
@@ -1061,8 +1079,15 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"Հաստատեք փոփոխությունը <xliff:g id="DEVICE">%s</xliff:g> սարքի համար"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Սահեցրեք մատը՝ ավելին իմանալու համար"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Բեռնման խորհուրդներ"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"Փակել աշխատաշրջանը"</string>
+ <!-- no translation found for controls_media_title (1746947284862928133) -->
+ <skip />
+ <!-- no translation found for controls_media_close_session (3957093425905475065) -->
+ <skip />
+ <!-- no translation found for controls_media_dismiss_button (4485675693008031646) -->
+ <skip />
<string name="controls_media_resume" msgid="1933520684481586053">"Շարունակել"</string>
+ <!-- no translation found for controls_media_settings_button (5815790345117172504) -->
+ <skip />
<string name="controls_error_timeout" msgid="794197289772728958">"Ակտիվ չէ, ստուգեք հավելվածը"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Սխալ. նորից ենք փորձում…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Չի գտնվել"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 72fac719f1f1..4fa434488c55 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -454,8 +454,10 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Ketuk lagi untuk membuka"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Geser ke atas untuk membuka"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Geser ke atas untuk mencoba lagi"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"Perangkat ini dikelola oleh organisasi"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"Perangkat ini dikelola oleh <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for do_disclosure_generic (4896482821974707167) -->
+ <skip />
+ <!-- no translation found for do_disclosure_with_name (2091641464065004091) -->
+ <skip />
<string name="phone_hint" msgid="6682125338461375925">"Geser dari ikon untuk telepon"</string>
<string name="voice_hint" msgid="7476017460191291417">"Geser dari ikon untuk bantuan suara"</string>
<string name="camera_hint" msgid="4519495795000658637">"Geser dari ikon untuk kamera"</string>
@@ -521,21 +523,33 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"Profil dapat dipantau"</string>
<string name="vpn_footer" msgid="3457155078010607471">"Jaringan mungkin dipantau"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"Jaringan mungkin dipantau"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"Organisasi mengelola perangkat ini dan mungkin memantau traffic jaringan"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> mengelola perangkat ini dan mungkin memantau traffic jaringan Anda"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"Perangkat dikelola oleh organisasi dan tersambung ke <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"Perangkat dikelola oleh <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> dan tersambung ke <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"Perangkat dikelola oleh organisasi"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"Perangkat dikelola oleh <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"Perangkat dikelola oleh organisasi dan tersambung ke VPN"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"Perangkat dikelola oleh <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> dan tersambung ke VPN"</string>
+ <!-- no translation found for quick_settings_disclosure_management_monitoring (8231336875820702180) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_monitoring (2831423806103479812) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_named_vpn (6096715329056415588) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (5302786161534380104) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management (5515296598440684962) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management (3476472755775165827) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_vpns (371835422690053154) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_vpns (4046375645500668555) -->
+ <skip />
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Organisasi dapat memantau traffic jaringan di profil kerja"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> mungkin memantau traffic jaringan di profil kerja Anda"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Jaringan mungkin dipantau"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"Perangkat tersambung ke VPN"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"Profil kerja tersambung ke <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"Profil pribadi tersambung ke <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"Perangkat tersambung ke <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <!-- no translation found for quick_settings_disclosure_vpns (7213546797022280246) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (8117568745060010789) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (5481763430080807797) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_vpn (2350838218824492465) -->
+ <skip />
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Pengelolaan perangkat"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Pemantauan profil"</string>
<string name="monitoring_title" msgid="4063890083735924568">"Pemantauan jaringan"</string>
@@ -545,8 +559,10 @@
<string name="disable_vpn" msgid="482685974985502922">"Nonaktifkan VPN"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"Putuskan sambungan VPN"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"Lihat Kebijakan"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"Perangkat dikelola oleh <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nAdmin dapat memantau dan mengelola setelan, akses perusahaan, aplikasi, data yang terkait dengan perangkat, dan informasi lokasi perangkat.\n\nUntuk informasi selengkapnya, hubungi admin."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"Perangkat dikelola oleh organisasi.\n\nAdmin dapat memantau dan mengelola setelan, akses perusahaan, aplikasi, data yang terkait dengan perangkat, dan informasi lokasi perangkat.\n\nUntuk informasi selengkapnya, hubungi admin."</string>
+ <!-- no translation found for monitoring_description_named_management (505833016545056036) -->
+ <skip />
+ <!-- no translation found for monitoring_description_management (4308879039175729014) -->
+ <skip />
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Organisasi Anda menginstal otoritas sertifikat di perangkat ini. Traffic jaringan aman Anda mungkin dipantau atau diubah."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Organisasi Anda menginstal otoritas sertifikat di profil kerja. Traffic jaringan aman Anda mungkin dipantau atau diubah."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Otoritas sertifikat diinstal di perangkat. Traffic jaringan aman Anda mungkin dipantau atau diubah."</string>
@@ -920,6 +936,7 @@
<string name="pip_pause" msgid="1139598607050555845">"Jeda"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"Lewati ke berikutnya"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"Lewati ke sebelumnya"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"Ubah ukuran"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"Ponsel dimatikan karena panas"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"Ponsel kini berfungsi normal"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Ponsel menjadi terlalu panas, jadi dimatikan untuk mendinginkan. Ponsel kini berfungsi normal.\n\nPonsel dapat menjadi terlalu panas jika Anda:\n • Menggunakan aplikasi yang menggunakan sumber daya secara intensif (seperti aplikasi game, video, atau navigasi)\n • Mendownload atau mengupload file besar\n • Menggunakan ponsel dalam suhu tinggi"</string>
@@ -1013,7 +1030,7 @@
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Navigasi sistem diupdate. Untuk melakukan perubahan, buka Setelan."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Buka Setelan untuk mengupdate navigasi sistem"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Siaga"</string>
- <string name="priority_onboarding_title" msgid="2893070698479227616">"Percakapan disetel ke prioritas"</string>
+ <string name="priority_onboarding_title" msgid="2893070698479227616">"Percakapan ditetapkan jadi prioritas"</string>
<string name="priority_onboarding_behavior" msgid="5342816047020432929">"Percakapan prioritas akan:"</string>
<string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Muncul di atas bagian percakapan"</string>
<string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Menampilkan gambar profil di layar kunci"</string>
@@ -1045,7 +1062,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Tahan &amp; tarik untuk mengatur ulang kontrol"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"Semua kontrol dihapus"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Perubahan tidak disimpan"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"Daftar semua kontrol tidak dapat dimuat."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"Kontrol tidak dapat dimuat. Periksa aplikasi <xliff:g id="APP">%s</xliff:g> untuk memastikan setelan aplikasi tidak berubah."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"Kontrol yang kompatibel tidak tersedia"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Lainnya"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"Tambahkan ke kontrol perangkat"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"Tambahkan"</string>
@@ -1061,8 +1079,15 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"Konfirmasi perubahan untuk <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Geser untuk melihat selengkapnya"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Memuat rekomendasi"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"Tutup sesi media ini"</string>
+ <!-- no translation found for controls_media_title (1746947284862928133) -->
+ <skip />
+ <!-- no translation found for controls_media_close_session (3957093425905475065) -->
+ <skip />
+ <!-- no translation found for controls_media_dismiss_button (4485675693008031646) -->
+ <skip />
<string name="controls_media_resume" msgid="1933520684481586053">"Lanjutkan"</string>
+ <!-- no translation found for controls_media_settings_button (5815790345117172504) -->
+ <skip />
<string name="controls_error_timeout" msgid="794197289772728958">"Nonaktif, periksa aplikasi"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Error, mencoba lagi..."</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Tidak ditemukan"</string>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index a3119ce21498..82ceb4e43aac 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -454,8 +454,8 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Ýttu aftur til að opna"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Strjúktu upp til að opna"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Strjúktu upp til að reyna aftur"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"Þessu tæki er stýrt af fyrirtækinu þínu"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"Þessu tæki er stýrt af <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
+ <string name="do_disclosure_generic" msgid="4896482821974707167">"Þetta tæki tilheyrir fyrirtækinu þínu"</string>
+ <string name="do_disclosure_with_name" msgid="2091641464065004091">"Þetta tæki tilheyrir <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="6682125338461375925">"Strjúktu frá tákninu fyrir síma"</string>
<string name="voice_hint" msgid="7476017460191291417">"Strjúktu frá tákninu fyrir raddaðstoð"</string>
<string name="camera_hint" msgid="4519495795000658637">"Strjúktu frá tákninu fyrir myndavél"</string>
@@ -521,21 +521,21 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"Hugsanlega er fylgst með þessu sniði"</string>
<string name="vpn_footer" msgid="3457155078010607471">"Hugsanlega er fylgst með netinu"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"Hugsanlega er fylgst með netinu"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"Fyrirtækið þitt stjórnar þessu tæki og kann að fylgjast með netnotkun."</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> stjórnar þessu tæki og kann að fylgjast með netnotkun."</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"Tæki er stýrt af fyrirtækinu þínu og tengt við <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"Tæki er stýrt af <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> og tengt við <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"Tæki er stýrt af fyrirtækinu þínu"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"Tæki er stýrt af <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"Tæki er stýrt af fyrirtækinu þínu og tengt við VPN"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"Tæki er stýrt af <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> og tengt við VPN"</string>
+ <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Fyrirtækið þitt á þetta tæki og fylgist hugsanlega með netumferð"</string>
+ <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> á þetta tæki og fylgist hugsanlega með netumferð"</string>
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Þetta tæki tilheyrir fyrirtækinu þínu og er tengt við <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Þetta tæki tilheyrir <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> og er tengt við <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Þetta tæki tilheyrir fyrirtækinu þínu"</string>
+ <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Þetta tæki tilheyrir <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management_vpns" msgid="371835422690053154">"Þetta tæki tilheyrir fyrirtækinu þínu og er tengt við VPN-net"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="4046375645500668555">"Þetta tæki tilheyrir <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> og er tengt við VPN-net"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Fyrirtækið þitt kann að fylgjast með netnotkun á vinnusniðinu þínu"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> kann að fylgjast með netnotkun á vinnusniðinu þínu"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Hugsanlega er fylgst með netinu"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"Tæki er tengt við VPN"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"Vinnusnið er tengt við <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"Einkaprófíll er tengdur við <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"Tæki er tengt við <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_vpns" msgid="7213546797022280246">"Þetta tæki er tengt við VPN-net"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Vinnusniðið þitt er tengt við <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Einkaprófíllinn þinn er tengdur við <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Þetta tæki er tengt við <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Tækjastjórnun"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Fylgst með sniði"</string>
<string name="monitoring_title" msgid="4063890083735924568">"Neteftirlit"</string>
@@ -545,8 +545,8 @@
<string name="disable_vpn" msgid="482685974985502922">"Slökkva á VPN"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"Aftengja VPN-net"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"Skoða stefnur"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> stjórnar tækinu þínu.\n\nKerfisstjórinn getur fylgst með og breytt stillingum, fyrirtækjaaðgangi, forritum, gögnum sem tengjast tækinu þínu og staðsetningarupplýsingum tækisins.\n\nHafðu samband við kerfisstjórann til að fá frekari upplýsingar."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"Fyrirtækið þitt stjórnar tækinu þínu.\n\nKerfisstjórinn getur fylgst með og breytt stillingum, fyrirtækjaaðgangi, forritum, gögnum sem tengjast tækinu þínu og staðsetningarupplýsingum tækisins.\n\nHafðu samband við kerfisstjórann til að fá frekari upplýsingar."</string>
+ <string name="monitoring_description_named_management" msgid="505833016545056036">"Þetta tæki tilheyrir <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nKerfisstjórinn getur fylgst með og breytt stillingum, fyrirtækjaaðgangi, forritum, gögnum sem tengjast tækinu þínu og staðsetningarupplýsingum tækisins.\n\nHafðu samband við kerfisstjórann til að fá frekari upplýsingar."</string>
+ <string name="monitoring_description_management" msgid="4308879039175729014">"Þetta tæki tilheyrir fyrirtækinu þínu.\n\nKerfisstjórinn getur fylgst með og breytt stillingum, fyrirtækjaaðgangi, forritum, gögnum sem tengjast tækinu þínu og staðsetningarupplýsingum tækisins.\n\nHafðu samband við kerfisstjórann til að fá frekari upplýsingar."</string>
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Fyrirtækið þitt setti upp CA-vottorð á þessu tæki. Eftirlit kann að vera haft með öruggri netnotkun þinni eða henni kann að vera breytt."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Fyrirtækið þitt setti upp CA-vottorð á vinnusniðinu þínu. Eftirlit kann að vera haft með öruggri netnotkun þinni eða henni kann að vera breytt."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"CA-vottorð er uppsett á þessu tæki. Eftirlit kann að vera haft með öruggri netnotkun þinni eða henni kann að vera breytt."</string>
@@ -920,6 +920,7 @@
<string name="pip_pause" msgid="1139598607050555845">"Gera hlé"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"Fara á næsta"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"Fara á fyrra"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"Breyta stærð"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"Slökkt var á símanum vegna hita"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"Síminn virkar núna sem skyldi"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Síminn varð of heitur og því var slökkt á honum til að kæla hann. Síminn virkar núna sem skyldi.\n\nSíminn getur orðið of heitur ef þú:\n • Notar plássfrek forrit (t.d. leikja-, myndbands- eða leiðsagnarforrit\n • Sækir eða hleður upp stórum skrám\n • Notar símann í miklum hita"</string>
@@ -1015,7 +1016,7 @@
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Biðstaða"</string>
<string name="priority_onboarding_title" msgid="2893070698479227616">"Samtal sett í forgang"</string>
<string name="priority_onboarding_behavior" msgid="5342816047020432929">"Forgangssamtöl munu:"</string>
- <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Sýna yfir samtalshluta"</string>
+ <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Birtast efst í samtalshluta"</string>
<string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Sýna prófílmynd á lásskjá"</string>
<string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Birta sem fljótandi blöðru yfir forritum"</string>
<string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Stöðva „Ónáðið ekki“"</string>
@@ -1045,7 +1046,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Haltu og dragðu til að endurraða stýringum"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"Allar stýringar fjarlægðar"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Breytingar ekki vistaðar"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"Ekki tókst að hlaða lista yfir allar stýringar."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"Ekki tókst að hlaða stýringum. Athugaðu <xliff:g id="APP">%s</xliff:g> til að ganga úr skugga um að stillingar forritsins hafi ekki breyst."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"Samhæfar stýringar eru ekki tiltækar"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Annað"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"Bæta við tækjastjórnun"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"Bæta við"</string>
@@ -1061,8 +1063,11 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"Staðfesta breytingu fyrir <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Strjúktu til að sjá meira"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Hleður tillögum"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"Loka þessari efnislotu"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"Margmiðlunarefni"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"Fela núverandi lotu."</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Fela"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Halda áfram"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"Stillingar"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Óvirkt, athugaðu forrit"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Villa, reynir aftur…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Fannst ekki"</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index b90ae3e5834a..6f6ca2b0a7fc 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -454,8 +454,10 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Tocca ancora per aprire"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Scorri verso l\'alto per aprire"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Scorri verso l\'alto per riprovare"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"Questo dispositivo è gestito dalla tua organizzazione"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"Questo dispositivo è gestito da <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for do_disclosure_generic (4896482821974707167) -->
+ <skip />
+ <!-- no translation found for do_disclosure_with_name (2091641464065004091) -->
+ <skip />
<string name="phone_hint" msgid="6682125338461375925">"Scorri per accedere al telefono"</string>
<string name="voice_hint" msgid="7476017460191291417">"Scorri dall\'icona per accedere a Voice Assist"</string>
<string name="camera_hint" msgid="4519495795000658637">"Scorri dall\'icona per accedere alla fotocamera"</string>
@@ -521,21 +523,33 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"Il profilo potrebbe essere monitorato"</string>
<string name="vpn_footer" msgid="3457155078010607471">"La rete potrebbe essere monitorata"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"La rete potrebbe essere monitorata"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"Questo dispositivo è gestito dalla tua organizzazione, che potrebbe monitorare il traffico di rete"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"Questo dispositivo è gestito da <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>, che potrebbe monitorare il traffico di rete"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"Il dispositivo è gestito dalla tua organizzazione e collegato a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"Il dispositivo è gestito da <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> e collegato a <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"Il dispositivo è gestito dalla tua organizzazione"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"Il dispositivo è gestito da <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"Il dispositivo è gestito dalla tua organizzazione e collegato a VPN"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"Il dispositivo è gestito da <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> e collegato a VPN"</string>
+ <!-- no translation found for quick_settings_disclosure_management_monitoring (8231336875820702180) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_monitoring (2831423806103479812) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_named_vpn (6096715329056415588) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (5302786161534380104) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management (5515296598440684962) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management (3476472755775165827) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_vpns (371835422690053154) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_vpns (4046375645500668555) -->
+ <skip />
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"La tua organizzazione potrebbe monitorare il traffico di rete nel tuo profilo di lavoro"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> potrebbe monitorare il traffico di rete nel tuo profilo di lavoro"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"La rete potrebbe essere monitorata"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"Dispositivo collegato a VPN"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"Profilo di lavoro collegato a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"Profilo personale collegato a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"Dispositivo collegato a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <!-- no translation found for quick_settings_disclosure_vpns (7213546797022280246) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (8117568745060010789) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (5481763430080807797) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_vpn (2350838218824492465) -->
+ <skip />
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Gestione dei dispositivi"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Monitoraggio del profilo"</string>
<string name="monitoring_title" msgid="4063890083735924568">"Monitoraggio rete"</string>
@@ -545,8 +559,10 @@
<string name="disable_vpn" msgid="482685974985502922">"Disattiva VPN"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"Scollega VPN"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"Visualizza le norme"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"Il dispositivo è gestito da <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nL\'amministratore può monitorare e gestire impostazioni, accesso aziendale, app, dati associati al dispositivo e informazioni sulla posizione del dispositivo.\n\nPer ulteriori informazioni, contatta l\'amministratore."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"Il dispositivo è gestito dalla tua organizzazione.\n\nL\'amministratore può monitorare e gestire impostazioni, accesso aziendale, app, dati associati al dispositivo e informazioni sulla posizione del dispositivo.\n\nPer ulteriori informazioni, contatta l\'amministratore."</string>
+ <!-- no translation found for monitoring_description_named_management (505833016545056036) -->
+ <skip />
+ <!-- no translation found for monitoring_description_management (4308879039175729014) -->
+ <skip />
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"La tua organizzazione ha installato un\'autorità di certificazione sul dispositivo. Il tuo traffico di rete protetto potrebbe essere monitorato o modificato."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"La tua organizzazione ha installato un\'autorità di certificazione nel tuo profilo di lavoro. Il tuo traffico di rete protetto potrebbe essere monitorato o modificato."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Sul dispositivo è installata un\'autorità di certificazione. Il tuo traffico di rete protetto potrebbe essere monitorato o modificato."</string>
@@ -920,6 +936,7 @@
<string name="pip_pause" msgid="1139598607050555845">"Metti in pausa"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"Passa ai contenuti successivi"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"Passa ai contenuti precedenti"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"Ridimensiona"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"Il telefono si è spento perché surriscaldato"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"Ora il telefono funziona normalmente"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Il telefono era surriscaldato e si è spento per raffreddarsi. Ora funziona normalmente.\n\nIl telefono può surriscaldarsi se:\n • Utilizzi app che consumano molte risorse (ad esempio app di navigazione, giochi o video)\n • Scarichi o carichi grandi file\n • Lo utilizzi in presenza di alte temperature"</string>
@@ -1003,10 +1020,10 @@
<string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Sposta in basso a sinistra"</string>
<string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Sposta in basso a destra"</string>
<string name="bubble_dismiss_text" msgid="1314082410868930066">"Ignora bolla"</string>
- <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Non utilizzare bolle per la conversazione"</string>
+ <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Non mettere la conversazione nella bolla"</string>
<string name="bubbles_user_education_title" msgid="5547017089271445797">"Chatta utilizzando le bolle"</string>
<string name="bubbles_user_education_description" msgid="1160281719576715211">"Le nuove conversazioni vengono visualizzate come icone mobili o bolle. Tocca per aprire la bolla. Trascinala per spostarla."</string>
- <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Controlla le bolle in qualsiasi momento"</string>
+ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Controlla le bolle quando vuoi"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"Tocca Gestisci per disattivare le bolle dall\'app"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string>
<string name="bubbles_app_settings" msgid="5779443644062348657">"Impostazioni <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
@@ -1016,7 +1033,7 @@
<string name="priority_onboarding_title" msgid="2893070698479227616">"Conversazione impostata come prioritaria"</string>
<string name="priority_onboarding_behavior" msgid="5342816047020432929">"Le conversazioni prioritarie:"</string>
<string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Appaiono in cima alla sezione delle conversazioni"</string>
- <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Mostrano immagine profilo in schermata di blocco"</string>
+ <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Mostrano l\'immagine del profilo sulla schermata di blocco"</string>
<string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Vengono mostrate come bolle mobili sopra le app"</string>
<string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Interrompono la modalità Non disturbare"</string>
<string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"OK"</string>
@@ -1045,7 +1062,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Tieni premuto e trascina per riordinare i controlli"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"Tutti i controlli sono stati rimossi"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Modifiche non salvate"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"Impossibile caricare l\'elenco di tutti i controlli."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"Impossibile caricare i controlli. Verifica nell\'app <xliff:g id="APP">%s</xliff:g> che le relative impostazioni non siano cambiate."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"Controlli compatibili non disponibili"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Altro"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"Aggiungi al controllo dei dispositivi"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"Aggiungi"</string>
@@ -1061,8 +1079,11 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"Conferma modifica per <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Scorri per vedere altro"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Caricamento dei consigli"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"Chiudi questa sessione multimediale"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"Contenuti multimediali"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"Nascondi la sessione attuale."</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Nascondi"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Riprendi"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"Impostazioni"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inattivo, controlla l\'app"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Errore. Nuovo tentativo…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Controllo non trovato"</string>
@@ -1070,7 +1091,7 @@
<string name="controls_error_removed_message" msgid="2885911717034750542">"Impossibile accedere a: <xliff:g id="DEVICE">%1$s</xliff:g>. Verifica nell\'app <xliff:g id="APPLICATION">%2$s</xliff:g> che il controllo sia ancora disponibile e che le impostazioni dell\'app non siano cambiate."</string>
<string name="controls_open_app" msgid="483650971094300141">"Apri app"</string>
<string name="controls_error_generic" msgid="352500456918362905">"Impossibile caricare lo stato"</string>
- <string name="controls_error_failed" msgid="960228639198558525">"Errore. Riprova"</string>
+ <string name="controls_error_failed" msgid="960228639198558525">"Errore, riprova"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"In corso"</string>
<string name="controls_added_tooltip" msgid="4842812921719153085">"Tieni premuto il tasto di accensione per visualizzare i nuovi controlli"</string>
<string name="controls_menu_add" msgid="4447246119229920050">"Aggiungi controlli"</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 9d2d0cc973aa..b7a726e1fe1e 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -458,8 +458,10 @@
<string name="notification_tap_again" msgid="4477318164947497249">"הקש שוב כדי לפתוח"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"צריך להחליק כדי לפתוח"</string>
<string name="keyguard_retry" msgid="886802522584053523">"יש להחליק למעלה כדי לנסות שוב"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"מכשיר זה מנוהל על ידי הארגון שלך"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"המכשיר הזה מנוהל על ידי <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for do_disclosure_generic (4896482821974707167) -->
+ <skip />
+ <!-- no translation found for do_disclosure_with_name (2091641464065004091) -->
+ <skip />
<string name="phone_hint" msgid="6682125338461375925">"החלק מהסמל כדי להפעיל את הטלפון"</string>
<string name="voice_hint" msgid="7476017460191291417">"החלק מהסמל כדי להפעיל את המסייע הקולי"</string>
<string name="camera_hint" msgid="4519495795000658637">"החלק מהסמל כדי להפעיל את המצלמה"</string>
@@ -527,21 +529,33 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"ייתכן שהפרופיל נתון למעקב"</string>
<string name="vpn_footer" msgid="3457155078010607471">"ייתכן שהרשת נמצאת במעקב"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"ייתכן שהרשת מנוטרת"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"הארגון שלך מנהל מכשיר זה ועשוי לנטר את התנועה ברשת"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"הארגון <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> מנהל מכשיר זה ועשוי לנטר את התנועה ברשת"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"המכשיר מנוהל על ידי הארגון ומחובר לאפליקציה <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"המכשיר מנוהל על ידי <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ומחובר לאפליקציה <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"המכשיר מנוהל על ידי הארגון שלך"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"מכשיר זה מנוהל על ידי <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"‏המכשיר מנוהל על ידי הארגון שלך ומחובר לאפליקציות VPN"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"‏המכשיר מנוהל על ידי <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ומחובר לאפליקציות VPN"</string>
+ <!-- no translation found for quick_settings_disclosure_management_monitoring (8231336875820702180) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_monitoring (2831423806103479812) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_named_vpn (6096715329056415588) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (5302786161534380104) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management (5515296598440684962) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management (3476472755775165827) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_vpns (371835422690053154) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_vpns (4046375645500668555) -->
+ <skip />
<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_monitoring" msgid="8548019955631378680">"ייתכן שהרשת מנוטרת"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"‏המכשיר מחובר לאפליקציות VPN"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"פרופיל העבודה מחובר לאפליקציה <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"הפרופיל האישי מחובר לאפליקציה <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"המכשיר מחובר לאפליקציה <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <!-- no translation found for quick_settings_disclosure_vpns (7213546797022280246) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (8117568745060010789) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (5481763430080807797) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_vpn (2350838218824492465) -->
+ <skip />
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"ניהול מכשירים"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"מעקב אחר פרופיל"</string>
<string name="monitoring_title" msgid="4063890083735924568">"מעקב אחר פעילות ברשת"</string>
@@ -551,8 +565,10 @@
<string name="disable_vpn" msgid="482685974985502922">"‏השבת VPN"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"‏נתק את ה-VPN"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"הצג מדיניות"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"המכשיר שלך מנוהל על ידי <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nמנהל המערכת יכול לנטר ולנהל הגדרות, גישה ארגונית, אפליקציות, נתונים המשויכים למכשיר ומידע על מיקום המכשיר.\n\nלמידע נוסף, פנה למנהל המערכת."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"המכשיר מנוהל על ידי הארגון שלך.\n\nמנהל המערכת יכול לנטר ולנהל הגדרות, גישה ארגונית, אפליקציות, נתונים המשויכים למכשיר ומידע על מיקום המכשיר.\n\nלמידע נוסף, פנה למנהל המערכת."</string>
+ <!-- no translation found for monitoring_description_named_management (505833016545056036) -->
+ <skip />
+ <!-- no translation found for monitoring_description_management (4308879039175729014) -->
+ <skip />
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"הארגון שלך התקין רשות אישורים במכשיר. ניתן לעקוב אחר התנועה ברשת המאובטחת או לשנות אותה."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"הארגון שלך התקין רשות אישורים בפרופיל העבודה. ניתן לעקוב אחר התנועה ברשת המאובטחת או לשנות אותה."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"במכשיר זה מותקנת רשות אישורים. ניתן לעקוב אחר התנועה ברשת המאובטחת או לשנות אותה."</string>
@@ -930,6 +946,7 @@
<string name="pip_pause" msgid="1139598607050555845">"השהה"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"אפשר לדלג אל הבא"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"אפשר לדלג אל הקודם"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"שינוי גודל"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"הטלפון כבה עקב התחממות"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"הטלפון פועל כרגיל עכשיו"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"הטלפון שלך התחמם יותר מדי וכבה כדי להתקרר. הטלפון פועל כרגיל עכשיו.\n\nייתכן שהטלפון יתחמם יותר מדי אם:\n • תשתמש באפליקציות עתירות משאבים (כגון משחקים, אפליקציות וידאו או אפליקציות ניווט)\n • תוריד או תעלה קבצים גדולים\n • תשתמש בטלפון בטמפרטורות גבוהות"</string>
@@ -1057,7 +1074,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"יש ללחוץ לחיצה ארוכה ולגרור כדי לארגן מחדש את הפקדים"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"כל הפקדים הוסרו"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"השינויים לא נשמרו"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"לא ניתן היה לטעון את הרשימה של כל הפקדים."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"לא ניתן היה לטעון את הפקדים. יש לבדוק את האפליקציה <xliff:g id="APP">%s</xliff:g> כדי לוודא שהגדרות האפליקציה לא השתנו."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"פקדים תואמים לא זמינים"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"אחר"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"הוספה לפקדי המכשירים"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"הוספה"</string>
@@ -1073,8 +1091,11 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"יש לאשר את השינוי עבור <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"יש להחליק כדי להציג עוד פריטים"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"בטעינת המלצות"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"סגירת הסשן הזה של המדיה"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"מדיה"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"הסתרת הסשן הנוכחי."</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"הסתרה"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"המשך"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"הגדרות"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"לא פעיל, יש לבדוק את האפליקציה"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"שגיאה, מתבצע ניסיון חוזר…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"לא נמצא"</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 4f6c7858379c..38904f594907 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -454,8 +454,8 @@
<string name="notification_tap_again" msgid="4477318164947497249">"開くにはもう一度タップしてください"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"開くには上にスワイプします"</string>
<string name="keyguard_retry" msgid="886802522584053523">"上にスワイプしてもう一度お試しください"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"このデバイスは組織によって管理されています"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"このデバイスは <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> が管理しています"</string>
+ <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="phone_hint" msgid="6682125338461375925">"右にスワイプして通話"</string>
<string name="voice_hint" msgid="7476017460191291417">"アイコンからスワイプして音声アシストを起動"</string>
<string name="camera_hint" msgid="4519495795000658637">"左にスワイプしてカメラを起動"</string>
@@ -521,21 +521,21 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"プロファイルが監視されている可能性があります"</string>
<string name="vpn_footer" msgid="3457155078010607471">"ネットワークが監視されている可能性があります"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"ネットワークが監視されている可能性があります"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"組織がこのデバイスを管理しています。ネットワーク トラフィックが監視されることもあります"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> がこのデバイスを管理しています。ネットワーク トラフィックが監視されることもあります"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"デバイスは組織によって管理され、<xliff:g id="VPN_APP">%1$s</xliff:g> に接続しています"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"デバイスは <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> によって管理され、<xliff:g id="VPN_APP">%2$s</xliff:g> に接続しています"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"デバイスは組織によって管理されています"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"デバイスは <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> によって管理されています"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"デバイスは組織によって管理され、VPN に接続しています"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"デバイスは <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> によって管理され、VPN に接続しています"</string>
+ <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"これは組織が所有するデバイスで、ネットワーク トラフィックが監視されることもあります"</string>
+ <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"これは <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> が所有するデバイスで、ネットワーク トラフィックが監視されることもあります"</string>
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"これは組織が所有するデバイスで、<xliff:g id="VPN_APP">%1$s</xliff:g> に接続しています"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"これは <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> が所有するデバイスで、<xliff:g id="VPN_APP">%2$s</xliff:g> に接続しています"</string>
+ <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"これは組織が所有するデバイスです"</string>
+ <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"これは <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> が所有するデバイスです"</string>
+ <string name="quick_settings_disclosure_management_vpns" msgid="371835422690053154">"これは組織が所有するデバイスで、VPN に接続しています"</string>
+ <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_monitoring" msgid="8548019955631378680">"ネットワークが監視されることもあります"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"デバイスは VPN に接続しています"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"仕事用プロファイルは <xliff:g id="VPN_APP">%1$s</xliff:g> に接続しています"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"個人用プロファイルは <xliff:g id="VPN_APP">%1$s</xliff:g> に接続しています"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"デバイスは <xliff:g id="VPN_APP">%1$s</xliff:g> に接続しています"</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>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"この個人用プロファイルは <xliff:g id="VPN_APP">%1$s</xliff:g> に接続しています"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"このデバイスは <xliff:g id="VPN_APP">%1$s</xliff:g> に接続しています"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"デバイス管理"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"プロファイルの監視"</string>
<string name="monitoring_title" msgid="4063890083735924568">"ネットワーク監視"</string>
@@ -545,8 +545,8 @@
<string name="disable_vpn" msgid="482685974985502922">"VPNを無効にする"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"VPNを切断"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"ポリシーを見る"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"このデバイスは <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> によって管理されています。\n\n管理者は、このデバイスに関連付けられた設定、コーポレート アクセス、アプリ、データと、デバイスの位置情報を監視、管理できます。\n\n詳しくは管理者にお問い合わせください。"</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"このデバイスは組織によって管理されています。\n\n管理者は、このデバイスに関連付けられた設定、コーポレート アクセス、アプリ、データと、デバイスの位置情報を監視、管理できます。\n\n詳しくは管理者にお問い合わせください。"</string>
+ <string name="monitoring_description_named_management" msgid="505833016545056036">"これは <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> が所有するデバイスです。\n\nIT 管理者が、このデバイスに関連付けられている設定、コーポレート アクセス、アプリ、データのほか、デバイスの位置情報を監視、管理できます。\n\n詳しくは、IT 管理者にお問い合わせください。"</string>
+ <string name="monitoring_description_management" msgid="4308879039175729014">"これは組織が所有するデバイスです。\n\nIT 管理者が、このデバイスに関連付けられている設定、コーポレート アクセス、アプリ、データのほか、デバイスの位置情報を監視、管理できます。\n\n詳しくは、IT 管理者にお問い合わせください。"</string>
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"組織によってこのデバイスに認証局がインストールされました。保護されたネットワーク トラフィックが監視、変更される場合があります。"</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"組織によって、あなたの仕事用プロファイルに認証局がインストールされました。保護されたネットワーク トラフィックが監視、変更される場合があります。"</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"このデバイスには認証局がインストールされています。保護されたネットワーク トラフィックが監視、変更される可能性があります。"</string>
@@ -920,6 +920,7 @@
<string name="pip_pause" msgid="1139598607050555845">"一時停止"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"次へスキップ"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"前へスキップ"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"サイズ変更"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"高熱で電源が OFF になりました"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"お使いのスマートフォンは現在、正常に動作しています"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"スマートフォンが熱すぎたため電源が OFF になりました。現在は正常に動作しています。\n\nスマートフォンは以下の場合に熱くなる場合があります。\n • リソースを集中的に使用する機能やアプリ(ゲームアプリ、動画アプリ、ナビアプリなど)を使用\n • サイズの大きいファイルをダウンロードまたはアップロード\n • 高温の場所で使用"</string>
@@ -1002,19 +1003,19 @@
<string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"右上に移動"</string>
<string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"左下に移動"</string>
<string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"右下に移動"</string>
- <string name="bubble_dismiss_text" msgid="1314082410868930066">"ふきだしを閉じる"</string>
+ <string name="bubble_dismiss_text" msgid="1314082410868930066">"バブルを閉じる"</string>
<string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"会話をバブルで表示しない"</string>
<string name="bubbles_user_education_title" msgid="5547017089271445797">"チャットでバブルを使う"</string>
<string name="bubbles_user_education_description" msgid="1160281719576715211">"新しい会話はフローティング アイコン(バブル)として表示されます。タップするとバブルが開きます。ドラッグしてバブルを移動できます。"</string>
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"いつでもバブルを管理"</string>
- <string name="bubbles_user_education_manage" msgid="1391639189507036423">"このアプリからのバブルをオフにするには、[管理] をタップしてください"</string>
+ <string name="bubbles_user_education_manage" msgid="1391639189507036423">"このアプリからのバブルを OFF にするには、[管理] をタップしてください"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string>
<string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> の設定"</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"システム ナビゲーションを更新しました。変更するには [設定] に移動してください。"</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"システム ナビゲーションを更新するには [設定] に移動してください"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"スタンバイ"</string>
<string name="priority_onboarding_title" msgid="2893070698479227616">"優先度を高く設定された会話"</string>
- <string name="priority_onboarding_behavior" msgid="5342816047020432929">"優先度の高い会話では、次のようになります。"</string>
+ <string name="priority_onboarding_behavior" msgid="5342816047020432929">"優先度の高い会話は、次のように表示されます。"</string>
<string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"会話セクションの一番上にバブルで表示"</string>
<string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"ロック画面にプロフィール写真を表示"</string>
<string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"他のアプリに重ねてフローティング バブルとして表示"</string>
@@ -1045,7 +1046,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"コントロールを並べ替えるには長押ししてドラッグします"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"すべてのコントロールを削除しました"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"変更が保存されていません"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"全コントロールの一覧を読み込めませんでした。"</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"コントロールを読み込めませんでした。<xliff:g id="APP">%s</xliff:g> アプリで、アプリの設定が変更されていないことをご確認ください。"</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"互換性のあるコントロールがありません"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"その他"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"デバイス コントロールに追加"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"追加"</string>
@@ -1061,13 +1063,16 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"<xliff:g id="DEVICE">%s</xliff:g>の変更を確認する"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"スワイプすると他の構造が表示されます"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"候補を読み込んでいます"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"このメディア セッションを閉じる"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"メディア"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"現在のセッションを非表示にします。"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"非表示"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"再開"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"設定"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"無効: アプリをご確認ください"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"エラー。再試行しています…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"見つかりませんでした"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"コントロールを使用できません"</string>
- <string name="controls_error_removed_message" msgid="2885911717034750542">"「<xliff:g id="DEVICE">%1$s</xliff:g>」にアクセスできませんでした<xliff:g id="APPLICATION">%2$s</xliff:g> アプリで、コントロールが使用可能な状態でアプリの設定が変更されていないことをご確認ください。"</string>
+ <string name="controls_error_removed_message" msgid="2885911717034750542">"「<xliff:g id="DEVICE">%1$s</xliff:g>」にアクセスできませんでした。<xliff:g id="APPLICATION">%2$s</xliff:g> アプリで、コントロールが使用可能な状態でアプリの設定が変更されていないことをご確認ください。"</string>
<string name="controls_open_app" msgid="483650971094300141">"アプリを開く"</string>
<string name="controls_error_generic" msgid="352500456918362905">"ステータスを読み込めません"</string>
<string name="controls_error_failed" msgid="960228639198558525">"エラー: もう一度お試しください"</string>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index aeee416750ed..72a494a9f7c7 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -454,8 +454,8 @@
<string name="notification_tap_again" msgid="4477318164947497249">"შეეხეთ ისევ გასახსნელად"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"გასახსნელად გადაფურცლეთ ზემოთ"</string>
<string name="keyguard_retry" msgid="886802522584053523">"ხელახლა საცდელად გადაფურცლეთ ზემოთ"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"ამ მოწყობილობას მართავს თქვენი ორგანიზაცია"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"ამ მოწყობილობას მართავს <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
+ <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="phone_hint" msgid="6682125338461375925">"ტელეფონისთვის გადაფურცლეთ ხატულადან"</string>
<string name="voice_hint" msgid="7476017460191291417">"ხმოვანი დახმარებისთვის გადაფურცლეთ ხატულადან"</string>
<string name="camera_hint" msgid="4519495795000658637">"კამერისთვის გადაფურცლეთ ხატულადან"</string>
@@ -521,21 +521,21 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"შესაძლოა პროფილზე ხორციელდებოდეს მონიტორინგი"</string>
<string name="vpn_footer" msgid="3457155078010607471">"შესაძლოა ქსელზე ხორციელდება მონიტორინგი"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"ქსელზე შესაძლოა მონიტორინგი ხორციელდებოდეს"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"ამ მოწყობილობას მართავს თქვენი ორგანიზაცია და მას ქსელის ტრაფიკის მონიტორინგი შეუძლია"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"ამ მოწყობილობას მართავს <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> და მას ქსელის ტრაფიკის მონიტორინგი შეუძლია"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"მოწყობილობას მართავს თქვენი ორგანიზაცია და ის დაკავშირებულია <xliff:g id="VPN_APP">%1$s</xliff:g>-თან"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"მოწყობილობას მართავს <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> და ის დაკავშირებულია <xliff:g id="VPN_APP">%2$s</xliff:g>-თან"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"მოწყობილობას მართავს თქვენი ორგანიზაცია"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"მოწყობილობას მართავს <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"მოწყობილობას მართავს თქვენი ორგანიზაცია და ის დაკავშირებულია VPN-ებთან"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"მოწყობილობას მართავს <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> და ის დაკავშირებულია VPN-ებთან"</string>
+ <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"ამ მოწყობილობას ფლობს თქვენი ორგანიზაცია და მას ქსელის ტრაფიკის მონიტორინგი შეუძლია"</string>
+ <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"ამ მოწყობილობას ფლობს <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> და მას ქსელის ტრაფიკის მონიტორინგი შეუძლია"</string>
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"ამ მოწყობილობას ფლობს თქვენი ორგანიზაცია და ის დაკავშირებულია <xliff:g id="VPN_APP">%1$s</xliff:g>-თან"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"ამ მოწყობილობას ფლობს <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> და ის დაკავშირებულია <xliff:g id="VPN_APP">%2$s</xliff:g>-თან"</string>
+ <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"ამ მოწყობილობას ფლობს თქვენი ორგანიზაცია"</string>
+ <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"ამ მოწყობილობას ფლობს <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management_vpns" msgid="371835422690053154">"ამ მოწყობილობას ფლობს თქვენი ორგანიზაცია და ის დაკავშირებულია VPN-ებთან"</string>
+ <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_monitoring" msgid="8548019955631378680">"ქსელზე შესაძლოა ხორციელდებოდეს მონიტორინგი"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"მოწყობილობა დაკავშირებულია VPN-ებთან"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"სამსახურის პროფილი დაკავშირებულია <xliff:g id="VPN_APP">%1$s</xliff:g>-თან"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"პირადი პროფილი დაკავშირებულია <xliff:g id="VPN_APP">%1$s</xliff:g>-თან"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"მოწყობილობა დაკავშირებულია <xliff:g id="VPN_APP">%1$s</xliff:g>-თან"</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>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"თქვენი პერსონალური პროფილი დაკავშირებულია <xliff:g id="VPN_APP">%1$s</xliff:g>-თან"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"ეს მოწყობილობა დაკავშირებულია <xliff:g id="VPN_APP">%1$s</xliff:g>-თან"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"მოწყობილობის მართვა"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"პროფილის მონიტორინგი"</string>
<string name="monitoring_title" msgid="4063890083735924568">"ქსელის მონიტორინგი"</string>
@@ -545,8 +545,8 @@
<string name="disable_vpn" msgid="482685974985502922">"VPN-ის გაუქმება"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"VPN-ის გათიშვა"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"წესების ნახვა"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"თქვენს მოწყობილობას მართავს <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nთქვენს ადმინისტრატორს შეუძლია მოწყობილობასთან დაკავშირებული პარამეტრების, კორპორაციული წვდომის, აპებისა და მონაცემების (მათ შორის, თქვენი მოწყობილობის მდებარეობის ინფორმაციის) მონიტორინგი და მართვა.\n\nდამატებითი ინფორმაციისთვის დაუკავშირდით თქვენს ადმინისტრატორს."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"თქვენს მოწყობილობას მართავს თქვენი ორგანიზაცია.\n\nთქვენს ადმინისტრატორს შეუძლია მოწყობილობასთან დაკავშირებული პარამეტრების, კორპორაციული წვდომის, აპებისა და მონაცემების (მათ შორის, თქვენი მოწყობილობის მდებარეობის ინფორმაციის) მონიტორინგი და მართვა.\n\nდამატებითი ინფორმაციისთვის დაუკავშირდით თქვენს ადმინისტრატორს."</string>
+ <string name="monitoring_description_named_management" msgid="505833016545056036">"ეს მოწყობილობას ფლობს <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nთქვენს IT ადმინისტრატორს შეუძლია მოწყობილობასთან დაკავშირებული პარამეტრების, კორპორაციული წვდომის, აპებისა და მონაცემების (მათ შორის, თქვენი მოწყობილობის მდებარეობის ინფორმაციის) მონიტორინგი და მართვა.\n\nდამატებითი ინფორმაციისთვის დაუკავშირდით თქვენს IT ადმინისტრატორს."</string>
+ <string name="monitoring_description_management" msgid="4308879039175729014">"ამ მოწყობილობას ფლობს თქვენი ორგანიზაცია.\n\nთქვენს IT ადმინისტრატორს შეუძლია მოწყობილობასთან დაკავშირებული პარამეტრების, კორპორაციული წვდომის, აპებისა და მონაცემების (მათ შორის, თქვენი მოწყობილობის მდებარეობის ინფორმაციის) მონიტორინგი და მართვა.\n\nდამატებითი ინფორმაციისთვის დაუკავშირდით თქვენს IT ადმინისტრატორს."</string>
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"თქვენმა ორგანიზაციამ ამ მოწყობილობაზე სერტიფიცირების ორგანო დააინსტალირა. თქვენი ქსელის დაცული ტრაფიკი შეიძლება შეიცვალოს, ან მასზე მონიტორინგი განხორციელდეს."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"თქვენმა ორგანიზაციამ სამსახურის პროფილში სერტიფიცირების ორგანო დააინსტალირა. თქვენი ქსელის დაცული ტრაფიკი შეიძლება შეიცვალოს, ან მასზე მონიტორინგი განხორციელდეს."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"ამ მოწყობილობაზე დაინსტალირებულია სერტიფიცირების ორგანო. თქვენი ქსელის დაცული ტრაფიკი შეიძლება შეიცვალოს, ან მასზე მონიტორინგი განხორციელდეს."</string>
@@ -920,6 +920,7 @@
<string name="pip_pause" msgid="1139598607050555845">"დაპაუზება"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"შემდეგზე გადასვლა"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"წინაზე გადასვლა"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"ზომის შეცვლა"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"ტელეფონი გამოირთო გაცხელების გამო"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"თქვენი ტელეფონი ახლა ჩვეულებრივად მუშაობს"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"თქვენი ტელეფონი გამოირთო გასაგრილებლად, რადგან ის მეტისმეტად გაცხელდა. ახლა ის ჩვეულებრივად მუშაობს.\n\nტელეფონის გაცხელების მიზეზებია:\n • რესურსტევადი აპების გამოყენება (მაგ. სათამაშო, ვიდეო ან ნავიგაციის აპების)\n • დიდი ფაილების ჩამოტვირთვა ან ატვირთვა\n • ტელეფონის გამოყენება მაღალი ტემპერატურისას"</string>
@@ -1045,7 +1046,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"მართვის საშუალებების გადაწყობა შეგიძლიათ მათი ჩავლებით გადატანით"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"მართვის ყველა საშუალება ამოიშალა"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"ცვლილებები არ შენახულა"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"მართვის ყველა საშუალების სია ვერ ჩაიტვირთა."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"მართვის საშუალებების ჩატვირთვა ვერ მოხერხდა. შეამოწმეთ <xliff:g id="APP">%s</xliff:g> აპი, რათა დარწმუნდეთ, რომ აპის პარამეტრები არ შეცვლილა."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"მართვის თავსებადი საშუალებები მიუწვდომელია"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"სხვა"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"მოწყობილ. მართვის საშუალებებში დამატება"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"დამატება"</string>
@@ -1061,8 +1063,11 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"დაადასტურეთ ცვლილება <xliff:g id="DEVICE">%s</xliff:g>-ისთვის"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"გადაფურცლეთ მეტის სანახავად"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"მიმდინარეობს რეკომენდაციების ჩატვირთვა"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"ამ მედია სესიის დახურვა"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"მედია"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"დაიმალოს მიმდინარე სესია"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"დამალვა"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"გაგრძელება"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"პარამეტრები"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"არააქტიურია, გადაამოწმეთ აპი"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"შეცდომა, ხელახალი მცდელობა…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"ვერ მოიძებნა"</string>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 356526ce9a1d..83e18419151d 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -454,8 +454,10 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Ашу үшін қайта түртіңіз"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Ашу үшін жоғары қарай сырғытыңыз."</string>
<string name="keyguard_retry" msgid="886802522584053523">"Әрекетті қайталау үшін жоғары сырғытыңыз."</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"Бұл құрылғыны ұйым басқарады"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"Бұл құрылғыны <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> басқарады"</string>
+ <!-- no translation found for do_disclosure_generic (4896482821974707167) -->
+ <skip />
+ <!-- no translation found for do_disclosure_with_name (2091641464065004091) -->
+ <skip />
<string name="phone_hint" msgid="6682125338461375925">"Телефонды ашу үшін белгішеден әрі қарай сырғытыңыз"</string>
<string name="voice_hint" msgid="7476017460191291417">"Дауыс көмекшісін ашу үшін белгішеден әрі қарай сырғытыңыз"</string>
<string name="camera_hint" msgid="4519495795000658637">"Камераны ашу үшін белгішеден әрі қарай сырғытыңыз"</string>
@@ -521,21 +523,33 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"Профиль бақылануы мүмкін"</string>
<string name="vpn_footer" msgid="3457155078010607471">"Желі бақылауда болуы мүмкін"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"Желі бақылауда болуы мүмкін"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"Ұйымыңыз осы құрылғыны басқарады және желі трафигін бақылауы мүмкін"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> осы құрылғыны басқарады және желі трафигін бақылауы мүмкін"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"Құрылғыны ұйымыңыз басқарады және ол <xliff:g id="VPN_APP">%1$s</xliff:g> қолданбасына қосылған"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"Құрылғыны <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> басқарады және ол <xliff:g id="VPN_APP">%2$s</xliff:g> қолданбасына қосылған"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"Құрылғыны ұйымыңыз басқарады"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"Құрылғыны <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> басқарады"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"Құрылғыны ұйымыңыз басқарады және ол VPN желілеріне қосылған"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"Құрылғыны <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> басқарады және ол VPN желілеріне қосылған"</string>
+ <!-- no translation found for quick_settings_disclosure_management_monitoring (8231336875820702180) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_monitoring (2831423806103479812) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_named_vpn (6096715329056415588) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (5302786161534380104) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management (5515296598440684962) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management (3476472755775165827) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_vpns (371835422690053154) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_vpns (4046375645500668555) -->
+ <skip />
<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_monitoring" msgid="8548019955631378680">"Желі бақылануы мүмкін"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"Құрылғы VPN желілеріне қосылған"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"Жұмыс профилі <xliff:g id="VPN_APP">%1$s</xliff:g> қолданбасына қосылған"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"Жеке профиль <xliff:g id="VPN_APP">%1$s</xliff:g> қолданбасына қосылған"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"Құрылғы <xliff:g id="VPN_APP">%1$s</xliff:g> қолданбасына қосылған"</string>
+ <!-- no translation found for quick_settings_disclosure_vpns (7213546797022280246) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (8117568745060010789) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (5481763430080807797) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_vpn (2350838218824492465) -->
+ <skip />
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Құрылғыны басқару"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Профильді бақылау"</string>
<string name="monitoring_title" msgid="4063890083735924568">"Желіні бақылау"</string>
@@ -545,8 +559,10 @@
<string name="disable_vpn" msgid="482685974985502922">"VPN функциясын өшіру"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"VPN желісін ажырату"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"Саясаттарды көру"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"Құрылғыңызды <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> басқарады.\n\nӘкімші параметрлерді, корпоративтік кіру құқығын, қолданбаларды, құрылғыңызбен байланысты деректерді және құрылғыңыздың орналасқан жері туралы ақпаратты бақылай және басқара алады.\n\nҚосымша ақпарат алу үшін әкімшіге хабарласыңыз."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"Құрылғыңызды ұйымыңыз басқарады.\n\nӘкімші параметрлерді, корпоративтік кіру құқығын, қолданбаларды, құрылғыңызбен байланысты деректерді және құрылғыңыздың орналасқан жері туралы ақпаратты бақылай және басқара алады.\n\nҚосымша ақпарат алу үшін әкімшіге хабарласыңыз."</string>
+ <!-- no translation found for monitoring_description_named_management (505833016545056036) -->
+ <skip />
+ <!-- no translation found for monitoring_description_management (4308879039175729014) -->
+ <skip />
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Ұйымыңыз осы құрылғыда сертификат орнатқан. Қорғалған желі трафигіңіз бақылануы немесе өзгертілуі мүмкін."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Ұйымыңыз жұмыс профиліңізде сертификат орнатқан. Қорғалған желі трафигіңіз бақылануы немесе өзгертілуі мүмкін."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Осы құрылғыда сертификат орнатылған. Қорғалған желі трафигіңіз бақылануы немесе өзгертілуі мүмкін."</string>
@@ -920,6 +936,7 @@
<string name="pip_pause" msgid="1139598607050555845">"Кідірту"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"Келесіге өту"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"Алдыңғысына оралу"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"Өлшемін өзгерту"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"Телефон қызып кеткендіктен өшірілді"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"Телефоныңыз қазір қалыпты жұмыс істеп тұр"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Телефоныңыз қатты қызып кеткендіктен өшірілді. Телефоныңыз қазір қалыпты жұмыс істеп тұр.\n\nТелефоныңыз мына жағдайларда ыстық болуы мүмкін:\n • Ресурстар талап ететін қолданбаларды пайдалану (ойын, бейне немесе навигация қолданбалары)\n • Үлкен көлемді файлдарды жүктеу немесе жүктеп салу\n • Телефонды жоғары температурада пайдалану"</string>
@@ -1002,7 +1019,7 @@
<string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Жоғары оң жаққа жылжыту"</string>
<string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Төменгі сол жаққа жылжыту"</string>
<string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Төменгі оң жаққа жылжыту"</string>
- <string name="bubble_dismiss_text" msgid="1314082410868930066">"Қалқымалы анықтаманы жабу"</string>
+ <string name="bubble_dismiss_text" msgid="1314082410868930066">"Қалқымалы хабарды жабу"</string>
<string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Әңгіменің қалқыма хабары көрсетілмесін"</string>
<string name="bubbles_user_education_title" msgid="5547017089271445797">"Қалқыма хабарлар арқылы сөйлесу"</string>
<string name="bubbles_user_education_description" msgid="1160281719576715211">"Жаңа әңгімелер қалқыма белгішелер немесе хабарлар түрінде көрсетіледі. Қалқыма хабарды ашу үшін түртіңіз. Жылжыту үшін сүйреңіз."</string>
@@ -1014,8 +1031,8 @@
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Жүйе навигациясын жаңарту үшін \"Параметрлер\" бөліміне өтіңіз."</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Күту режимі"</string>
<string name="priority_onboarding_title" msgid="2893070698479227616">"Әңгіме маңызды деп белгіленді"</string>
- <string name="priority_onboarding_behavior" msgid="5342816047020432929">"Маңызды әңгімелердің әрекеті:"</string>
- <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Сөйлесу бөлімінің жоғарғы жағында көрсетіледі."</string>
+ <string name="priority_onboarding_behavior" msgid="5342816047020432929">"Маңызды әңгімелер:"</string>
+ <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Әңгімелер бөлімінің жоғарғы жағында көрсетіледі."</string>
<string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Профиль суреті құлыптаулы экранда көрсетіледі."</string>
<string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Қолданбалар терезесінің бергі жағынан қалқыма хабарлар түрінде көрсетіледі."</string>
<string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"\"Мазаламау\" режимінде көрсетіледі."</string>
@@ -1025,7 +1042,7 @@
<string name="magnification_window_title" msgid="4863914360847258333">"Ұлғайту терезесі"</string>
<string name="magnification_controls_title" msgid="8421106606708891519">"Ұлғайту терезесінің басқару элементтері"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"Құрылғы басқару виджеттері"</string>
- <string name="quick_controls_subtitle" msgid="1667408093326318053">"Жалғанған құрылғыларға басқару элементтерін енгізу"</string>
+ <string name="quick_controls_subtitle" msgid="1667408093326318053">"Жалғанған құрылғылар үшін басқару виджеттерін қосу"</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"Құрылғы басқару виджеттерін реттеу"</string>
<string name="quick_controls_setup_subtitle" msgid="1681506617879773824">"Басқару элементтерін шығару үшін қуат түймесін басып тұрыңыз."</string>
<string name="controls_providers_title" msgid="6879775889857085056">"Басқару элементтері енгізілетін қолданбаны таңдаңыз"</string>
@@ -1045,7 +1062,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Басқару элементтерінің ретін өзгерту үшін оларды басып тұрып сүйреңіз."</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"Барлық басқару элементтері өшірілді."</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Өзгерістер сақталмады."</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"Барлық басқару элементі тізімі жүктелмеді."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"Басқару элементтері жүктелмеді. Қолданба параметрлерінің өзгермегенін тексеру үшін <xliff:g id="APP">%s</xliff:g> қолданбасын қараңыз."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"Үйлесімді басқару элементтері қолжетімді емес."</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Басқа"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"Құрылғы басқару виджеттеріне қосу"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"Енгізу"</string>
@@ -1061,13 +1079,20 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"<xliff:g id="DEVICE">%s</xliff:g> құрылғысындағы өзгерісті растау"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Толығырақ ақпарат алу үшін сырғытыңыз."</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Жүктеуге қатысты ұсыныстар"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"Мультимедиа сеансын жабу"</string>
+ <!-- no translation found for controls_media_title (1746947284862928133) -->
+ <skip />
+ <!-- no translation found for controls_media_close_session (3957093425905475065) -->
+ <skip />
+ <!-- no translation found for controls_media_dismiss_button (4485675693008031646) -->
+ <skip />
<string name="controls_media_resume" msgid="1933520684481586053">"Жалғастыру"</string>
+ <!-- no translation found for controls_media_settings_button (5815790345117172504) -->
+ <skip />
<string name="controls_error_timeout" msgid="794197289772728958">"Өшірулі. Қолданба тексеріңіз."</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Қате, әрекет қайталануда…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Табылмады"</string>
- <string name="controls_error_removed_title" msgid="1207794911208047818">"Басқару элементтері қолжетімді емес"</string>
- <string name="controls_error_removed_message" msgid="2885911717034750542">"<xliff:g id="DEVICE">%1$s</xliff:g> ашылмады. Басқару элементтерінің әлі қолжетімді екенін және қолданба параметрлерінің өзгермегенін тексеру үшін <xliff:g id="APPLICATION">%2$s</xliff:g> қолданбасын қараңыз."</string>
+ <string name="controls_error_removed_title" msgid="1207794911208047818">"Басқару виджеті қолжетімсіз"</string>
+ <string name="controls_error_removed_message" msgid="2885911717034750542">"<xliff:g id="DEVICE">%1$s</xliff:g> ашылмады. Басқару виджетінің әлі қолжетімді екенін және қолданба параметрлерінің өзгермегенін тексеру үшін <xliff:g id="APPLICATION">%2$s</xliff:g> қолданбасын қараңыз."</string>
<string name="controls_open_app" msgid="483650971094300141">"Қолданбаны ашу"</string>
<string name="controls_error_generic" msgid="352500456918362905">"Күйді жүктеу мүмкін емес."</string>
<string name="controls_error_failed" msgid="960228639198558525">"Қате шықты. Қайталап көріңіз."</string>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index b0f90e2b2869..bc30c41641c0 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -454,8 +454,10 @@
<string name="notification_tap_again" msgid="4477318164947497249">"ប៉ះ​ម្ដង​ទៀត ដើម្បី​បើក"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"អូសឡើងលើ​ដើម្បីបើក"</string>
<string name="keyguard_retry" msgid="886802522584053523">"អូសឡើងលើ ដើម្បី​ព្យាយាម​ម្ដងទៀត"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"ឧបករណ៍​នេះ​ស្ថិត​ក្រោម​ការ​គ្រប់គ្រង​​របស់ស្ថាប័ន​​អ្នក"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"ឧបករណ៍នេះស្ថិតក្រោមការគ្រប់គ្រងរបស់ <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for do_disclosure_generic (4896482821974707167) -->
+ <skip />
+ <!-- no translation found for do_disclosure_with_name (2091641464065004091) -->
+ <skip />
<string name="phone_hint" msgid="6682125338461375925">"អូសចេញពីរូបតំណាងដើម្បីប្រើទូរស័ព្ទ"</string>
<string name="voice_hint" msgid="7476017460191291417">"អូសចេញពីរូបតំណាងដើម្បីប្រើជំនួយសំឡេង"</string>
<string name="camera_hint" msgid="4519495795000658637">"អូសចេញពីរូបតំណាងដើម្បីប្រើកាមេរ៉ា"</string>
@@ -521,21 +523,33 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"ប្រវត្តិរូបអាចត្រូវបានតាមដាន"</string>
<string name="vpn_footer" msgid="3457155078010607471">"បណ្ដាញ​អាច​ត្រូវ​បាន​ត្រួតពិនិត្យ"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"បណ្ដាញអាចត្រូវបានត្រួតពិនិត្យ"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"ស្ថាប័ន​របស់អ្នក​គ្រប់គ្រង​ឧបករណ៍​នេះ ហើយ​អាចនឹង​តាមដាន​ចរាចរណ៍បណ្តាញ"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> គ្រប់គ្រង​ឧបករណ៍​នេះ ហើយ​អាចនឹង​តាមដាន​ចរាចរណ៍​បណ្តាញ"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"ឧបករណ៍​ស្ថិត​ក្រោម​ការ​គ្រប់គ្រង​របស់ស្ថាប័ន​អ្នក និង​ត្រូវបាន​ភ្ជាប់ទៅ <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"ឧបករណ៍​ស្ថិត​ក្រោម​ការ​គ្រប់គ្រង​របស់ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> និង​ត្រូវបាន​ភ្ជាប់​ទៅ <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"ឧបករណ៍​នេះ​ស្ថិត​ក្រោម​ការ​គ្រប់គ្រង​របស់ស្ថាប័ន​អ្នក"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"ឧបករណ៍​ស្ថិត​ក្រោម​ការ​គ្រប់គ្រង​របស់ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"ឧបករណ៍​ស្ថិត​ក្រោម​ការ​គ្រប់គ្រង​របស់ស្ថាប័ន​អ្នក និង​ត្រូវបាន​តភ្ជាប់​ទៅ VPN"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"ឧបករណ៍​ស្ថិត​ក្រោម​ការ​គ្រប់គ្រង​របស់ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> និង​ត្រូវបាន​ភ្ជាប់​ទៅ VPN"</string>
+ <!-- no translation found for quick_settings_disclosure_management_monitoring (8231336875820702180) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_monitoring (2831423806103479812) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_named_vpn (6096715329056415588) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (5302786161534380104) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management (5515296598440684962) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management (3476472755775165827) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_vpns (371835422690053154) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_vpns (4046375645500668555) -->
+ <skip />
<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_monitoring" msgid="8548019955631378680">"បណ្ដាញ​អាច​ត្រូវ​តាមដាន"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"ឧបករណ៍​ត្រូវបាន​ភ្ជាប់​ទៅ VPN"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"កម្រងព័ត៌មាន​ការងារ​ត្រូវបាន​ភ្ជាប់ទៅ <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"កម្រងព័ត៌មាន​ផ្ទាល់ខ្លួន​ត្រូវបាន​ភ្ជាប់​ទៅ <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"ឧបករណ៍​ត្រូវបាន​ភ្ជាប់​ទៅ <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <!-- no translation found for quick_settings_disclosure_vpns (7213546797022280246) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (8117568745060010789) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (5481763430080807797) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_vpn (2350838218824492465) -->
+ <skip />
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"ការ​គ្រប់គ្រង​ឧបករណ៍"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"តាមដានប្រវត្ថិរូប"</string>
<string name="monitoring_title" msgid="4063890083735924568">"ការ​ត្រួតពិនិត្យ​បណ្ដាញ"</string>
@@ -545,8 +559,10 @@
<string name="disable_vpn" msgid="482685974985502922">"បិទ VPN"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"ផ្ដាច់ VPN"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"មើល​គោលការណ៍"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"ឧបករណ៍​របស់អ្នក​ស្ថិត​ក្រោម​ការ​គ្រប់គ្រង​របស់ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>។\n\nអ្នក​គ្រប់គ្រង​របស់អ្នក​អាចតាមដាន និង​គ្រប់គ្រង​ការកំណត់ ការចូលប្រើជាលក្ខណៈក្រុមហ៊ុន កម្មវិធី ទិន្នន័យ​ដែលពាក់ព័ន្ធ​នឹង​ឧបករណ៍​របស់អ្នក និង​ព័ត៌មាន​ទីតាំង​នៃឧបករណ៍​របស់​អ្នក។\n\nសម្រាប់​ព័ត៌មាន​បន្ថែម សូម​ទាក់ទងអ្នក​គ្រប់គ្រង​របស់​អ្នក។"</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"ឧបករណ៍​របស់អ្នក​ស្ថិត​ក្រោម​ការ​គ្រប់គ្រង​របស់ស្ថាប័ន​អ្នក។\n\nអ្នក​គ្រប់គ្រង​របស់អ្នក​អាចតាមដាន និង​គ្រប់គ្រង​ការកំណត់ ការចូលប្រើជាលក្ខណៈក្រុមហ៊ុន កម្មវិធី ទិន្នន័យ​ដែលពាក់ព័ន្ធ​នឹង​ឧបករណ៍​របស់អ្នក និង​ព័ត៌មាន​ទីតាំង​នៃឧបករណ៍​របស់​អ្នក។\n\nសម្រាប់​ព័ត៌មាន​បន្ថែម សូម​ទាក់ទង​អ្នក​គ្រប់គ្រង​របស់​អ្នក។"</string>
+ <!-- no translation found for monitoring_description_named_management (505833016545056036) -->
+ <skip />
+ <!-- no translation found for monitoring_description_management (4308879039175729014) -->
+ <skip />
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"ស្ថាប័ន​របស់អ្នក​បានដំឡើង​អាជ្ញាធរវិញ្ញាបនបត្រនៅលើ​ឧបករណ៍​នេះ។ ចរាចរណ៍​បណ្តាញដែលមាន​សុវត្ថិភាព​របស់អ្នក​អាច​ត្រូវបាន​តាមដាន ឬ​កែសម្រួល។"</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"ស្ថាប័នរបស់អ្នក​បានដំឡើង​អាជ្ញាធរវិញ្ញាបនបត្រ​នៅក្នុង​កម្រងព័ត៌មាន​ការងារ។ ចរាចរណ៍​បណ្តាញដែលមាន​សុវត្ថិភាព​របស់អ្នក​អាច​ត្រូវបាន​តាមដាន ឬ​កែសម្រួល។"</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"បាន​ដំឡើង​អាជ្ញាធរវិញ្ញាបនបត្រ​នៅលើ​ឧបករណ៍​នេះ។ ចរាចរណ៍​បណ្តាញដែលមានសុវត្ថិភាព​របស់អ្នក​អាច​ត្រូវបាន​តាមដាន ឬ​កែសម្រួល។"</string>
@@ -920,6 +936,7 @@
<string name="pip_pause" msgid="1139598607050555845">"ផ្អាក"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"រំលងទៅបន្ទាប់"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"រំលងទៅក្រោយ"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"ប្ដូរ​ទំហំ"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"ទូរសព្ទ​បាន​បិទដោយសារ​វា​ឡើងកម្តៅ"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"ឥឡូវនេះ​ទូរសព្ទ​របស់អ្នក​កំពុង​ដំណើរការ​ធម្មតា"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"ទូរសព្ទ​របស់អ្នក​ក្តៅពេក ដូច្នេះ​វាបាន​បិទ​ដើម្បី​បន្ថយ​កម្តៅ។ ឥឡូវនេះ ​ទូរសព្ទ​របស់អ្នក​កំពុង​ដំណើរការ​ធម្មតា។\n\nទូរសព្ទ​របស់អ្នក​អាចនឹង​ឡើង​កម្តៅ​ខ្លាំងជ្រុល ប្រសិន​បើអ្នក៖\n • ប្រើប្រាស់​កម្មវិធី​ដែល​ប្រើប្រាស់ទិន្នន័យច្រើនក្នុងរយៈពេលខ្លី (ដូចជាហ្គេម វីដេអូ ឬកម្មវិធីរុករក)\n • ទាញយក ឬ​បង្ហោះ​ឯកសារដែលមានទំហំធំ\n • ប្រើប្រាស់​ទូរសព្ទ​របស់អ្នក​នៅកន្លែង​មានសីតុណ្ហភាព​ខ្ពស់"</string>
@@ -1045,7 +1062,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"ចុច​ឱ្យ​ជាប់ រួចអូស​ដើម្បី​រៀបចំ​ផ្ទាំងគ្រប់គ្រង​ឡើងវិញ"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"បាន​ដកផ្ទាំងគ្រប់គ្រងទាំងអស់ហើយ"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"មិនបាន​រក្សាទុក​ការផ្លាស់ប្ដូរទេ"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"មិនអាច​ផ្ទុក​បញ្ជី​នៃការគ្រប់គ្រង​ទាំងអស់​បានទេ។"</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"មិនអាចផ្ទុក​ការគ្រប់គ្រង​បានទេ។ សូមពិនិត្យមើល​កម្មវិធី <xliff:g id="APP">%s</xliff:g> ដើម្បីធ្វើឱ្យប្រាកដថា​ការកំណត់កម្មវិធី​មិនបានផ្លាស់ប្ដូរ។"</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"មិនអាចប្រើ​ការគ្រប់គ្រង​ដែលត្រូវគ្នា​បានទេ"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"ផ្សេងៗ"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"បញ្ចូល​ទៅក្នុងផ្ទាំងគ្រប់គ្រងឧបករណ៍"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"បញ្ចូល"</string>
@@ -1061,8 +1079,15 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"បញ្ជាក់​ការផ្លាស់ប្ដូរ​សម្រាប់ <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"អូសដើម្បី​មើលច្រើនទៀត"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"កំពុងផ្ទុក​ការណែនាំ"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"បិទវគ្គ​មេឌៀ​នេះ"</string>
+ <!-- no translation found for controls_media_title (1746947284862928133) -->
+ <skip />
+ <!-- no translation found for controls_media_close_session (3957093425905475065) -->
+ <skip />
+ <!-- no translation found for controls_media_dismiss_button (4485675693008031646) -->
+ <skip />
<string name="controls_media_resume" msgid="1933520684481586053">"បន្ត"</string>
+ <!-- no translation found for controls_media_settings_button (5815790345117172504) -->
+ <skip />
<string name="controls_error_timeout" msgid="794197289772728958">"អសកម្ម ពិនិត្យមើល​កម្មវិធី"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"បញ្ហា កំពុងព្យាយាម​ម្ដងទៀត…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"រកមិន​ឃើញទេ"</string>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index ed5342554913..73461f31efa9 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -454,8 +454,8 @@
<string name="notification_tap_again" msgid="4477318164947497249">"ತೆರೆಯಲು ಮತ್ತೆ ಟ್ಯಾಪ್‌ ಮಾಡಿ"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"ತೆರೆಯಲು ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ"</string>
<string name="keyguard_retry" msgid="886802522584053523">"ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಲು ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"ಈ ಸಾಧನವನ್ನು ನಿಮ್ಮ ಸಂಸ್ಥೆ ನಿರ್ವಹಿಸುತ್ತಿದೆ"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"ಈ ಸಾಧನವನ್ನು <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ರಿಂದ ನಿರ್ವಹಿಸಲಾಗಿದೆ"</string>
+ <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="phone_hint" msgid="6682125338461375925">"ಫೋನ್‌ಗಾಗಿ ಐಕಾನ್‌ನಿಂದ ಸ್ವೈಪ್ ಮಾಡಿ"</string>
<string name="voice_hint" msgid="7476017460191291417">"ಧ್ವನಿ ಸಹಾಯಕ್ಕಾಗಿ ಐಕಾನ್‌ನಿಂದ ಸ್ವೈಪ್ ಮಾಡಿ"</string>
<string name="camera_hint" msgid="4519495795000658637">"ಕ್ಯಾಮರಾಗಾಗಿ ಐಕಾನ್‌ನಿಂದ ಸ್ವೈಪ್ ಮಾಡಿ"</string>
@@ -510,8 +510,7 @@
<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>
- <!-- no translation found for notification_section_header_incoming (850925217908095197) -->
- <skip />
+ <string name="notification_section_header_incoming" msgid="850925217908095197">"ಹೊಸತು"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"ನಿಶ್ಶಬ್ದ"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"ಅಧಿಸೂಚನೆಗಳು"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"ಸಂಭಾಷಣೆಗಳು"</string>
@@ -522,21 +521,21 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"ಪ್ರೊಫೈಲ್ ಅನ್ನು ಪರಿವೀಕ್ಷಿಸಬಹುದಾಗಿದೆ"</string>
<string name="vpn_footer" msgid="3457155078010607471">"ನೆಟ್‌ವರ್ಕ್ ಅನ್ನು ವೀಕ್ಷಿಸಬಹುದಾಗಿ"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"ನೆಟ್‌ವರ್ಕ್ ಅನ್ನು ವೀಕ್ಷಿಸಬಹುದಾಗಿರುತ್ತದೆ"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"ನಿಮ್ಮ ಸಂಸ್ಥೆಯು ಈ ಸಾಧನವನ್ನು ನಿರ್ವಹಿಸುತ್ತದೆ ಮತ್ತು ಅದು ನೆಟ್‌ವರ್ಕ್ ಟ್ರಾಫಿಕ್ ಅನ್ನು ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಬಹುದು"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"ಈ ಸಾಧನವನ್ನು <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ನಿರ್ವಹಿಸುತ್ತಿದೆ ಮತ್ತು ಅದು ನೆಟ್‌ವರ್ಕ್ ಟ್ರಾಫಿಕ್‌ನ ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಬಹುದು"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"ಸಾಧನವನ್ನು ನಿಮ್ಮ ಸಂಸ್ಥೆಯು ನಿರ್ವಹಿಸುತ್ತದೆ ಮತ್ತು ಅದನ್ನು <xliff:g id="VPN_APP">%1$s</xliff:g> ಗೆ ಸಂಪರ್ಕಪಡಿಸಲಾಗಿದೆ"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"ಸಾಧನವನ್ನು <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ನಿರ್ವಹಿಸುತ್ತಿದೆ ಮತ್ತು ಅದನ್ನು <xliff:g id="VPN_APP">%2$s</xliff:g> ಗೆ ಸಂಪರ್ಕಪಡಿಸಲಾಗಿದೆ"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"ನಿಮ್ಮ ಸಂಸ್ಥೆಯು ಸಾಧನವನ್ನು ನಿರ್ವಹಿಸುತ್ತದೆ"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"ಸಾಧನವನ್ನು <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ನಿರ್ವಹಿಸುತ್ತಿದೆ"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"ಸಾಧನವನ್ನು ನಿಮ್ಮ ಸಂಸ್ಥೆಯು ನಿರ್ವಹಿಸುತ್ತದೆ ಮತ್ತು ಅದನ್ನು VPN ಗಳಿಗೆ ಸಂಪರ್ಕಪಡಿಸಲಾಗಿದೆ"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"ಸಾಧನವನ್ನು <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ನಿರ್ವಹಿಸುತ್ತಿದೆ ಮತ್ತು ಅದನ್ನು VPN ಗಳಿಗೆ ಸಂಪರ್ಕಪಡಿಸಲಾಗಿದೆ"</string>
+ <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"ನಿಮ್ಮ ಸಂಸ್ಥೆಯು ಈ ಸಾಧನದ ಮಾಲೀಕತ್ವವನ್ನು ಹೊಂದಿದೆ ಮತ್ತು ಅದು ನೆಟ್‌ವರ್ಕ್ ಟ್ರಾಫಿಕ್‌ನ ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಬಹುದು"</string>
+ <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ಈ ಸಾಧನದ ಮಾಲೀಕತ್ವವನ್ನು ಹೊಂದಿದೆ ಮತ್ತು ಅದು ನೆಟ್‌ವರ್ಕ್ ಟ್ರಾಫಿಕ್‌ನ ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಬಹುದು"</string>
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"ಈ ಸಾಧನವು ನಿಮ್ಮ ಸಂಸ್ಥೆಗೆ ಸೇರಿದೆ ಮತ್ತು <xliff:g id="VPN_APP">%1$s</xliff:g> ಗೆ ಕನೆಕ್ಟ್ ಆಗಿದೆ"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"ಈ ಸಾಧನವು <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ಗೆ ಸೇರಿದೆ ಮತ್ತು <xliff:g id="VPN_APP">%2$s</xliff:g> ಗೆ ಕನೆಕ್ಟ್ ಆಗಿದೆ"</string>
+ <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"ಈ ಸಾಧನವು ನಿಮ್ಮ ಸಂಸ್ಥೆಗೆ ಸೇರಿದೆ"</string>
+ <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"ಈ ಸಾಧನವು <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ಗೆ ಸೇರಿದೆ"</string>
+ <string name="quick_settings_disclosure_management_vpns" msgid="371835422690053154">"ಈ ಸಾಧನವು ನಿಮ್ಮ ಸಂಸ್ಥೆಗೆ ಸೇರಿದೆ ಮತ್ತು VPN ಗಳಿಗೆ ಕನೆಕ್ಟ್ ಆಗಿದೆ"</string>
+ <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_monitoring" msgid="8548019955631378680">"ನೆಟ್‌ವರ್ಕ್‌ನ ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಬಹುದಾಗಿದೆ"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"ಸಾಧನವನ್ನು VPN ಗಳಿಗೆ ಸಂಪರ್ಕಪಡಿಸಲಾಗಿದೆ"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"ಉದ್ಯೋಗ ಪ್ರೊಫೈಲ್‌ ಅನ್ನು <xliff:g id="VPN_APP">%1$s</xliff:g> ಗೆ ಸಂಪರ್ಕಪಡಿಸಲಾಗಿದೆ"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"ವೈಯಕ್ತಿಕ ಪ್ರೊಫೈಲ್ ಅನ್ನು <xliff:g id="VPN_APP">%1$s</xliff:g> ಗೆ ಸಂಪರ್ಕಪಡಿಸಲಾಗಿದೆ"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"<xliff:g id="VPN_APP">%1$s</xliff:g> ಗೆ ಸಾಧನವನ್ನು ಸಂಪರ್ಕಪಡಿಸಲಾಗಿದೆ"</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>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"ನಿಮ್ಮ ವೈಯಕ್ತಿಕ ಪ್ರೊಫೈಲ್ <xliff:g id="VPN_APP">%1$s</xliff:g> ಗೆ ಕನೆಕ್ಟ್ ಆಗಿದೆ"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"ಈ ಸಾಧನವು <xliff:g id="VPN_APP">%1$s</xliff:g> ಗೆ ಕನೆಕ್ಟ್ ಆಗಿದೆ"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"ಸಾಧನ ನಿರ್ವಹಣೆ"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"ಪ್ರೊಫೈಲ್ ಮೇಲ್ವಿಚಾರಣೆ"</string>
<string name="monitoring_title" msgid="4063890083735924568">"ನೆಟ್‌ವರ್ಕ್‌ ಪರಿವೀಕ್ಷಣೆ"</string>
@@ -546,8 +545,8 @@
<string name="disable_vpn" msgid="482685974985502922">"VPN ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"VPN ಸಂಪರ್ಕಕಡಿತಗೊಳಿಸಿ"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"ಕಾರ್ಯನೀತಿಗಳನ್ನು ವೀಕ್ಷಿಸಿ"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"ನಿಮ್ಮ ಸಾಧನವನ್ನು <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ನಿರ್ವಹಿಸುತ್ತಿದೆ.\n\nಸೆಟ್ಟಿಂಗ್‌ಗಳು, ಕಾರ್ಪೊರೇಟ್ ಪ್ರವೇಶ, ಅಪ್ಲಿಕೇಶನ್‌ಗಳು, ನಿಮ್ಮ ಸಾಧನಕ್ಕೆ ಸಂಬಂಧಿಸಿದ ಡೇಟಾ ಮತ್ತು ನಿಮ್ಮ ಸಾಧನದ ಸ್ಥಳ ಮಾಹಿತಿಯನ್ನು ನಿಮ್ಮ ನಿರ್ವಾಹಕರು ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಬಹುದು ಮತ್ತು ನಿರ್ವಹಿಸಬಹುದು.\n\nಹೆಚ್ಚಿನ ಮಾಹಿತಿಗಾಗಿ, ನಿಮ್ಮ ನಿರ್ವಾಹಕರನ್ನು ಸಂಪರ್ಕಿಸಿ."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"ನಿಮ್ಮ ಸಾಧನವನ್ನು ನಿಮ್ಮ ಸಂಸ್ಥೆಯು ನಿರ್ವಹಿಸುತ್ತಿದೆ.\n\nಸೆಟ್ಟಿಂಗ್‌ಗಳು, ಕಾರ್ಪೊರೇಟ್ ಪ್ರವೇಶ, ಅಪ್ಲಿಕೇಶನ್‌ಗಳು, ನಿಮ್ಮ ಸಾಧನಕ್ಕೆ ಸಂಬಂಧಿಸಿದ ಡೇಟಾ, ಮತ್ತು ನಿಮ್ಮ ಸಾಧನದ ಸ್ಥಳ ಮಾಹಿತಿಯನ್ನು ನಿಮ್ಮ ನಿರ್ವಾಹಕರು ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಬಹುದು ಮತ್ತು ನಿರ್ವಹಿಸಬಹುದು.\n\nಹೆಚ್ಚಿನ ಮಾಹಿತಿಗಾಗಿ, ನಿಮ್ಮ ನಿರ್ವಾಹಕರನ್ನು ಸಂಪರ್ಕಿಸಿ."</string>
+ <string name="monitoring_description_named_management" msgid="505833016545056036">"ಈ ಸಾಧನವು <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ಗೆ ಸೇರಿದೆ.\n\nಸೆಟ್ಟಿಂಗ್‌ಗಳು, ಕಾರ್ಪೊರೇಟ್ ಪ್ರವೇಶ, ಆ್ಯಪ್‌ಗಳು, ನಿಮ್ಮ ಸಾಧನಕ್ಕೆ ಸಂಬಂಧಿಸಿದ ಡೇಟಾ ಮತ್ತು ನಿಮ್ಮ ಸಾಧನದ ಸ್ಥಳದ ಮಾಹಿತಿಯನ್ನು ನಿಮ್ಮ IT ನಿರ್ವಾಹಕರು ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಬಹುದು ಮತ್ತು ನಿರ್ವಹಿಸಬಹುದು.\n\nಹೆಚ್ಚಿನ ಮಾಹಿತಿಗಾಗಿ ನಿಮ್ಮ IT ನಿರ್ವಾಹಕರನ್ನು ಸಂಪರ್ಕಿಸಿ."</string>
+ <string name="monitoring_description_management" msgid="4308879039175729014">"ಈ ಸಾಧನವು ನಿಮ್ಮ ಸಂಸ್ಥೆಗೆ ಸೇರಿದೆ.\n\nಸೆಟ್ಟಿಂಗ್‌ಗಳು, ಕಾರ್ಪೊರೇಟ್ ಪ್ರವೇಶ, ಆ್ಯಪ್‌ಗಳು, ನಿಮ್ಮ ಸಾಧನಕ್ಕೆ ಸಂಬಂಧಿಸಿದ ಡೇಟಾ ಮತ್ತು ನಿಮ್ಮ ಸಾಧನದ ಸ್ಥಳದ ಮಾಹಿತಿಯನ್ನು ನಿಮ್ಮ IT ನಿರ್ವಾಹಕರು ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಬಹುದು ಮತ್ತು ನಿರ್ವಹಿಸಬಹುದು.\n\nಹೆಚ್ಚಿನ ಮಾಹಿತಿಗಾಗಿ ನಿಮ್ಮ IT ನಿರ್ವಾಹಕರನ್ನು ಸಂಪರ್ಕಿಸಿ."</string>
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"ನಿಮ್ಮ ಸಂಸ್ಥೆಯು ಈ ಸಾಧನದಲ್ಲಿ ಪ್ರಮಾಣಪತ್ರ ಅಂಗೀಕಾರವನ್ನು ಸ್ಥಾಪಿಸಿದೆ. ನಿಮ್ಮ ಸುರಕ್ಷಿತ ನೆಟ್‌ವರ್ಕ್ ಟ್ರಾಫಿಕ್ ಅನ್ನು ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಬಹುದು ಅಥವಾ ಮಾರ್ಪಡಿಸಬಹುದು."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"ನಿಮ್ಮ ಸಂಸ್ಥೆಯು ನಿಮ್ಮ ಉದ್ಯೋಗ ಪ್ರೊಫೈಲ್‌ನಲ್ಲಿ ಪ್ರಮಾಣಪತ್ರ ಅಂಗೀಕಾರವನ್ನು ಸ್ಥಾಪಿಸಿದೆ. ನಿಮ್ಮ ಸುರಕ್ಷಿತ ನೆಟ್‌ವರ್ಕ್ ಟ್ರಾಫಿಕ್ ಅನ್ನು ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಬಹುದು ಅಥವಾ ಮಾರ್ಪಡಿಸಬಹುದು."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"ಈ ಸಾಧನದಲ್ಲಿ ಪ್ರಮಾಣಪತ್ರ ಅಂಗೀಕಾರವನ್ನು ಸ್ಥಾಪಿಸಲಾಗಿದೆ. ನಿಮ್ಮ ಸುರಕ್ಷಿತ ನೆಟ್‌ವರ್ಕ್ ಟ್ರಾಫಿಕ್ ಅನ್ನು ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಬಹುದು ಅಥವಾ ಮಾರ್ಪಡಿಸಬಹುದು."</string>
@@ -921,6 +920,7 @@
<string name="pip_pause" msgid="1139598607050555845">"ವಿರಾಮಗೊಳಿಸಿ"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"ಮುಂದಕ್ಕೆ ಸ್ಕಿಪ್‌ ಮಾಡಿ"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"ಹಿಂದಕ್ಕೆ ಸ್ಕಿಪ್‌ ಮಾಡಿ"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"ಮರುಗಾತ್ರಗೊಳಿಸಿ"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"ಫೋನ್ ಬಿಸಿಯಾಗಿದ್ದರಿಂದ ಆಫ್ ಆಗಿದೆ"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"ಈಗ ನಿಮ್ಮ ಫೋನ್ ಎಂದಿನಂತೆ ಕೆಲಸ ಮಾಡುತ್ತಿದೆ"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"ನಿಮ್ಮ ಫೋನ್ ತುಂಬಾ ಬಿಸಿಯಾಗಿತ್ತು, ತಣ್ಣಗಾಗಲು ಅದು ತಾನಾಗಿ ಆಫ್ ಆಗಿದೆ. ಈಗ ನಿಮ್ಮ ಫೋನ್ ಎಂದಿನಂತೆ ಕೆಲಸ ಮಾಡುತ್ತಿದೆ.\n\nನಿಮ್ಮ ಫೋನ್ ಬಿಸಿಯಾಗಲು ಕಾರಣಗಳು:\n • ಹೆಚ್ಚು ಸಂಪನ್ಮೂಲ ಉಪಯೋಗಿಸುವ ಅಪ್ಲಿಕೇಶನ್‌ಗಳ ಬಳಕೆ (ಉದಾ, ಗೇಮಿಂಗ್, ವೀಡಿಯೊ/ನ್ಯಾವಿಗೇಶನ್ ಅಪ್ಲಿಕೇಶನ್‌ಗಳು)\n • ದೊಡ್ಡ ಫೈಲ್‌ಗಳ ಡೌನ್‌ಲೋಡ್ ಅಥವಾ ಅಪ್‌ಲೋಡ್\n • ಅಧಿಕ ಉಷ್ಣಾಂಶದಲ್ಲಿ ಫೋನಿನ ಬಳಕೆ"</string>
@@ -1046,7 +1046,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"ನಿಯಂತ್ರಣಗಳನ್ನು ಮರುಹೊಂದಿಸಲು ಹೋಲ್ಡ್ ಮಾಡಿ ಮತ್ತು ಡ್ರ್ಯಾಗ್‌ ಮಾಡಿ"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"ಎಲ್ಲಾ ನಿಯಂತ್ರಣಗಳನ್ನು ತೆಗೆದುಹಾಕಲಾಗಿದೆ"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"ಬದಲಾವಣೆಗಳನ್ನು ಉಳಿಸಲಾಗಿಲ್ಲ"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"ಎಲ್ಲಾ ನಿಯಂತ್ರಣಗಳ ಪಟ್ಟಿಯನ್ನು ಲೋಡ್ ಮಾಡಲು ಆಗಲಿಲ್ಲ."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"ನಿಯಂತ್ರಣಗಳನ್ನು ಲೋಡ್ ಮಾಡಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ. ಆ್ಯಪ್ ಸೆಟ್ಟಿಂಗ್‌ಗಳು ಬದಲಾಗಿಲ್ಲ ಎಂದು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಲು <xliff:g id="APP">%s</xliff:g> ಆ್ಯಪ್ ಅನ್ನು ಪರಿಶೀಲಿಸಿ."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"ಹೊಂದಾಣಿಕೆಯ ನಿಯಂತ್ರಣಗಳು ಲಭ್ಯವಿಲ್ಲ"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"ಇತರ"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"ಸಾಧನ ನಿಯಂತ್ರಣಗಳಿಗೆ ಸೇರಿಸಿ"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"ಸೇರಿಸಿ"</string>
@@ -1062,8 +1063,11 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"<xliff:g id="DEVICE">%s</xliff:g> ಸಾಧನಕ್ಕಾಗಿ ಬದಲಾವಣೆಯನ್ನು ದೃಢೀಕರಿಸಿ"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"ಇನ್ನಷ್ಟು ನೋಡಲು ಸ್ವೈಪ್ ಮಾಡಿ"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"ಶಿಫಾರಸುಗಳು ಲೋಡ್ ಆಗುತ್ತಿವೆ"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"ಈ ಮಾಧ್ಯಮ ಸೆಶನ್ ಅನ್ನು ಮುಚ್ಚಿರಿ"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"ಮಾಧ್ಯಮ"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"ಪ್ರಸ್ತುತ ಸೆಶನ್ ಅನ್ನು ಮರೆಮಾಡಿ."</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"ಮರೆಮಾಡಿ"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"ಪುನರಾರಂಭಿಸಿ"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"ನಿಷ್ಕ್ರಿಯ, ಆ್ಯಪ್ ಪರಿಶೀಲಿಸಿ"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"ದೋಷ, ಮರುಪ್ರಯತ್ನಿಸಲಾಗುತ್ತಿದೆ…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"ಕಂಡುಬಂದಿಲ್ಲ"</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index a27f4f723a0c..23831b1f21de 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -454,8 +454,10 @@
<string name="notification_tap_again" msgid="4477318164947497249">"다시 탭하여 열기"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"위로 스와이프하여 열기"</string>
<string name="keyguard_retry" msgid="886802522584053523">"위로 스와이프하여 다시 시도해 주세요"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"조직에서 관리하는 기기입니다."</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>에서 관리하는 기기입니다."</string>
+ <!-- no translation found for do_disclosure_generic (4896482821974707167) -->
+ <skip />
+ <!-- no translation found for do_disclosure_with_name (2091641464065004091) -->
+ <skip />
<string name="phone_hint" msgid="6682125338461375925">"전화 기능을 사용하려면 아이콘에서 스와이프하세요."</string>
<string name="voice_hint" msgid="7476017460191291417">"음성 지원을 사용하려면 아이콘에서 스와이프하세요."</string>
<string name="camera_hint" msgid="4519495795000658637">"카메라를 사용하려면 아이콘에서 스와이프하세요."</string>
@@ -521,21 +523,33 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"프로필이 모니터링될 수 있음"</string>
<string name="vpn_footer" msgid="3457155078010607471">"네트워크가 모니터링될 수 있음"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"네트워크가 모니터링될 수 있음"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"조직에서 이 기기를 관리하며 네트워크 트래픽을 모니터링할 수 있습니다."</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>에서 관리하는 기기이며 네트워크 트래픽을 모니터링할 수 있습니다."</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"조직에서 관리하는 기기이며 <xliff:g id="VPN_APP">%1$s</xliff:g>에 연결되어 있습니다."</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>에서 관리하는 기기이며 <xliff:g id="VPN_APP">%2$s</xliff:g>에 연결되어 있습니다."</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"조직에서 기기를 관리합니다."</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>에서 관리하는 기기입니다."</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"조직에서 관리하는 기기이며 VPN에 연결되어 있습니다."</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>에서 관리하는 기기이며 VPN에 연결되어 있습니다."</string>
+ <!-- no translation found for quick_settings_disclosure_management_monitoring (8231336875820702180) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_monitoring (2831423806103479812) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_named_vpn (6096715329056415588) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (5302786161534380104) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management (5515296598440684962) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management (3476472755775165827) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_vpns (371835422690053154) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_vpns (4046375645500668555) -->
+ <skip />
<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_monitoring" msgid="8548019955631378680">"네트워크가 모니터링될 수 있습니다."</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"기기가 VPN에 연결되어 있습니다."</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"직장 프로필이 <xliff:g id="VPN_APP">%1$s</xliff:g>에 연결되었습니다."</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"개인 프로필이 <xliff:g id="VPN_APP">%1$s</xliff:g>에 연결되어 있습니다."</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"기기가 <xliff:g id="VPN_APP">%1$s</xliff:g>에 연결되어 있습니다."</string>
+ <!-- no translation found for quick_settings_disclosure_vpns (7213546797022280246) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (8117568745060010789) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (5481763430080807797) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_vpn (2350838218824492465) -->
+ <skip />
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"기기 관리"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"프로필 모니터링"</string>
<string name="monitoring_title" msgid="4063890083735924568">"네트워크 모니터링"</string>
@@ -545,8 +559,10 @@
<string name="disable_vpn" msgid="482685974985502922">"VPN 사용 중지"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"VPN 연결 해제"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"정책 보기"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>에서 관리하는 기기입니다.\n\n관리자는 설정, 기업 액세스, 앱, 기기와 관련된 데이터 및 기기의 위치 정보를 모니터링하고 관리할 수 있습니다.\n\n자세한 내용은 관리자에게 문의하세요."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"조직에서 관리하는 기기입니다.\n\n관리자는 설정, 기업 액세스, 앱, 기기와 관련된 데이터 및 기기의 위치 정보를 모니터링하고 관리할 수 있습니다.\n\n자세한 내용은 관리자에게 문의하세요."</string>
+ <!-- no translation found for monitoring_description_named_management (505833016545056036) -->
+ <skip />
+ <!-- no translation found for monitoring_description_management (4308879039175729014) -->
+ <skip />
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"조직에서 이 기기에 인증기관을 설치했습니다. 보안 네트워크 트래픽을 모니터링 또는 수정할 수 있습니다."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"조직에서 직장 프로필에 인증기관을 설치했습니다. 보안 네트워크 트래픽을 모니터링 또는 수정할 수 있습니다."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"이 기기에는 인증기관이 설치되어 있습니다. 보안 네트워크 트래픽을 모니터링 또는 수정할 수 있습니다."</string>
@@ -920,6 +936,7 @@
<string name="pip_pause" msgid="1139598607050555845">"일시중지"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"다음으로 건너뛰기"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"이전으로 건너뛰기"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"크기 조절"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"발열로 인해 휴대전화 전원이 종료됨"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"휴대전화가 정상적으로 실행 중입니다."</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"휴대전화가 과열되어 온도를 낮추기 위해 전원이 종료되었습니다. 지금은 휴대전화가 정상적으로 실행 중입니다.\n\n휴대전화가 과열되는 이유는 다음과 같습니다.\n • 리소스를 많이 사용하는 앱 사용(예: 게임, 동영상 또는 내비게이션 앱)\n • 대용량 파일을 다운로드 또는 업로드\n • 온도가 높은 곳에서 휴대폰 사용"</string>
@@ -1003,7 +1020,7 @@
<string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"왼쪽 하단으로 이동"</string>
<string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"오른쪽 하단으로 이동"</string>
<string name="bubble_dismiss_text" msgid="1314082410868930066">"대화창 닫기"</string>
- <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"대화를 대화창으로 표시하지 않음"</string>
+ <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"대화를 대화창으로 표시하지 않기"</string>
<string name="bubbles_user_education_title" msgid="5547017089271445797">"대화창으로 채팅하기"</string>
<string name="bubbles_user_education_description" msgid="1160281719576715211">"새로운 대화가 플로팅 아이콘인 대화창으로 표시됩니다. 대화창을 열려면 탭하세요. 드래그하여 이동할 수 있습니다."</string>
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"언제든지 대화창을 제어하세요"</string>
@@ -1014,7 +1031,7 @@
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"설정으로 이동하여 시스템 탐색을 업데이트하세요."</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"대기"</string>
<string name="priority_onboarding_title" msgid="2893070698479227616">"대화가 우선순위 대화로 설정됨"</string>
- <string name="priority_onboarding_behavior" msgid="5342816047020432929">"우선순위 대화에서 다음과 같은 동작을 합니다."</string>
+ <string name="priority_onboarding_behavior" msgid="5342816047020432929">"우선순위 대화는 다음과 같이 표시됩니다."</string>
<string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"대화 섹션의 상단에 표시"</string>
<string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"잠금 화면에서 프로필 사진 표시"</string>
<string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"앱 상단에서 플로팅 대화창으로 표시"</string>
@@ -1025,7 +1042,7 @@
<string name="magnification_window_title" msgid="4863914360847258333">"확대 창"</string>
<string name="magnification_controls_title" msgid="8421106606708891519">"확대 창 컨트롤"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"기기 컨트롤"</string>
- <string name="quick_controls_subtitle" msgid="1667408093326318053">"연결된 기기의 컨트롤을 추가합니다."</string>
+ <string name="quick_controls_subtitle" msgid="1667408093326318053">"연결된 기기의 컨트롤을 추가하세요."</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"기기 컨트롤 설정"</string>
<string name="quick_controls_setup_subtitle" msgid="1681506617879773824">"전원 버튼을 길게 눌러 컨트롤에 액세스하세요."</string>
<string name="controls_providers_title" msgid="6879775889857085056">"컨트롤을 추가할 앱을 선택하세요"</string>
@@ -1045,7 +1062,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"길게 누르고 드래그하여 컨트롤 재정렬"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"모든 컨트롤 삭제됨"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"변경사항이 저장되지 않음"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"전체 컨트롤 목록을 로드할 수 없습니다."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"컨트롤을 로드할 수 없습니다. <xliff:g id="APP">%s</xliff:g> 앱에서 설정이 변경되지 않았는지 확인하세요."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"호환 컨트롤을 사용할 수 없습니다."</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"기타"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"기기 컨트롤에 추가"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"추가"</string>
@@ -1061,13 +1079,20 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"<xliff:g id="DEVICE">%s</xliff:g> 변경 확인"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"자세히 보려면 스와이프하세요."</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"추천 제어 기능 로드 중"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"이 미디어 세션 닫기"</string>
+ <!-- no translation found for controls_media_title (1746947284862928133) -->
+ <skip />
+ <!-- no translation found for controls_media_close_session (3957093425905475065) -->
+ <skip />
+ <!-- no translation found for controls_media_dismiss_button (4485675693008031646) -->
+ <skip />
<string name="controls_media_resume" msgid="1933520684481586053">"다시 시작"</string>
+ <!-- no translation found for controls_media_settings_button (5815790345117172504) -->
+ <skip />
<string name="controls_error_timeout" msgid="794197289772728958">"비활성. 앱을 확인하세요."</string>
<string name="controls_error_retryable" msgid="864025882878378470">"오류 발생, 다시 시도 중…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"찾을 수 없음"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"컨트롤을 사용할 수 없음"</string>
- <string name="controls_error_removed_message" msgid="2885911717034750542">"<xliff:g id="DEVICE">%1$s</xliff:g>에 액세스할 수 없습니다. <xliff:g id="APPLICATION">%2$s</xliff:g> 앱에서 컨트롤을 계속 사용할 수 있는지와 앱 설정이 변경되지 않았는지 확인하세요."</string>
+ <string name="controls_error_removed_message" msgid="2885911717034750542">"<xliff:g id="DEVICE">%1$s</xliff:g>에 액세스할 수 없습니다. <xliff:g id="APPLICATION">%2$s</xliff:g> 앱에서 컨트롤을 계속 사용할 수 있는지, 앱 설정이 변경되지는 않았는지 확인하세요."</string>
<string name="controls_open_app" msgid="483650971094300141">"앱 열기"</string>
<string name="controls_error_generic" msgid="352500456918362905">"통계를 로드할 수 없음"</string>
<string name="controls_error_failed" msgid="960228639198558525">"오류. 다시 시도하세요."</string>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index 74f43e870da7..5fc2b7d280b2 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -454,8 +454,10 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Ачуу үчүн кайра таптап коюңуз"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Ачуу үчүн өйдө сүрүңүз"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Кайталоо үчүн экранды өйдө сүрүңүз"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"Бул түзмөк уюмуңуз тарабынан башкарылат"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"Бул түзмөк <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> тарабынан башкарылат"</string>
+ <!-- no translation found for do_disclosure_generic (4896482821974707167) -->
+ <skip />
+ <!-- no translation found for do_disclosure_with_name (2091641464065004091) -->
+ <skip />
<string name="phone_hint" msgid="6682125338461375925">"Сүрөтчөнү серпип телефонго өтүңүз"</string>
<string name="voice_hint" msgid="7476017460191291417">"Сүрөтчөнү серпип үн жардамчысына өтүңүз"</string>
<string name="camera_hint" msgid="4519495795000658637">"Сүрөтчөнү серпип камерага өтүңүз"</string>
@@ -521,21 +523,33 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"Профилди көзөмөлдөсө болот"</string>
<string name="vpn_footer" msgid="3457155078010607471">"Тармак көзөмөлдөнүшү мүмкүн"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"Тармак көзөмөлдөнүшү мүмкүн"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"Ишканаңыз бул түзмөктү башкарат жана тармак трафигин көзөмөлдөй алат."</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> бул түзмөктү башкарат жана тармак трафигин көзөмөлдөй алат"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"Түзмөгүңүздү ишканаңыз башкарат жана ал <xliff:g id="VPN_APP">%1$s</xliff:g> тармагына туташкан"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"Түзмөк <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> тарабынан башкарылат жана <xliff:g id="VPN_APP">%2$s</xliff:g> тармагына туташкан"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"Түзмөктү ишканаңыз башкарат"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"Бул түзмөктү <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> башкарат"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"Түзмөгүңүздү ишканаңыз башкарат жана ал VPN тармактарына туташкан"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"Түзмөк <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> тарабынан башкарылат жана VPN тармактарына туташкан"</string>
+ <!-- no translation found for quick_settings_disclosure_management_monitoring (8231336875820702180) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_monitoring (2831423806103479812) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_named_vpn (6096715329056415588) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (5302786161534380104) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management (5515296598440684962) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management (3476472755775165827) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_vpns (371835422690053154) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_vpns (4046375645500668555) -->
+ <skip />
<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_monitoring" msgid="8548019955631378680">"Тармак көзөмөлдөнүшү мүмкүн"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"Түзмөк VPN тармактарына туташкан"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"Жумуш профили <xliff:g id="VPN_APP">%1$s</xliff:g> колдонмосуна туташкан"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"Жеке профиль <xliff:g id="VPN_APP">%1$s</xliff:g> тармагына туташкан"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"Түзмөк <xliff:g id="VPN_APP">%1$s</xliff:g> тармагына туташкан"</string>
+ <!-- no translation found for quick_settings_disclosure_vpns (7213546797022280246) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (8117568745060010789) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (5481763430080807797) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_vpn (2350838218824492465) -->
+ <skip />
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Түзмөктү башкаруу"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Профилди көзөмөлдөө"</string>
<string name="monitoring_title" msgid="4063890083735924568">"Тармакка көз салуу"</string>
@@ -545,8 +559,10 @@
<string name="disable_vpn" msgid="482685974985502922">"VPN\'ди өчүрүү"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"VPN\'ди ажыратуу"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"Саясаттарды карап көрүү"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"Түзмөгүңүздү <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> башкарат.\n\nАдминистраторуңуз жөндөөлөрдү, корпоративдик мүмкүнчүлүктү, колдонмолорду, түзмөгүңүзгө байланыштуу дайын-даректерди жана түзмөгүңүздүн жайгашкан жери тууралуу маалыматты көзөмөлдөп жана башкара алат.\n\nКөбүрөөк маалымат алуу үчүн администраторуңузга кайрылыңыз."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"Түзмөгүңүздү уюмуңуз башкарат.\n\nАдминистраторуңуз жөндөөлөрдү, корпоративдик мүмкүнчүлүктү, колдонмолорду, түзмөгүңүзгө байланыштуу дайын-даректерди жана түзмөгүңүздүн жайгашкан жери тууралуу маалыматты көзөмөлдөп жана башкара алат.\n\nКөбүрөөк маалымат алуу үчүн администраторуңузга кайрылыңыз."</string>
+ <!-- no translation found for monitoring_description_named_management (505833016545056036) -->
+ <skip />
+ <!-- no translation found for monitoring_description_management (4308879039175729014) -->
+ <skip />
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Ишканаңыз бул түзмөккө тастыктоочу борборду орнотту. Коопсуз тармагыңыздын трафиги көзөмөлдөнүп же өзгөртүлүшү мүмкүн."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Ишканаңыз жумуш профилиңизге тастыктоочу борборду орнотту. Коопсуз тармагыңыздын трафиги көзөмөлдөнүп же өзгөртүлүшү мүмкүн."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Бул түзмөктө тастыктоочу борбор орнотулган. Коопсуз тармагыңыздын трафиги көзөмөлдөнүп же өзгөртүлүшү мүмкүн."</string>
@@ -920,6 +936,7 @@
<string name="pip_pause" msgid="1139598607050555845">"Тындыруу"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"Кийинкисине өткөрүп жиберүү"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"Мурункусуна өткөрүп жиберүү"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"Өлчөмүн өзгөртүү"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"Телефон ысыгандыктан өчүрүлдү"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"Телефонуңуз кадимкидей иштеп жатат"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Телефонуңуз өтө ысып кеткендиктен, аны муздатуу үчүн өчүрүлдү. Эми телефонуңуз кадимкидей иштеп жатат.\n\nТелефонуңуз төмөнкү шарттарда ысып кетиши мүмкүн:\n • Ашыкча ресурс короткон колдонмолорду (оюндар, видео же чабыттоо колдонмолору) пайдалансаңыз \n • Ири көлөмдөгү файлдарды жүктөп алсаңыз же берсеңиз\n • Телефонуңузду жогорку температураларда пайдалансаңыз"</string>
@@ -1003,11 +1020,11 @@
<string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Төмөнкү сол жакка жылдыруу"</string>
<string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Төмөнкү оң жакка жылдырыңыз"</string>
<string name="bubble_dismiss_text" msgid="1314082410868930066">"Калкып чыкма билдирмени жабуу"</string>
- <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Жазышуу калкып чыкма билдирмеде көрүнбөсүн"</string>
+ <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Жазышууда калкып чыкма билдирмелер көрүнбөсүн"</string>
<string name="bubbles_user_education_title" msgid="5547017089271445797">"Калкып чыкма билдирмелер аркылуу маектешүү"</string>
<string name="bubbles_user_education_description" msgid="1160281719576715211">"Жаңы жазышуулар калкыма сүрөтчөлөр же калкып чыкма билдирмелер түрүндө көрүнөт. Калкып чыкма билдирмелерди ачуу үчүн таптап коюңуз. Жылдыруу үчүн сүйрөңүз."</string>
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Калкып чыкма билдирмелерди каалаган убакта көзөмөлдөңүз"</string>
- <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Бул колдонмодогу калкып чыкма билдирмелерди өчүрүү үчүн \"Башкарууну\" басыңыз"</string>
+ <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Бул колдонмодогу калкып чыкма билдирмелерди өчүрүү үчүн, \"Башкарууну\" басыңыз"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Түшүндүм"</string>
<string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> жөндөөлөрү"</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Тутум чабыттоосу жаңырды. Өзгөртүү үчүн, Жөндөөлөргө өтүңүз."</string>
@@ -1015,8 +1032,8 @@
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Көшүү режими"</string>
<string name="priority_onboarding_title" msgid="2893070698479227616">"Жазышуу маанилүү болуп коюлду"</string>
<string name="priority_onboarding_behavior" msgid="5342816047020432929">"Маанилүү жазышуулардын төмөнкүдөй артыкчылыктары бар:"</string>
- <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Жазышуу бөлүмүнүн үстүндө көрсөтүү"</string>
- <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Профилдин сүрөтүн кулпуланган экранда көрсөтүү"</string>
+ <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Жазышуулар тизмесинин үстүндө көрүнөт"</string>
+ <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Профилдин сүрөтү кулпуланган экранда көрүнөт"</string>
<string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Калкым чыкма билдирме катары көрсөтүү"</string>
<string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"\"Тынчымды алба\" режими үзгүлтүккө учурайт"</string>
<string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Түшүндүм"</string>
@@ -1025,7 +1042,7 @@
<string name="magnification_window_title" msgid="4863914360847258333">"Чоңойтуу терезеси"</string>
<string name="magnification_controls_title" msgid="8421106606708891519">"Чоңойтуу терезесин башкаруу каражаттары"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"Түзмөктү башкаруу элементтери"</string>
- <string name="quick_controls_subtitle" msgid="1667408093326318053">"Байланышкан түзмөктөрүңүздү башкаруу элементтерин кошуңуз"</string>
+ <string name="quick_controls_subtitle" msgid="1667408093326318053">"Байланышкан түзмөктөрүңүздү башкаруу элементтерин кошосуз"</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"Түзмөктү башкаруу элементтерин жөндөө"</string>
<string name="quick_controls_setup_subtitle" msgid="1681506617879773824">"Көзөмөлдөргө өтүү үчүн, күйгүзүү/өчүрүү баскычын басып туруңуз"</string>
<string name="controls_providers_title" msgid="6879775889857085056">"Башкаруу элементтери кошула турган колдонмону тандаңыз"</string>
@@ -1045,7 +1062,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Башкаруу элементтеринин иретин өзгөртүү үчүн, кармап туруп, сүйрөңүз"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"Бардык башкаруу элементтери өчүрүлдү"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Өзгөртүүлөр сакталган жок"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"Бардык көзөмөлдөрдүн тизмеси жүктөлгөн жок."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"Көзөмөлдөр жүктөлгөн жок. <xliff:g id="APP">%s</xliff:g> колдонмосуна өтүп, колдонмонун жөндөөлөрү өзгөрбөгөнүн текшериңиз."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"Шайкеш көзөмөлдөр жеткиликсиз"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Башка"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"Түзмөктү башкаруу элементтерине кошуу"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"Кошуу"</string>
@@ -1061,13 +1079,20 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"<xliff:g id="DEVICE">%s</xliff:g> түзмөгү үчүн өзгөртүүнү ырастаңыз"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Дагы көрүү үчүн экранды сүрүп коюңуз"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Сунуштар жүктөлүүдө"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"Бул медиа сеансын жабуу"</string>
+ <!-- no translation found for controls_media_title (1746947284862928133) -->
+ <skip />
+ <!-- no translation found for controls_media_close_session (3957093425905475065) -->
+ <skip />
+ <!-- no translation found for controls_media_dismiss_button (4485675693008031646) -->
+ <skip />
<string name="controls_media_resume" msgid="1933520684481586053">"Улантуу"</string>
+ <!-- no translation found for controls_media_settings_button (5815790345117172504) -->
+ <skip />
<string name="controls_error_timeout" msgid="794197289772728958">"Жигерсиз. Колдонмону текшериңиз"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Ката, дагы аракет жасалууда…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Табылган жок"</string>
- <string name="controls_error_removed_title" msgid="1207794911208047818">"Көзөмөл жеткиликтүү эмес"</string>
- <string name="controls_error_removed_message" msgid="2885911717034750542">"<xliff:g id="DEVICE">%1$s</xliff:g> түзмөгүнө кирүү мүмкүнчүлүгү жок. <xliff:g id="APPLICATION">%2$s</xliff:g> колдонмосуна өтүп, көзөмөл жеткиликтүү экенин жана колдонмонун жөндөөлөрү өзгөрбөгөнүн текшериңиз."</string>
+ <string name="controls_error_removed_title" msgid="1207794911208047818">"Башкара албайсыз"</string>
+ <string name="controls_error_removed_message" msgid="2885911717034750542">"<xliff:g id="DEVICE">%1$s</xliff:g> түзмөгүн пайдалана албайсыз. Аны <xliff:g id="APPLICATION">%2$s</xliff:g> колдонмосунан башкарууга мүмкүн же мүмкүн эместигин, ошондой эле колдонмонун жөндөөлөрүнүн өзгөрүлбөгөнүн текшериңиз."</string>
<string name="controls_open_app" msgid="483650971094300141">"Колдонмону ачуу"</string>
<string name="controls_error_generic" msgid="352500456918362905">"Абалы жүктөлгөн жок"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Ката, кайталап көрүңүз"</string>
diff --git a/packages/SystemUI/res/values-land/dimens.xml b/packages/SystemUI/res/values-land/dimens.xml
index 2d42ce6faa2c..2c08925be496 100644
--- a/packages/SystemUI/res/values-land/dimens.xml
+++ b/packages/SystemUI/res/values-land/dimens.xml
@@ -41,4 +41,7 @@
<dimen name="bubble_padding_top">4dp</dimen>
<dimen name="controls_activity_view_top_offset">25dp</dimen>
+
+ <dimen name="biometric_dialog_button_negative_max_width">140dp</dimen>
+ <dimen name="biometric_dialog_button_positive_max_width">116dp</dimen>
</resources>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index 0fe47aab6e7c..1f5254616413 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -454,8 +454,8 @@
<string name="notification_tap_again" msgid="4477318164947497249">"ແຕະ​ອີກ​ຄັ້ງ​ເພື່ອ​ເປີດ"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"ປັດຂຶ້ນເພື່ອເປີດ"</string>
<string name="keyguard_retry" msgid="886802522584053523">"ປັດຂຶ້ນເພື່ອລອງໃໝ່"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"ອຸປະກອນນີ້ແມ່ນຈັດການໂດຍອົງກອນຂອງທ່ານ"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"ອຸປະກອນນີ້ຖືກຈັດການໂດຍ <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
+ <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="phone_hint" msgid="6682125338461375925">"ປັດ​ຈາກ​ໄອ​ຄອນ​ສຳ​ລັບ​ໂທ​ລະ​ສັບ"</string>
<string name="voice_hint" msgid="7476017460191291417">"ປັດ​ຈາກ​ໄອ​ຄອນ​ສຳ​ລັບ​ການ​ຊ່ວຍ​ທາງ​ສຽງ"</string>
<string name="camera_hint" msgid="4519495795000658637">"ປັດ​ຈາກ​ໄອ​ຄອນ​ສຳ​ລັບ​ກ້ອງ​ຖ່າຍ​ຮູບ"</string>
@@ -521,21 +521,21 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"ໂປຣ​ໄຟລ໌​ອາດ​ຖືກ​ເຝົ້າ​ຕິດ​ຕາມ​ຢູ່"</string>
<string name="vpn_footer" msgid="3457155078010607471">"​ເຄືອ​ຂ່າຍ​ອາດ​ມີ​ການ​ເຝົ້າ​ຕິດ​ຕາມ"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"ການນຳໃຊ້ເຄືອຂ່າຍອາດມີການກວດສອບຕິດຕາມ"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"ອົງກອນຂອງທ່ານຈັດການອຸປະກອນນີ້ ແລະ ສາມາດຕິດຕາມທຣາບຟິກເຄືອຂ່າຍໄດ້"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ຈັດການອຸປະກອນນີ້ ແລະ ສາມາດຕິດຕາມທຣາບຟິກເຄືອຂ່າຍໄດ້"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"ອຸປະກອນຂອງທ່ານຖືກຈັດການໂດຍອົງກອນຂອງທ່ານ ແລະ ເຊື່ອມຕໍ່ກັບ <xliff:g id="VPN_APP">%1$s</xliff:g> ແລ້ວ"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"ອຸປະກອນຖືກຈັດການໂດຍ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ແລະ ເຊື່ອມຕໍ່ຫາ <xliff:g id="VPN_APP">%2$s</xliff:g> ແລ້ວ"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"ອຸປະກອນຖືກຈັດການໂດຍອົງກອນຂອງທ່ານ"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"ອຸປະກອນຖືກຈັດການໂດຍ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"ອຸປະກອນຂອງທ່ານຖືກຈັດການໂດຍອົງກອນຂອງທ່ານ ແລະ ເຊື່ອມຕໍ່ກັບ VPN ແລ້ວ"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"ອຸປະກອນຖືກຈັດການໂດຍ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ແລະ ເຊື່ອມຕໍ່ຫາ VPN ແລ້ວ"</string>
+ <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"ອົງການຂອງທ່ານເປັນເຈົ້າຂອງອຸປະກອນນີ້ ແລະ ສາມາດຕິດຕາມທຣາບຟິກເຄືອຂ່າຍໄດ້"</string>
+ <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ເປັນເຈົ້າຂອງອຸປະກອນນີ້ ແລະ ສາມາດຕິດຕາມທຣາບຟິກເຄືອຂ່າຍໄດ້"</string>
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"ອຸປະກອນນີ້ເປັນຂອງອົງການທ່ານ ແລະ ເຊື່ອມຕໍ່ຫາ <xliff:g id="VPN_APP">%1$s</xliff:g> ແລ້ວ"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"ອຸປະກອນນີ້ເປັນຂອງ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ແລະ ເຊື່ອມຕໍ່ຫາ <xliff:g id="VPN_APP">%2$s</xliff:g> ແລ້ວ"</string>
+ <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"ອຸປະກອນນີ້ເປັນຂອງອົງການທ່ານ"</string>
+ <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"ອຸ​ປະ​ກອນ​ນີ້​ເປັນ​ຂອງ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management_vpns" msgid="371835422690053154">"ອຸປະກອນນີ້ເປັນຂອງອົງການທ່ານ ແລະ ເຊື່ອມຕໍ່ຫາ VPN ແລ້ວ"</string>
+ <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_monitoring" msgid="8548019955631378680">"ເຄືອຂ່າຍອາດຖືກຕິດຕາມ"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"ອຸປະກອນເຊື່ອມຕໍ່ຫາ VPN ແລ້ວ"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"ໂປຣໄຟລ໌ບ່ອນເຮັດວຽກເຊື່ອມຕໍ່ຫາ <xliff:g id="VPN_APP">%1$s</xliff:g> ແລ້ວ"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"ໂປຣໄຟລ໌ສ່ວນຕົວເຊື່ອມຕໍ່ຫາ <xliff:g id="VPN_APP">%1$s</xliff:g> ແລ້ວ"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"ອຸປະກອນເຊື່ອມຕໍ່ຫາ <xliff:g id="VPN_APP">%1$s</xliff:g> ແລ້ວ"</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>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"ໂປຣໄຟລ໌ສ່ວນຕົວຂອງທ່ານເຊື່ອມຕໍ່ຫາ <xliff:g id="VPN_APP">%1$s</xliff:g> ແລ້ວ"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"ອຸປະກອນນີ້ເຊື່ອມຕໍ່ຫາ <xliff:g id="VPN_APP">%1$s</xliff:g> ແລ້ວ"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"ການຈັດການອຸປະກອນ"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"ການ​ຕິດ​ຕາມ​ໂປຣ​ໄຟລ໌"</string>
<string name="monitoring_title" msgid="4063890083735924568">"ການກວດ​ສອບ​ຕິດ​ຕາມ​ເຄືອ​ຂ່າຍ"</string>
@@ -545,8 +545,8 @@
<string name="disable_vpn" msgid="482685974985502922">"ປິດ​ການ​ໃຊ້ VPN"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"ຕັດ​ການ​ເຊື່ອມ​ຕໍ່ VPN"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"ເບິ່ງນະໂຍບາຍ"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"ອຸປະກອນຂອງທ່ານແມ່ນຖືກຈັດການໂດຍ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nຜູ້ເບິ່ງແຍງລະບົບຂອງທ່ານສາມາດຕິດຕາມ ແລະ ຈັດການການຕັ້ງຄ່າຕ່າງໆ, ການເຂົ້າເຖິງອົງກອນ, ແອັບ, ຂໍ້ມູນທີ່ເຊື່ອມໂຍງກັບອຸປະກອນ ແລະ ຂໍ້ມູນສະຖານທີ່ຂອງອຸປະກອນທ່ານໄດ້.\n\nສຳລັບຂໍ້ມູນເພີ່ມເຕີມ, ໃຫ້ຕິດຕໍ່ຜູ້ເບິ່ງແຍງລະບົບຂອງທ່ານ."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"ອຸປະກອນຂອງທ່ານແມ່ນຖືກຈັດການໂດຍອົງກອນຂອງທ່ານ.\n\nຜູ້ເບິ່ງແຍງລະບົບຂອງທ່ານສາມາດຕິດຕາມ ແລະ ຈັດການການຕັ້ງຄ່າຕ່າງໆ, ການເຂົ້າເຖິງອົງກອນ, ແອັບ, ຂໍ້ມູນທີ່ເຊື່ອມໂຍງກັບອຸປະກອນ ແລະ ຂໍ້ມູນສະຖານທີ່ຂອງອຸປະກອນທ່ານໄດ້.\n\nສຳລັບຂໍ້ມູນເພີ່ມເຕີມ, ໃຫ້ຕິດຕໍ່ຜູ້ເບິ່ງແຍງລະບົບຂອງທ່ານ."</string>
+ <string name="monitoring_description_named_management" msgid="505833016545056036">"ອຸປະກອນນີ້ເປັນຂອງ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nຜູ້ເບິ່ງແຍງໄອທີຂອງທ່ານສາມາດເຝົ້າຕິດຕາມ ແລະ ຈັດການການຕັ້ງຄ່າ, ສິດເຂົ້າເຖິງອົງກອນ, ແອັບ, ຂໍ້ມູນທີ່ເຊື່ອມໂຍງກັບອຸປະກອນຂອງທ່ານໄດ້.\n\nສຳລັບຂໍ້ມູນເພີ່ມເຕີມ, ກະລຸນາຕິດຕໍ່ຜູ້ເບິ່ງແຍງໄອທີຂອງທ່ານ."</string>
+ <string name="monitoring_description_management" msgid="4308879039175729014">"ອຸປະກອນນີ້ເປັນຂອງອົງການທ່ານ.\n\nຜູ້ເບິ່ງແຍງໄອທີຂອງທ່ານສາມາດເຝົ້າຕິດຕາມ ແລະ ຈັດການການຕັ້ງຄ່າ, ສິດເຂົ້າເຖິງອົງກອນ, ແອັບ, ຂໍ້ມູນທີ່ເຊື່ອມໂຍງກັບອຸປະກອນຂອງທ່ານໄດ້.\n\nສຳລັບຂໍ້ມູນເພີ່ມເຕີມ, ກະລຸນາຕິດຕໍ່ຜູ້ເບິ່ງແຍງໄອທີຂອງທ່ານ."</string>
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"ອົງກອນຂອງທ່ານຕິດຕັ້ງອຳນາດໃບຮັບຮອງໄວ້ໃນອຸປະກອນນີ້. ທຣາບຟິກເຄືອຂ່າຍທີ່ເຂົ້າລະຫັດໄວ້ຂອງທ່ານອາດຖືກຕິດຕາມ ຫຼື ແກ້ໄຂໄດ້."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"ອົງກອນຂອງທ່ານຕິດຕັ້ງອຳນາດໃບຮັບຮອງໄວ້ໃນໂປຣໄຟລ໌ບ່ອນເຮັດວຽກນີ້. ທຣາບຟິກເຄືອຂ່າຍທີ່ເຂົ້າລະຫັດໄວ້ຂອງທ່ານອາດຖືກຕິດຕາມ ຫຼື ແກ້ໄຂໄດ້."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"ມີອຳນາດໃບຮັບຮອງຕິດຕັ້ງຢູ່ໃນອຸປະກອນນີ້. ທຣາບຟິກເຄືອຂ່າຍທີ່ເຂົ້າລະຫັດໄວ້ຂອງທ່ານອາດຖືກຕິດຕາມ ຫຼື ແກ້ໄຂໄດ້."</string>
@@ -920,6 +920,7 @@
<string name="pip_pause" msgid="1139598607050555845">"ຢຸດຊົ່ວຄາວ"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"ຂ້າມໄປລາຍການໜ້າ"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"ຂ້າມໄປລາຍການກ່ອນນີ້"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"ປ່ຽນຂະໜາດ"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"ປິດໂທລະສັບເນື່ອງຈາກຮ້ອນເກີນໄປ"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"ໂທລະສັບຂອງທ່ານຕອນນີ້ເຮັດວຽກປົກກະຕິແລ້ວ"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"ໂທລະສັບຂອງທ່ານຮ້ອນເກີນໄປ, ດັ່ງນັ້ນມັນຈຶ່ງຖືກປິດໄວ້ເພື່ອໃຫ້ເຢັນກ່ອນ. ໂທລະສັບຂອງທ່ານຕອນນີ້ເຮັດວຽກປົກກະຕິແລ້ວ.\n\nໂທລະສັບຂອງທ່ານອາດຮ້ອນຫາກວ່າທ່ານ:\n • ໃຊ້ແອັບທີ່ກິນຊັບພະຍາກອນຫຼາຍ (ເຊັ່ນ: ເກມ, ວິດີໂອ ຫຼື ແອັບການນຳທາງ)\n • ດາວໂຫລດ ຫຼື ອັບໂຫລດຮູບພາບຂະໜາດໃຫຍ່\n • ໃຊ້ໂທລະສັບຂອງທ່ານໃນບ່ອນທີ່ມີອຸນຫະພູມສູງ"</string>
@@ -1002,7 +1003,7 @@
<string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"ຍ້າຍຂວາເທິງ"</string>
<string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"ຍ້າຍຊ້າຍລຸ່ມ"</string>
<string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"ຍ້າຍຂວາລຸ່ມ"</string>
- <string name="bubble_dismiss_text" msgid="1314082410868930066">"ປິດ bubble ໄວ້"</string>
+ <string name="bubble_dismiss_text" msgid="1314082410868930066">"ປິດຟອງໄວ້"</string>
<string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"ຢ່າໃຊ້ຟອງໃນການສົນທະນາ"</string>
<string name="bubbles_user_education_title" msgid="5547017089271445797">"ສົນທະນາໂດຍໃຊ້ຟອງ"</string>
<string name="bubbles_user_education_description" msgid="1160281719576715211">"ການສົນທະນາໃໝ່ຈະປາກົດເປັນໄອຄອນ ຫຼື ຟອງແບບລອຍ. ແຕະເພື່ອເປີດຟອງ. ລາກເພື່ອຍ້າຍມັນ."</string>
@@ -1045,7 +1046,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"ກົດຄ້າງໄວ້ເພື່ອຈັດຮຽງການຄວບຄຸມຄືນໃໝ່"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"ລຶບການຄວບຄຸມທັງໝົດອອກແລ້ວ"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"ບໍ່ໄດ້ບັນທຶກການປ່ຽນແປງໄວ້"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"ບໍ່ສາມາດໂຫຼດລາຍຊື່ການຄວບຄຸມທັງໝົດໄດ້."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"ບໍ່ສາມາດໂຫຼດການຄວບຄຸມໄດ້. ກວດສອບແອັບ <xliff:g id="APP">%s</xliff:g> ເພື່ອໃຫ້ແນ່ໃຈວ່າຍັງບໍ່ມີການປ່ຽນແປງການຕັ້ງຄ່າແອັບເທື່ອ."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"ບໍ່ມີການຄວບຄຸມທີ່ໃຊ້ຮ່ວມກັນທີ່ສາມາດໃຊ້ໄດ້"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"ອື່ນໆ"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"ເພີ່ມໃສ່ການຄວບຄຸມອຸປະກອນ"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"ເພີ່ມ"</string>
@@ -1061,8 +1063,11 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"ຢືນຢັນການປ່ຽນແປງສຳລັບ <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"ປັດເພື່ອເບິ່ງເພີ່ມເຕີມ"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"ກຳລັງໂຫຼດຄຳແນະນຳ"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"ປິດເຊດຊັນມີເດຍນີ້"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"ມີເດຍ"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"ເຊື່ອງເຊດຊັນປັດຈຸບັນ."</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"ເຊື່ອງ"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"ສືບຕໍ່"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"ການຕັ້ງຄ່າ"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"ບໍ່ເຮັດວຽກ, ກະລຸນາກວດສອບແອັບ"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"ຜິດພາດ, ກໍາລັງ​ລອງ​ໃໝ່…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"ບໍ່ພົບ"</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 59cab5795f13..ed02b486efbf 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -458,8 +458,10 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Palieskite dar kartą, kad atidarytumėte"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Perbraukite aukštyn, kad atidarytumėte"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Jei norite bandyti dar kartą, perbraukite aukštyn"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"Šį įrenginį tvarko jūsų organizacija"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"Šį įrenginį tvarko <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for do_disclosure_generic (4896482821974707167) -->
+ <skip />
+ <!-- no translation found for do_disclosure_with_name (2091641464065004091) -->
+ <skip />
<string name="phone_hint" msgid="6682125338461375925">"Perbraukite iš telefono piktogramos"</string>
<string name="voice_hint" msgid="7476017460191291417">"Perbraukite iš „Voice Assist“ piktogramos"</string>
<string name="camera_hint" msgid="4519495795000658637">"Perbraukite iš fotoaparato piktogramos"</string>
@@ -527,21 +529,33 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"Profilis gali būti stebimas"</string>
<string name="vpn_footer" msgid="3457155078010607471">"Tinklas gali būti stebimas"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"Tinklas gali būti stebimas"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"Šį įrenginį tvarko jūsų organizacija ir gali stebėti tinklo srautą."</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"Šį įrenginį tvarko „<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>“ ir gali stebėti tinklo srautą"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"Įrenginį tvarko jūsų organizaciją ir jis susietas su programa „<xliff:g id="VPN_APP">%1$s</xliff:g>“"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"Įrenginį tvarko „<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>“ ir jis susietas su programa „<xliff:g id="VPN_APP">%2$s</xliff:g>“"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"Įrenginį tvarko jūsų organizacija"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"Įrenginį tvarko „<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>“"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"Įrenginį tvarko jūsų organizacija ir jis susietas su VPN"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"Įrenginį tvarko „<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>“ ir jis susietas su VPN"</string>
+ <!-- no translation found for quick_settings_disclosure_management_monitoring (8231336875820702180) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_monitoring (2831423806103479812) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_named_vpn (6096715329056415588) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (5302786161534380104) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management (5515296598440684962) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management (3476472755775165827) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_vpns (371835422690053154) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_vpns (4046375645500668555) -->
+ <skip />
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Jūsų organizacija darbo profilyje gali stebėti tinklo srautą"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"„<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>“ darbo profilyje gali stebėti tinklo srautą"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Tinklas gali būti stebimas"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"Įrenginys susietas su VPN"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"Darbo profilis susietas su programa „<xliff:g id="VPN_APP">%1$s</xliff:g>“"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"Asmeninis profilis susietas su programa „<xliff:g id="VPN_APP">%1$s</xliff:g>“"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"Įrenginys susietas su programa „<xliff:g id="VPN_APP">%1$s</xliff:g>“"</string>
+ <!-- no translation found for quick_settings_disclosure_vpns (7213546797022280246) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (8117568745060010789) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (5481763430080807797) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_vpn (2350838218824492465) -->
+ <skip />
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Įrenginio tvarkymas"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Profilio stebėjimas"</string>
<string name="monitoring_title" msgid="4063890083735924568">"Tinklo stebėjimas"</string>
@@ -551,8 +565,10 @@
<string name="disable_vpn" msgid="482685974985502922">"Išjungti VPN"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"Atjungti VPN"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"Žr. politiką"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"Įrenginį tvarko „<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>“.\n\nAdministratorius gali stebėti ir tvarkyti nustatymus, įmonės prieigą, programas, su įrenginiu susietus duomenis ir įrenginio vietovės informaciją.\n\nDaugiau informacijos galite gauti susisiekę su administratoriumi."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"Įrenginį tvarko organizacija.\n\nAdministratorius gali stebėti ir tvarkyti nustatymus, įmonės prieigą, programas, su įrenginiu susietus duomenis ir įrenginio vietovės informaciją.\n\nDaugiau informacijos galite gauti susisiekę su administratoriumi."</string>
+ <!-- no translation found for monitoring_description_named_management (505833016545056036) -->
+ <skip />
+ <!-- no translation found for monitoring_description_management (4308879039175729014) -->
+ <skip />
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Jūsų organizacija įdiegė šiame įrenginyje sertifikato įgaliojimą. Jūsų saugaus tinklo srautas gali būti stebimas arba keičiamas."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Jūsų organizacija įdiegė darbo profilyje sertifikato įgaliojimą. Jūsų saugaus tinklo srautas gali būti stebimas arba keičiamas."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Šiame įrenginyje įdiegtas sertifikato įgaliojimas. Jūsų saugaus tinklo srautas gali būti stebimas arba keičiamas."</string>
@@ -930,6 +946,7 @@
<string name="pip_pause" msgid="1139598607050555845">"Pristabdyti"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"Praleisti ir eiti į kitą"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"Praleisti ir eiti į ankstesnį"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"Pakeisti dydį"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"Telefonas išjungt., nes įkaito"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"Dabar telefonas veikia įprastai"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Telefonas per daug įkaito, todėl buvo išj., kad atvėstų. Dabar telefonas veikia įprastai.\n\nTelefonas gali per daug įkaisti, jei:\n • esate įjungę daug išteklių naudoj. progr. (pvz., žaidimų, vaizdo įr. arba navig. progr.);\n • atsis. arba įkeliate didelius failus;\n • telefoną naudojate aukštoje temper."</string>
@@ -1057,7 +1074,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Norėdami pertvarkyti valdiklius, vilkite laikydami nuspaudę"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"Visi valdikliai pašalinti"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Pakeitimai neišsaugoti"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"Nepavyko įkelti visų valdiklių sąrašo."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"Nepavyko įkelti valdiklių. Eikite į programą „<xliff:g id="APP">%s</xliff:g>“ ir įsitikinkite, kad programos nustatymai nepakeisti."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"Suderinami valdikliai nepasiekiami"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Kita"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"Pridėjimas prie įrenginio valdiklių"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"Pridėti"</string>
@@ -1073,8 +1091,11 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"Patvirtinti <xliff:g id="DEVICE">%s</xliff:g> pakeitimą"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Perbraukite, kad peržiūrėtumėte daugiau"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Įkeliamos rekomendacijos"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"Uždaryti šį medijos seansą"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"Medija"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"Slėpti dabartinį seansą."</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Slėpti"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Tęsti"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"Nustatymai"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Neaktyvu, patikrinkite progr."</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Klaida, bandoma iš naujo…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Nerasta"</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index bc157026e745..09b0fc3d3ce7 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -456,8 +456,10 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Pieskarieties vēlreiz, lai atvērtu"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Velciet augšup, lai atvērtu"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Velciet augšup, lai mēģinātu vēlreiz"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"Šo ierīci pārvalda jūsu organizācija"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"Šo ierīci pārvalda <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for do_disclosure_generic (4896482821974707167) -->
+ <skip />
+ <!-- no translation found for do_disclosure_with_name (2091641464065004091) -->
+ <skip />
<string name="phone_hint" msgid="6682125338461375925">"Lai lietotu tālruni, velciet no ikonas"</string>
<string name="voice_hint" msgid="7476017460191291417">"Lai lietotu balss palīgu, velciet no ikonas"</string>
<string name="camera_hint" msgid="4519495795000658637">"Lai lietotu kameru, velciet no ikonas"</string>
@@ -524,21 +526,33 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"Profilu var pārraudzīt"</string>
<string name="vpn_footer" msgid="3457155078010607471">"Iespējams, tīklā veiktās darbības tiek pārraudzītas."</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"Var tikt pārraudzītas tīklā veiktās darbības."</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"Jūsu organizācija pārvalda šo ierīci un var uzraudzīt tīkla datplūsmu."</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> pārvalda šo ierīci un var uzraudzīt tīkla datplūsmu."</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"Ierīci pārvalda jūsu organizācija, un tai ir izveidots savienojums ar lietotni <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"Ierīci pārvalda <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>, un tai ir izveidots savienojums ar lietotni <xliff:g id="VPN_APP">%2$s</xliff:g>."</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"Ierīci pārvalda jūsu organizācija"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"Šo ierīci pārvalda <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>."</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"Ierīci pārvalda jūsu organizācija un tai ir izveidots savienojums ar VPN."</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"Ierīci pārvalda <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>, un tai ir izveidots savienojums ar VPN."</string>
+ <!-- no translation found for quick_settings_disclosure_management_monitoring (8231336875820702180) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_monitoring (2831423806103479812) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_named_vpn (6096715329056415588) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (5302786161534380104) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management (5515296598440684962) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management (3476472755775165827) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_vpns (371835422690053154) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_vpns (4046375645500668555) -->
+ <skip />
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Jūsu organizācija var uzraudzīt jūsu darba profila tīkla datplūsmu."</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> var uzraudzīt jūsu profila tīkla datplūsmu."</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Var tikt pārraudzītas tīklā veiktās darbības."</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"Ierīcei ir izveidots savienojums ar VPN."</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"Darba profilam tika izveidots savienojums ar lietotni <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"Personīgajam profilam ir izveidots savienojums ar lietotni <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"Izveidots savienojums ar lietotni <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
+ <!-- no translation found for quick_settings_disclosure_vpns (7213546797022280246) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (8117568745060010789) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (5481763430080807797) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_vpn (2350838218824492465) -->
+ <skip />
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Ierīces pārvaldība"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Profila pārraudzība"</string>
<string name="monitoring_title" msgid="4063890083735924568">"Tīkla pārraudzība"</string>
@@ -548,8 +562,10 @@
<string name="disable_vpn" msgid="482685974985502922">"Atspējot VPN"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"Atvienot VPN tīklu"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"Skatīt politikas"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"Jūsu ierīci pārvalda <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nAdministrators var pārraudzīt un pārvaldīt iestatījumus, korporatīvo piekļuvi, lietotnes, ar ierīci saistītos datus un ierīces atrašanās vietas informāciju.\n\nLai iegūtu plašāku informāciju, sazinieties ar administratoru."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"Jūsu ierīci pārvalda jūsu organizācija.\n\nAdministrators var pārraudzīt un pārvaldīt iestatījumus, korporatīvo piekļuvi, lietotnes, ar ierīci saistītos datus un ierīces atrašanās vietas informāciju.\n\nLai iegūtu plašāku informāciju, sazinieties ar administratoru."</string>
+ <!-- no translation found for monitoring_description_named_management (505833016545056036) -->
+ <skip />
+ <!-- no translation found for monitoring_description_management (4308879039175729014) -->
+ <skip />
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Jūsu organizācija instalēja sertifikātu šajā ierīcē. Jūsu drošā tīkla datplūsma var tikt uzraudzīta."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Jūsu organizācija instalēja sertifikātu jūsu darba profilā. Jūsu drošā tīkla datplūsma var tikt uzraudzīta."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Šajā ierīcē ir instalēts sertifikāts. Drošā tīkla datplūsma var tikt uzraudzīta."</string>
@@ -925,6 +941,7 @@
<string name="pip_pause" msgid="1139598607050555845">"Apturēt"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"Pāriet uz nākamo"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"Pāriet uz iepriekšējo"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"Mainīt lielumu"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"Tālrunis izslēgts karstuma dēļ"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"Tagad jūsu tālrunis darbojas normāli"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Jūsu tālrunis bija pārkarsis un tika izslēgts. Tagad tas darbojas normāli.\n\nTālrunis var sakarst, ja:\n • tiek izmantotas lietotnes, kas patērē daudz enerģijas (piem., spēles, video lietotnes vai navigācija);\n • tiek lejupielādēti/augšupielādēti lieli faili;\n • tālrunis tiek lietots augstā temperatūrā."</string>
@@ -1011,7 +1028,7 @@
<string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Nerādīt sarunu burbuļos"</string>
<string name="bubbles_user_education_title" msgid="5547017089271445797">"Tērzēšana, izmantojot burbuļus"</string>
<string name="bubbles_user_education_description" msgid="1160281719576715211">"Jaunas sarunas tiek rādītas kā peldošas ikonas vai burbuļi. Pieskarieties, lai atvērtu burbuli. Velciet, lai to pārvietotu."</string>
- <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Pārvaldīt burbuļus jebkurā laikā"</string>
+ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Allaž pārvaldīt burbuļus"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"Pieskarieties pogai “Pārvaldīt”, lai izslēgtu burbuļus no šīs lietotnes."</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Labi"</string>
<string name="bubbles_app_settings" msgid="5779443644062348657">"Lietotnes <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> iestatījumi"</string>
@@ -1051,7 +1068,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Lai pārkārtotu vadīklas, turiet un velciet tās"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"Visas vadīklas ir noņemtas"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Izmaiņas nav saglabātas."</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"Nevarēja ielādēt sarakstu ar visām vadīklām."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"Nevarēja ielādēt vadīklas. Lietotnē <xliff:g id="APP">%s</xliff:g> pārbaudiet, vai nav mainīti lietotnes iestatījumi."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"Nav pieejamas saderīgas vadīklas"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Cita"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"Pievienošana ierīču vadīklām"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"Pievienot"</string>
@@ -1067,8 +1085,11 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"Izmaiņu apstiprināšana ierīcei <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Velciet, lai skatītu citus vienumus"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Notiek ieteikumu ielāde"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"Aizvērt multivides sesiju"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"Multivide"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"Paslēpiet pašreizējo sesiju."</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Paslēpt"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Atsākt"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"Iestatījumi"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Neaktīva, pārbaudiet lietotni"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Radās kļūda. Mēģina vēlreiz…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Netika atrasta"</string>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 09e7ff17714f..1dbae2790e56 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -454,8 +454,8 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Допрете повторно за да се отвори"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Повлечете за да отворите"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Повлечете нагоре за да се обидете повторно"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"Вашата организација управува со уредов"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"Уредов го управува <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
+ <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="phone_hint" msgid="6682125338461375925">"Повлечете од иконата за телефонот"</string>
<string name="voice_hint" msgid="7476017460191291417">"Повлечете од иконата за гласовна помош"</string>
<string name="camera_hint" msgid="4519495795000658637">"Повлечете од иконата за камерата"</string>
@@ -521,21 +521,21 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"Профилот можеби се следи"</string>
<string name="vpn_footer" msgid="3457155078010607471">"Мрежата може да се следи"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"Мрежата може да се следи"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"Вашата организација управува со уредов и можно е да го следи мрежниот сообраќај"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> управува со уредов и можно е да го следи мрежниот сообраќај"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"Вашата организација управува со уредот. Поврзан е на <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> управува со уредот. Поврзан е на <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"Вашата организација управува со уредот"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> управува со уредот"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"Вашата организација управува со уредот. Поврзан е на виртуелни приватни мрежи"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> управува со уредот. Поврзан е на виртуелни приватни мрежи"</string>
+ <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Организацијата управува со уредов и може да го следи мрежниот сообраќај"</string>
+ <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> е сопственик на уредов и може да го следи мрежниот сообраќај"</string>
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Уредов е во сопственост на организацијата и е поврзан со <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Уредов е во сопственост на <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> и е поврзан со <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Уредов е во сопственост на организацијата"</string>
+ <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Уредов е во сопственост на <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management_vpns" msgid="371835422690053154">"Уредов е во сопственост на организацијата и е поврзан со VPN-мрежи"</string>
+ <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_monitoring" msgid="8548019955631378680">"Мрежата можеби се следи"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"Уредот е поврзан на виртуелни приватни мрежи"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"Работниот профил е поврзан на <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"Личниот профил е поврзан на <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"Уредот е поврзан на <xliff:g id="VPN_APP">%1$s</xliff:g>"</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>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Вашиот личен профил е поврзан со <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Уредов е поврзан со <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Управување со уреди"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Следење профил"</string>
<string name="monitoring_title" msgid="4063890083735924568">"Следење на мрежата"</string>
@@ -545,8 +545,8 @@
<string name="disable_vpn" msgid="482685974985502922">"Оневозможи ВПН"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"Исклучи ВПН"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"Прикажи „Политики“"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"Со уредот управува <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nАдминистраторот може да ги следи и да управува со поставките, корпоративниот пристап, апликациите, податоците поврзани со уредот и информациите за локацијата на уредот.\n\nЗа повеќе информации, контактирајте со администраторот."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"Со уредот управува вашата организација.\n\nАдминистраторот може да ги следи и да управува со поставките, корпоративниот пристап, апликациите, податоците поврзани со уредот и информациите за локацијата на уредот.\n\nЗа повеќе информации, контактирајте со администраторот."</string>
+ <string name="monitoring_description_named_management" msgid="505833016545056036">"Уредов е во сопственост на <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nIT-администраторот може да ги следи и да управува со поставките, корпоративниот пристап, апликациите, податоците поврзани со уредот и информациите за локацијата на уредот.\n\nЗа повеќе информации, контактирајте со IT-администраторот."</string>
+ <string name="monitoring_description_management" msgid="4308879039175729014">"Уредов е во сопственост на организацијата.\n\nIT-администраторот може да ги следи и да управува со поставките, корпоративниот пристап, апликациите, податоците поврзани со уредот и информациите за локацијата на уредот.\n\nЗа повеќе информации, контактирајте со IT-администраторот."</string>
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Вашата организација инсталираше авторитет за сертификат на уредов. Сообраќајот на вашата безбедна мрежа можно е да се следи или изменува."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Вашата организација инсталираше авторитет за сертификат на вашиот работен профил. Вашиот безбеден мрежен сообраќај можно е да се следи или изменува."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"На уредов е инсталиран авторитет за сертификат. Вашиот безбеден мрежен сообраќај можно е да се следи или изменува."</string>
@@ -920,6 +920,7 @@
<string name="pip_pause" msgid="1139598607050555845">"Паузирај"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"Прескокни до следната"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"Прескокни до претходната"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"Промени големина"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"Телефонот се исклучи поради загреаност"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"Сега телефонот работи нормално"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Телефонот беше премногу загреан, така што се исклучи за да се олади. Сега работи нормално.\n\nТелефонот може премногу да се загрее ако:\n • користите апликации што работат со многу ресурси (како што се, на пример, апликациите за видеа, навигација или игри)\n • преземате или поставувате големи датотеки\n •го користите телефонот на високи температури"</string>
@@ -994,7 +995,7 @@
<string name="bubbles_settings_button_description" msgid="7324245408859877545">"Поставки за балончињата за <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Прелевање"</string>
<string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Додајте назад во stack"</string>
- <string name="manage_bubbles_text" msgid="6856830436329494850">"Управување"</string>
+ <string name="manage_bubbles_text" msgid="6856830436329494850">"Управувајте"</string>
<string name="bubble_content_description_single" msgid="5175160674436546329">"<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="7907610717462651870">"<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>
<string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Премести"</string>
@@ -1014,9 +1015,9 @@
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Одете во „Поставки“ за да ја ажурирате навигацијата на системот"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Подготвеност"</string>
<string name="priority_onboarding_title" msgid="2893070698479227616">"Разговорот е поставен како приоритетен"</string>
- <string name="priority_onboarding_behavior" msgid="5342816047020432929">"Приорететните разговори ќе:"</string>
- <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Се прикажува најгоре во делот со разговори"</string>
- <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Се прикажува профилна слика на заклучен екран"</string>
+ <string name="priority_onboarding_behavior" msgid="5342816047020432929">"Приоритетните разговори:"</string>
+ <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"ќе се прикажуваат најгоре во делот со разговори;"</string>
+ <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"ќе прикажуваат профилна слика на заклучен екран."</string>
<string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Се појавува како лебдечко балонче врз апликациите"</string>
<string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Прекинува „Не вознемирувај“"</string>
<string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Сфатив"</string>
@@ -1045,7 +1046,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Задржете и влечете за да ги преуредите контролите"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"Сите контроли се отстранети"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Промените не се зачувани"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"Не можеше да се вчита списокот со сите контроли."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"Контролите не можеше да се вчитаат. Проверете ја апликацијата <xliff:g id="APP">%s</xliff:g> за да се уверите дека поставките за апликацијата не се променети."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"Нема компатибилни контроли"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Друга"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"Додајте во контроли за уредите"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"Додај"</string>
@@ -1061,14 +1063,17 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"Потврдете ја промената за <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Повлечете за да видите повеќе"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Се вчитуваат препораки"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"Затвори ја аудиовизуелнава сесија"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"Аудиовизуелни содржини"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"Сокриј ја тековнава сесија."</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Сокриј"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Продолжи"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"Поставки"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Неактивна, провери апликација"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Грешка, повторен обид…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Не е најдено"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"Контролата не е достапна"</string>
- <string name="controls_error_removed_message" msgid="2885911717034750542">"Не може да се пристапи до <xliff:g id="DEVICE">%1$s</xliff:g>. Проверете ја апликацијата <xliff:g id="APPLICATION">%2$s</xliff:g> за да се осигурите дека контролата е сè уште достапна и дека поставките за апликацијата не се сменети."</string>
- <string name="controls_open_app" msgid="483650971094300141">"Отвори ја апликација"</string>
+ <string name="controls_error_removed_message" msgid="2885911717034750542">"Не може да се пристапи до <xliff:g id="DEVICE">%1$s</xliff:g>. Проверете ја апликацијата <xliff:g id="APPLICATION">%2$s</xliff:g> за да се уверите дека контролата е сѐ уште достапна и дека поставките за апликацијата не се сменети."</string>
+ <string name="controls_open_app" msgid="483650971094300141">"Отвори апликација"</string>
<string name="controls_error_generic" msgid="352500456918362905">"Не може да се вчита статусот"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Грешка, обидете се повторно"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"Во тек"</string>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index e4d4ba407732..bbc0d0692acb 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -454,8 +454,10 @@
<string name="notification_tap_again" msgid="4477318164947497249">"തുറക്കുന്നതിന് വീണ്ടും ടാപ്പുചെയ്യുക"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"തുറക്കാൻ മുകളിലോട്ട് സ്വൈപ്പ് ചെയ്യുക"</string>
<string name="keyguard_retry" msgid="886802522584053523">"വീണ്ടും ശ്രമിക്കാൻ മുകളിലേക്ക് സ്വൈപ്പ് ചെയ്യുക"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"ഈ ഉപകരണം മാനേജുചെയ്യുന്നത് നിങ്ങളുടെ സ്ഥാപനമാണ്"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> മാനേജുചെയ്യുന്ന ഉപകരണമാണിത്"</string>
+ <!-- no translation found for do_disclosure_generic (4896482821974707167) -->
+ <skip />
+ <!-- no translation found for do_disclosure_with_name (2091641464065004091) -->
+ <skip />
<string name="phone_hint" msgid="6682125338461375925">"ഫോൺ ഐക്കണിൽ നിന്ന് സ്വൈപ്പുചെയ്യുക"</string>
<string name="voice_hint" msgid="7476017460191291417">"വോയ്‌സ് അസിസ്റ്റിനായുള്ള ഐക്കണിൽ നിന്ന് സ്വൈപ്പുചെയ്യുക"</string>
<string name="camera_hint" msgid="4519495795000658637">"ക്യാമറ ഐക്കണിൽ നിന്ന് സ്വൈപ്പുചെയ്യുക"</string>
@@ -510,8 +512,7 @@
<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>
- <!-- no translation found for notification_section_header_incoming (850925217908095197) -->
- <skip />
+ <string name="notification_section_header_incoming" msgid="850925217908095197">"പുതിയത്"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"നിശബ്‌ദം"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"അറിയിപ്പുകൾ"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"സംഭാഷണങ്ങൾ"</string>
@@ -522,21 +523,33 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"പ്രൊഫൈൽ നിരീക്ഷിക്കപ്പെടാം"</string>
<string name="vpn_footer" msgid="3457155078010607471">"നെറ്റ്‌വർക്ക് നിരീക്ഷിക്കപ്പെടാം"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"നെറ്റ്‌വർക്ക് നിരീക്ഷിക്കപ്പെടാം"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"നിങ്ങളുടെ സ്ഥാപനമാണ് ഈ ഉപകരണം മാനേജുചെയ്യുന്നത്, നെറ്റ്‌വർക്ക് ട്രാഫിക്ക് നിരീക്ഷിക്കുകയും ചെയ്തേക്കാം"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ആണ് ഈ ഉപകരണം മാനേജുചെയ്യുന്നത്, നെറ്റ്‌വർക്ക് ട്രാഫിക്ക് നിരീക്ഷിക്കുകയും ചെയ്തേക്കാം"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"നിങ്ങളുടെ സ്ഥാപനമാണ് ഈ ഉപകരണം മാനേജുചെയ്യുന്നത്, <xliff:g id="VPN_APP">%1$s</xliff:g> ആപ്പിലേക്ക് ഉപകരണം കണക്റ്റുചെയ്തിരിക്കുന്നു"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ആണ് ഈ ഉപകരണം മാനേജുചെയ്യുന്നത്, <xliff:g id="VPN_APP">%2$s</xliff:g> ആപ്പിലേക്ക് ഉപകരണം കണക്റ്റുചെയ്തിരിക്കുന്നു"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"ഉപകരണം മാനേജുചെയ്യുന്നത് നിങ്ങളുടെ സ്ഥാപനമാണ്"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ആണ് ഈ ഉപകരണം മാനേജുചെയ്യുന്നത്"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"നിങ്ങളുടെ സ്ഥാപനമാണ് ഈ ഉപകരണം മാനേജുചെയ്യുന്നത്, VPN-കളിലേക്ക് ഉപകരണം കണക്റ്റുചെയ്തിരിക്കുന്നു"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ആണ് ഈ ഉപകരണം മാനേജുചെയ്യുന്നത്, VPN-കളിലേക്ക് ഉപകരണം കണക്റ്റുചെയ്തിരിക്കുന്നു"</string>
+ <!-- no translation found for quick_settings_disclosure_management_monitoring (8231336875820702180) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_monitoring (2831423806103479812) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_named_vpn (6096715329056415588) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (5302786161534380104) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management (5515296598440684962) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management (3476472755775165827) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_vpns (371835422690053154) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_vpns (4046375645500668555) -->
+ <skip />
<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_monitoring" msgid="8548019955631378680">"നെറ്റ്‌വർക്ക് നിരീക്ഷിക്കപ്പെടാം"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"VPN-കളിലേക്ക് ഉപകരണം കണക്റ്റുചെയ്തിരിക്കുന്നു"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"<xliff:g id="VPN_APP">%1$s</xliff:g> ആപ്പിലേക്ക് ഔദ്യോഗിക പ്രൊഫൈൽ കണക്റ്റുചെയ്തിരിക്കുന്നു"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"<xliff:g id="VPN_APP">%1$s</xliff:g> ആപ്പിലേക്ക് വ്യക്തിഗത പ്രൊഫൈൽ കണക്റ്റുചെയ്തിരിക്കുന്നു"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"<xliff:g id="VPN_APP">%1$s</xliff:g> ആപ്പിലേക്ക് ഉപകരണം കണക്റ്റുചെയ്തിരിക്കുന്നു"</string>
+ <!-- no translation found for quick_settings_disclosure_vpns (7213546797022280246) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (8117568745060010789) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (5481763430080807797) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_vpn (2350838218824492465) -->
+ <skip />
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"ഉപകരണ മാനേജ്‌മെന്റ്"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"പ്രൊഫൈൽ നിരീക്ഷിക്കൽ"</string>
<string name="monitoring_title" msgid="4063890083735924568">"നെറ്റ്‌വർക്ക് നിരീക്ഷിക്കൽ"</string>
@@ -546,8 +559,10 @@
<string name="disable_vpn" msgid="482685974985502922">"VPN പ്രവർത്തനരഹിതമാക്കുക"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"VPN വിച്‌ഛേദിക്കുക"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"നയങ്ങൾ കാണുക"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"നിങ്ങളുടെ ഉപകരണം നിയന്ത്രിക്കുന്നത് <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> എന്ന സ്ഥാപനമാണ്. \n\nക്രമീകരണം, കോർപ്പറേറ്റ് ആക്‌സസ്, ആപ്പുകൾ, നിങ്ങളുടെ ഉപകരണവുമായി ബന്ധപ്പെട്ട ഡാറ്റ, ഉപകരണത്തിന്റെ ലൊക്കേഷൻ ‌വിവരങ്ങൾ എന്നിവ കൈകാര്യം ചെയ്യാനും നിരീക്ഷിക്കാനും നിങ്ങളുടെ അഡ്‌മിന് കഴിയും.\n\nകൂടുതൽ വിവരങ്ങൾക്ക് നിങ്ങളുടെ അഡ്‌മിനെ ബന്ധപ്പെടുക."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"നിങ്ങളുടെ ഉപകരണം നിയന്ത്രിക്കുന്നത് നിങ്ങളുടെ സ്ഥാപനമാണ്.\n\nക്രമീകരണം, കോർപ്പറേറ്റ് ആക്‌സസ്, ആപ്പുകൾ, നിങ്ങളുടെ ഉപകരണവുമായി ബന്ധപ്പെട്ട ഡാറ്റ, ഉപകരണത്തിന്റെ ലൊക്കേഷൻ ‌വിവരങ്ങൾ എന്നിവ കൈകാര്യം ചെയ്യാനും നിരീക്ഷിക്കാനും നിങ്ങളുടെ അഡ്‌മിന് കഴിയും.\n\nകൂടുതൽ വിവരങ്ങൾക്ക് നിങ്ങളുടെ അഡ്‌മിനെ ബന്ധപ്പെടുക."</string>
+ <!-- no translation found for monitoring_description_named_management (505833016545056036) -->
+ <skip />
+ <!-- no translation found for monitoring_description_management (4308879039175729014) -->
+ <skip />
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"ഈ ഉപകരണത്തിൽ നിങ്ങളുടെ സ്ഥാപനമൊരു സർട്ടിഫിക്കറ്റ് അതോറിറ്റി ഇൻസ്റ്റാൾ ചെയ്തിരിക്കുന്നു. നിങ്ങളുടെ സുരക്ഷിത നെറ്റ്‌വർക്ക് ട്രാഫിക്ക് നിരീക്ഷിക്കപ്പെടുകയോ പരിഷ്കരിക്കപ്പെടുയോ ചെയ്തേക്കാം."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"നിങ്ങളുടെ ഔദ്യോഗിക പ്രൊഫൈലിൽ നിങ്ങളുടെ സ്ഥാപനമൊരു സർട്ടിഫിക്കറ്റ് അതോറിറ്റി ഇൻസ്റ്റാൾ ചെയ്തിരിക്കുന്നു. നിങ്ങളുടെ സുരക്ഷിത നെറ്റ്‌വർക്ക് ട്രാഫിക്ക് നിരീക്ഷിക്കപ്പെടുകയോ പരിഷ്കരിക്കപ്പെടുയോ ചെയ്തേക്കാം."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"നിങ്ങളുടെ ഉപകരണത്തിൽ ഒരു സർട്ടിഫിക്കറ്റ് അതോറിറ്റി ഇൻസ്റ്റാൾ ചെയ്തിരിക്കുന്നു. നിങ്ങളുടെ സുരക്ഷിത നെറ്റ്‌വർക്ക് ട്രാഫിക്ക് നിരീക്ഷിക്കപ്പെടുകയോ പരിഷ്കരിക്കപ്പെടുയോ ചെയ്തേക്കാം."</string>
@@ -921,6 +936,7 @@
<string name="pip_pause" msgid="1139598607050555845">"താൽക്കാലികമായി നിർത്തുക"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"അടുത്തതിലേക്ക് പോകുക"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"മുമ്പത്തേതിലേക്ക് പോകുക"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"വലുപ്പം മാറ്റുക"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"ചൂട് കൂടിയതിനാൽ ഫോൺ ഓഫാക്കി"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"ഫോൺ ഇപ്പോൾ സാധാരണഗതിയിൽ പ്രവർത്തിക്കുന്നു"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"ഫോൺ ചൂടായിരിക്കുന്നതിനാൽ തണുക്കാൻ ഓഫാക്കിയിരിക്കുന്നു. ഫോൺ ഇപ്പോൾ സാധാരണഗതിയിൽ പ്രവർത്തിക്കുന്നു.\n\nഫോണിന് ചൂട് കൂടാൻ കാരണം:\n • ഗെയിമിംഗ്, വീഡിയോ അല്ലെങ്കിൽ നാവിഗേഷൻ തുടങ്ങിയ റിസോഴ്സ്-ഇന്റൻസീവായ ആപ്പുകൾ ഉപയോഗിക്കുന്നത്\n • വലിയ ഫയലുകൾ അപ്‌ലോഡോ ഡൗൺലോഡോ ചെയ്യുന്നത്\n • ഉയർന്ന താപനിലയിൽ ഫോൺ ഉപയോഗിക്കുന്നത്"</string>
@@ -1009,7 +1025,7 @@
<string name="bubbles_user_education_description" msgid="1160281719576715211">"പുതിയ സംഭാഷണങ്ങൾ ഫ്ലോട്ടിംഗ് ഐക്കണുകളോ ബബിളുകളോ ആയി ദൃശ്യമാവുന്നു. ബബിൾ തുറക്കാൻ ടാപ്പ് ചെയ്യൂ. ഇത് നീക്കാൻ വലിച്ചിടുക."</string>
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"ബബിളുകൾ ഏതുസമയത്തും നിയന്ത്രിക്കുക"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"ഈ ആപ്പിൽ നിന്നുള്ള ബബിളുകൾ ഓഫാക്കാൻ മാനേജ് ചെയ്യുക ടാപ്പ് ചെയ്യുക"</string>
- <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"ലഭിച്ചു"</string>
+ <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"മനസ്സിലായി"</string>
<string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> ക്രമീകരണം"</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"സിസ്‌റ്റം നാവിഗേഷൻ അപ്‌ഡേറ്റ് ചെയ്‌തു. മാറ്റങ്ങൾ വരുത്താൻ ക്രമീകരണത്തിലേക്ക് പോവുക."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"സിസ്‌റ്റം നാവിഗേഷൻ അപ്‌ഡേറ്റ് ചെയ്യാൻ ക്രമീകരണത്തിലേക്ക് പോവുക"</string>
@@ -1026,7 +1042,7 @@
<string name="magnification_window_title" msgid="4863914360847258333">"മാഗ്നിഫിക്കേഷൻ വിൻഡോ"</string>
<string name="magnification_controls_title" msgid="8421106606708891519">"മാഗ്നിഫിക്കേഷൻ വിൻഡോ നിയന്ത്രണങ്ങൾ"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"ഉപകരണ നിയന്ത്രണങ്ങൾ"</string>
- <string name="quick_controls_subtitle" msgid="1667408093326318053">"നിങ്ങളുടെ കണക്റ്റ് ചെയ്ത ഉപകരണങ്ങൾക്ക് നിയന്ത്രണങ്ങൾ ചേർക്കുക"</string>
+ <string name="quick_controls_subtitle" msgid="1667408093326318053">"കണക്റ്റ് ചെയ്ത ഉപകരണങ്ങൾക്ക് നിയന്ത്രണങ്ങൾ ചേർക്കുക"</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"ഉപകരണ നിയന്ത്രണങ്ങൾ സജ്ജീകരിക്കുക"</string>
<string name="quick_controls_setup_subtitle" msgid="1681506617879773824">"നിങ്ങളുടെ നിയന്ത്രണങ്ങൾ ആക്‌സസ് ചെയ്യാൻ പവർ ബട്ടണിൽ പിടിക്കുക"</string>
<string name="controls_providers_title" msgid="6879775889857085056">"നിയന്ത്രണങ്ങൾ ചേർക്കാൻ ആപ്പ് തിരഞ്ഞെടുക്കുക"</string>
@@ -1046,7 +1062,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"നിയന്ത്രണങ്ങൾ പുനഃക്രമീകരിക്കാൻ അമർത്തിപ്പിടിച്ച് വലിച്ചിടുക"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"എല്ലാ നിയന്ത്രണങ്ങളും നീക്കം ചെയ്തു"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"മാറ്റങ്ങൾ സംരക്ഷിച്ചിട്ടില്ല"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"എല്ലാ നിയന്ത്രണങ്ങളുടെയും ലിസ്റ്റ് ലോഡ് ചെയ്യാനായില്ല."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"നിയന്ത്രണങ്ങൾ ലോഡ് ചെയ്യാനായില്ല. ആപ്പ് ക്രമീകരണം മാറ്റിയിട്ടില്ലെന്ന് ഉറപ്പാക്കാൻ <xliff:g id="APP">%s</xliff:g> ആപ്പ് പരിശോധിക്കുക."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"അനുയോജ്യമായ നിയന്ത്രണങ്ങൾ ലഭ്യമല്ല"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"മറ്റുള്ളവ"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"ഉപകരണ നിയന്ത്രണങ്ങളിലേക്ക് ചേർക്കുക"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"ചേർക്കുക"</string>
@@ -1062,8 +1079,11 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"<xliff:g id="DEVICE">%s</xliff:g> എന്നതിനുള്ള മാറ്റം സ്ഥിരീകരിക്കുക"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"കൂടുതൽ കാണാൻ സ്വൈപ്പ് ചെയ്യുക"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"നിർദ്ദേശങ്ങൾ ലോഡ് ചെയ്യുന്നു"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"ഈ മീഡിയ സെഷൻ അടയ്ക്കുക"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"മീഡിയ"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"നിലവിലെ സെഷൻ മറയ്‌ക്കുക."</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"മറയ്‌ക്കുക"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"പുനരാരംഭിക്കുക"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"ക്രമീകരണം"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"നിഷ്‌ക്രിയം, ആപ്പ് പരിശോധിക്കൂ"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"പിശക്, വീണ്ടും ശ്രമിക്കുന്നു…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"കണ്ടെത്തിയില്ല"</string>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index 4ab58f089e24..ca98a7c692ce 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -454,8 +454,10 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Нээхийн тулд дахин товшино уу"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Нээхийн тулд дээш шударна уу"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Дахин оролдохын тулд дээш шударна уу"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"Энэ төхөөрөмжийг таны байгууллага удирдаж байна"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"Энэ төхөөрөмжийг <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> удирддаг"</string>
+ <!-- no translation found for do_disclosure_generic (4896482821974707167) -->
+ <skip />
+ <!-- no translation found for do_disclosure_with_name (2091641464065004091) -->
+ <skip />
<string name="phone_hint" msgid="6682125338461375925">"Утсыг гаргахын тулд дүрс тэмдгээс шудрах"</string>
<string name="voice_hint" msgid="7476017460191291417">"Дуут туслахыг нээхийн тулд дүрс тэмдгээс шудрах"</string>
<string name="camera_hint" msgid="4519495795000658637">"Камер нээхийн тулд дүрс тэмдгийг шудрах"</string>
@@ -521,21 +523,33 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"Профайлыг хянаж байж болзошгүй"</string>
<string name="vpn_footer" msgid="3457155078010607471">"Сүлжээ хянагдаж байж болзошгүй"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"Сүлжээг хянаж байж болзошгүй"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"Таны байгууллага энэ төхөөрөмжийг удирддаг бөгөөд сүлжээний ачааллыг хянадаг"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> энэ төхөөрөмжийг удирдаж, сүлжээний ачааллыг хянадаг"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"Төхөөрөмжийг таны байгууллага удирддаг бөгөөд <xliff:g id="VPN_APP">%1$s</xliff:g>-д холбогдсон байна"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"Төхөөрмжийг <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> удирддаг бөгөөд <xliff:g id="VPN_APP">%2$s</xliff:g>-д холбогдсон байна"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"Төхөөрөмжийг таны байгууллага удирддаг"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"Энэ төхөөрөмжийг <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> удирддаг"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"Төхөөрөмжийг таны байгууллага удирддаг бөгөөд VPN-д холбогдсон байна"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"Төхөөрөмжийг <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> удирддаг бөгөөд VPN-д холбогдсон байна"</string>
+ <!-- no translation found for quick_settings_disclosure_management_monitoring (8231336875820702180) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_monitoring (2831423806103479812) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_named_vpn (6096715329056415588) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (5302786161534380104) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management (5515296598440684962) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management (3476472755775165827) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_vpns (371835422690053154) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_vpns (4046375645500668555) -->
+ <skip />
<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_monitoring" msgid="8548019955631378680">"Сүлжээг хянаж байж болзошгүй"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"Төхөөрөмж VPN-д холбогдсон байна"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"Ажлын профайл <xliff:g id="VPN_APP">%1$s</xliff:g>-д холбогдсон"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"Хувийн профайл <xliff:g id="VPN_APP">%1$s</xliff:g>-д холбогдсон байна"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"Төхөөрөмж <xliff:g id="VPN_APP">%1$s</xliff:g>-д холбогдсон байна"</string>
+ <!-- no translation found for quick_settings_disclosure_vpns (7213546797022280246) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (8117568745060010789) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (5481763430080807797) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_vpn (2350838218824492465) -->
+ <skip />
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Төхөөрөмжийн удирдлага"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Профайл хяналт"</string>
<string name="monitoring_title" msgid="4063890083735924568">"Сүлжээний хяналт"</string>
@@ -545,8 +559,10 @@
<string name="disable_vpn" msgid="482685974985502922">"VPN идэвхгүйжүүлэх"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"VPN таслах"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"Удирдамж харах"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"Таны төхөөрөмжийг <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> удирддаг.\n\nТаны админ тохиргоо, байгууллагын хандалт, апп, таны төхөөрөмжтэй холбоотой өгөгдөл, төхөөрөмжийн байршлын мэдээллийг хянаж, удирдах боломжтой.\n\nДэлгэрэнгүй мэдээлэл авах бол админтайгаа холбогдоно уу."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"Таны төхөөрөмжийг байгууллага тань удирддаг.\n\nТаны админ тохиргоо, байгууллагын хандалт, апп, таны төхөөрөмжтэй холбоотой өгөгдөл, төхөөрөмжийн байршлын мэдээллийг хянаж, удирдах боломжтой.\n\nДэлгэрэнгүй мэдээлэл авах бол админтайгаа холбогдоно уу."</string>
+ <!-- no translation found for monitoring_description_named_management (505833016545056036) -->
+ <skip />
+ <!-- no translation found for monitoring_description_management (4308879039175729014) -->
+ <skip />
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Таны байгууллага энэ төхөөрөмжид сертификатын зөвшөөрлийг суулгасан байна. Таны аюулгүй сүлжээний ачааллыг өөрчлөх эсвэл хянах боломжтой."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Таны байгууллага таны ажлын профайлд сертификатын зөвшөөрөл суулгасан байна. Таны аюулгүй сүлжээний ачааллыг өөрчлөх эсвэл хянах боломжтой."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Сертификатын зөвшөөрлийг энэ төхөөрөмжид суулгасан байна. Таны аюулгүй сүлжээний ачааллыг өөрчлөх эсвэл хянах боломжтой."</string>
@@ -920,6 +936,7 @@
<string name="pip_pause" msgid="1139598607050555845">"Түр зогсоох"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"Дараагийн медиад очих"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"Өмнөх медиад очих"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"Хэмжээг өөрчлөх"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"Халснаас үүдэн утас унтарсан"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"Таны утас одоо хэвийн ажиллаж байна"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Таны утас хэт халсан тул хөргөхөөр унтраасан болно. Таны утас одоо хэвийн ажиллаж байна.\n\nХэрэв та дараахыг хийвэл таны утас хэт халж болзошгүй:\n • Их хэмжээний нөөц хэрэглээний апп (тоглоом, видео эсвэл шилжилтийн апп зэрэг)\n • Багтаамж ихтэй файл татах, байршуулах\n • Утсаа өндөр температурт ашиглах"</string>
@@ -1045,7 +1062,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Хяналтуудыг дахин засварлахын тулд дараад чирнэ үү"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"Бүх хяналтыг хассан"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Өөрчлөлтийг хадгалаагүй"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"Бүх хяналтын жагсаалтыг ачаалж чадсангүй."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"Хяналтыг ачаалж чадсангүй. Аппын тохиргоог өөрчлөөгүй эсэхийг нягтлахын тулд <xliff:g id="APP">%s</xliff:g> аппыг шалгана уу."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"Тохирох хяналт байхгүй"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Бусад"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"Төхөөрөмжийн хяналт руу нэмэх"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"Нэмэх"</string>
@@ -1061,8 +1079,15 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"<xliff:g id="DEVICE">%s</xliff:g>-н өөрчлөлтийг баталгаажуулна уу"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Илүү ихийг харахын тулд шударна уу"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Зөвлөмжүүдийг ачаалж байна"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"Медианы энэ харилцан үйлдлийг хаах"</string>
+ <!-- no translation found for controls_media_title (1746947284862928133) -->
+ <skip />
+ <!-- no translation found for controls_media_close_session (3957093425905475065) -->
+ <skip />
+ <!-- no translation found for controls_media_dismiss_button (4485675693008031646) -->
+ <skip />
<string name="controls_media_resume" msgid="1933520684481586053">"Үргэлжлүүлэх"</string>
+ <!-- no translation found for controls_media_settings_button (5815790345117172504) -->
+ <skip />
<string name="controls_error_timeout" msgid="794197289772728958">"Идэвхгүй байна, аппыг шалгана уу"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Алдаа, дахин оролдож байна…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Олдсонгүй"</string>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index d49f46d840b2..1e043bbe666c 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -454,8 +454,10 @@
<string name="notification_tap_again" msgid="4477318164947497249">"उघडण्यासाठी पुन्हा टॅप करा"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"उघडण्यासाठी वर स्वाइप करा"</string>
<string name="keyguard_retry" msgid="886802522584053523">"पुन्हा प्रयत्न करण्यासाठी वर स्‍वाइप करा"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"हे डिव्हाइस तुमची संस्था व्यवस्थापित करते"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"हे डिव्हाइस <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ने व्यवस्थापित केले आहे"</string>
+ <!-- no translation found for do_disclosure_generic (4896482821974707167) -->
+ <skip />
+ <!-- no translation found for do_disclosure_with_name (2091641464065004091) -->
+ <skip />
<string name="phone_hint" msgid="6682125338461375925">"फोनसाठी चिन्हावरून स्वाइप करा"</string>
<string name="voice_hint" msgid="7476017460191291417">"व्हॉइस सहाय्यासाठी चिन्हावरून स्वाइप करा"</string>
<string name="camera_hint" msgid="4519495795000658637">"कॅमेर्‍यासाठी चिन्हावरून स्वाइप करा"</string>
@@ -510,8 +512,7 @@
<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>
- <!-- no translation found for notification_section_header_incoming (850925217908095197) -->
- <skip />
+ <string name="notification_section_header_incoming" msgid="850925217908095197">"नवीन"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"सायलंट"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"सूचना"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"संभाषणे"</string>
@@ -522,21 +523,33 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"प्रोफाईलचे परीक्षण केले जाऊ शकते"</string>
<string name="vpn_footer" msgid="3457155078010607471">"नेटवर्कचे परीक्षण केले जाऊ शकते"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"नेटवर्कचे परीक्षण केले जाऊ शकते"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"तुमची संस्था हे डिव्हाइस व्यवस्थापित करते आणि नेटवर्क रहदारीचे परीक्षण करू शकते"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> हे डिव्हाइस व्यवस्थापित करते आणि नेटवर्क रहदारीचे परीक्षण करू शकते"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"डिव्हाइस तुमच्या संस्थेद्वारे व्यवस्थापित केले जाते आणि ते <xliff:g id="VPN_APP">%1$s</xliff:g> शी कनेक्ट केलेले आहे"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"डिव्हाइस <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> द्वारे व्यवस्थापित केले जाते आणि ते <xliff:g id="VPN_APP">%2$s</xliff:g> शी कनेक्ट केलेले आहे"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"डिव्हाइस तुमच्या संस्थेद्वारे व्यवस्थापित आहे"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"डिव्हाइस <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> द्वारे व्यवस्थापित केले जाते"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"डिव्हाइस तुमच्या संस्थेद्वारे व्यवस्थापित केले जाते आणि ते VPN शी कनेक्ट केलेले आहे"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"डिव्हाइस <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> द्वारे व्यवस्थापित केले जाते आणि ते VPN शी कनेक्ट केलेले आहे"</string>
+ <!-- no translation found for quick_settings_disclosure_management_monitoring (8231336875820702180) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_monitoring (2831423806103479812) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_named_vpn (6096715329056415588) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (5302786161534380104) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management (5515296598440684962) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management (3476472755775165827) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_vpns (371835422690053154) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_vpns (4046375645500668555) -->
+ <skip />
<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_monitoring" msgid="8548019955631378680">"नेटवर्कचे परीक्षण केले जाऊ शकते"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"डिव्हाइस VPN शी कनेक्ट केलेले आहे"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"कार्य प्रोफाइल <xliff:g id="VPN_APP">%1$s</xliff:g> शी कनेक्ट केलेले आहे"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"वैयक्तिक प्रोफाइल <xliff:g id="VPN_APP">%1$s</xliff:g> शी कनेक्ट केलेले आहे"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"डिव्हाइस <xliff:g id="VPN_APP">%1$s</xliff:g> शी कनेक्ट केलेले आहे"</string>
+ <!-- no translation found for quick_settings_disclosure_vpns (7213546797022280246) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (8117568745060010789) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (5481763430080807797) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_vpn (2350838218824492465) -->
+ <skip />
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"डिव्हाइस व्‍यवस्‍थापन"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"प्रोफाईल परीक्षण"</string>
<string name="monitoring_title" msgid="4063890083735924568">"नेटवर्क परीक्षण"</string>
@@ -546,8 +559,10 @@
<string name="disable_vpn" msgid="482685974985502922">"VPN अक्षम करा"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"VPN डिस्कनेक्ट करा"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"धोरणे पहा"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"तुमचे डिव्हाइस <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> व्यवस्थापित करते.\n\nतुमचा प्रशासक सेटिंग्ज, कॉर्पोरेट अ‍ॅक्सेस, अ‍ॅप्स, तुमच्या डिव्हाइस शी संबंधित डेटा आणि तुमच्या डिव्हाइस च्या ठिकाणाची माहिती मॉनिटर करू शकते आणि ती व्यवस्थापित करू शकतो.\n\nआणखी माहितीसाठी, तुमच्या प्रशासकाशी संपर्क साधा."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"तुमचे डिव्हाइस तुमची संस्‍था व्यवस्थापित करते.\n\nतुमचा प्रशासक सेटिंग्ज, कॉर्पोरेट अ‍ॅक्सेस, अ‍ॅप्स, तुमच्या डिव्हाइस शी संबंधित डेटा आणि तुमच्या डिव्हाइस च्या ठिकाणाची माहिती मॉनिटर करू शकतो आणि ती व्यवस्थापित करू शकतो.\n\nआणखी माहितीसाठी, तुमच्या प्रशासकाशी संपर्क साधा."</string>
+ <!-- no translation found for monitoring_description_named_management (505833016545056036) -->
+ <skip />
+ <!-- no translation found for monitoring_description_management (4308879039175729014) -->
+ <skip />
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"आपल्या संस्थेने या डिव्हाइसवर प्रमाणपत्र अधिकार इंस्टॉल केला आहे. आपल्या सुरक्षित नेटवर्क रहदारीचे परीक्षण केले जाऊ शकते किंवा ती सुधारली जाऊ शकते."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"आपल्या संस्थेने आपल्या कार्य प्रोफाइलवर प्रमाणपत्र अधिकार इंस्टॉल केला आहे. आपल्या सुरक्षित नेटवर्क रहदारीचे परीक्षण केले जाऊ शकते किंवा ती सुधारली जाऊ शकते."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"या डिव्हाइसवर प्रमाणपत्र अधिकार इंस्टॉल केला आहे. आपल्या सुरक्षित नेटवर्क रहदारीचे परीक्षण केले जाऊ शकते किंवा ती सुधारली जाऊ शकते."</string>
@@ -921,6 +936,7 @@
<string name="pip_pause" msgid="1139598607050555845">"थांबवा"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"डावलून पुढे जा"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"डावलून मागे जा"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"आकार बदला"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"तापल्‍यामुळे फोन बंद झाला"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"तुमचा फोन आता व्‍यवस्थित सुरू आहे"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"तुमचा फोन खूप तापलाय, म्हणून तो थंड होण्यासाठी बंद झाला आहे. तुमचा फोन आता व्‍यवस्थित सुरू आहे.\n\nतुम्ही असे केल्यास तुमचा फोन खूप तापेल:\n •संसाधन केंद्रित अ‍ॅप वापरणे (गेमिंग, व्हिडिओ किंवा नेव्हिगेशन अ‍ॅप यासारखे)\n •मोठ्या फाइल डाउनलोड किंवा अपलोड करणे\n •उच्च तापमानामध्ये तुमचा फोन वापरणे"</string>
@@ -1046,7 +1062,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"नियंत्रणांची पुनर्रचना करण्यासाठी धरून ठेवा आणि ड्रॅग करा"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"सर्व नियंत्रणे काढून टाकली आहेत"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"बदल सेव्ह केले गेले नाहीत"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"सर्व नियंत्रणांची सूची लोड करता आली नाही."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"नियंत्रणे लोड करता अली नाहीत. ॲपची सेटिंग्ज बदलली नसल्याची खात्री करण्यासाठी <xliff:g id="APP">%s</xliff:g> ॲप तपासा."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"कंपॅटिबल नियंत्रणे उपलब्ध नाहीत"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"इतर"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"डिव्हाइस नियंत्रणांमध्ये जोडा"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"जोडा"</string>
@@ -1062,8 +1079,11 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"<xliff:g id="DEVICE">%s</xliff:g> च्या बदलांची निश्चिती करा"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"अधिक पाहण्यासाठी स्वाइप करा"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"शिफारशी लोड करत आहे"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"हे मीडिया सेशन बंद करा"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"मीडिया"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"सध्याचे सेशन लपवा."</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"लपवा"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"पुन्हा सुरू करा"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"सेटिंग्ज"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"निष्क्रिय, ॲप तपासा"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"एरर, पुन्हा प्रयत्न करत आहे…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"आढळले नाही"</string>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index be17eade57a1..ca3515c9411d 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -454,8 +454,10 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Ketik lagi untuk membuka"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Leret ke atas untuk buka"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Leret ke atas untuk mencuba lagi"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"Peranti ini diurus oleh organisasi anda"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"Peranti ini diurus oleh <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for do_disclosure_generic (4896482821974707167) -->
+ <skip />
+ <!-- no translation found for do_disclosure_with_name (2091641464065004091) -->
+ <skip />
<string name="phone_hint" msgid="6682125338461375925">"Leret dari ikon untuk telefon"</string>
<string name="voice_hint" msgid="7476017460191291417">"Leret dari ikon untuk bantuan suara"</string>
<string name="camera_hint" msgid="4519495795000658637">"Leret dari ikon untuk kamera"</string>
@@ -521,21 +523,33 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"Profil mungkin dipantau"</string>
<string name="vpn_footer" msgid="3457155078010607471">"Rangkaian mungkin dipantau"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"Rangkaian mungkin dipantau"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"Organisasi anda mengurus peranti ini dan mungkin memantau trafik rangkaian"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> mengurus peranti ini dan mungkin memantau trafik rangkaian"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"Peranti diurus oleh organisasi anda dan dihubungkan ke <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"Peranti diurus oleh <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> dan dihubungkan ke <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"Peranti diurus oleh organisasi anda"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"Peranti diurus oleh <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"Peranti diurus oleh organisasi anda dan dihubungkan ke beberapa VPN"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"Peranti diurus oleh <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> dan dihubungkan ke beberapa VPN"</string>
+ <!-- no translation found for quick_settings_disclosure_management_monitoring (8231336875820702180) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_monitoring (2831423806103479812) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_named_vpn (6096715329056415588) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (5302786161534380104) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management (5515296598440684962) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management (3476472755775165827) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_vpns (371835422690053154) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_vpns (4046375645500668555) -->
+ <skip />
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Organisasi anda mungkin memantau trafik rangkaian dalam profil kerja anda"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> mungkin memantau trafik rangkaian dalam profil kerja anda"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Rangkaian mungkin dipantau"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"Peranti dihubungkan ke beberapa VPN"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"Profil kerja dihubungkan ke <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"Profil peribadi dihubungkan ke <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"Peranti dihubungkan ke <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <!-- no translation found for quick_settings_disclosure_vpns (7213546797022280246) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (8117568745060010789) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (5481763430080807797) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_vpn (2350838218824492465) -->
+ <skip />
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Pengurusan peranti"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Pemantauan profil"</string>
<string name="monitoring_title" msgid="4063890083735924568">"Pemantauan rangkaian"</string>
@@ -545,8 +559,10 @@
<string name="disable_vpn" msgid="482685974985502922">"Lumpuhkan VPN"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"Putuskan sambungan VPN"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"Lihat Dasar"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"Peranti anda diurus oleh <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nPentadbir anda boleh memantau dan mengurus tetapan, akses korporat, apl, data yang dikaitkan dengan peranti serta maklumat lokasi peranti anda.\n\nUntuk mendapatkan maklumat lanjut, hubungi pentadbir anda."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"Peranti anda diurus oleh organisasi.\n\nPentadbir anda boleh memantau dan mengurus tetapan, akses korporat, apl, data yang dikaitkan dengan peranti serta maklumat lokasi peranti anda.\n\nUntuk mendapatkan maklumat lanjut, hubungi pentadbir anda."</string>
+ <!-- no translation found for monitoring_description_named_management (505833016545056036) -->
+ <skip />
+ <!-- no translation found for monitoring_description_management (4308879039175729014) -->
+ <skip />
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Organisasi anda memasang sijil kuasa pada peranti ini. Trafik rangkaian selamat anda mungkin dipantau atau diubah suai."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Organisasi anda memasang sijil kuasa dalam profil kerja anda. Trafik rangkaian selamat anda mungkin dipantau atau diubah suai."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Sijil kuasa dipasang pada peranti ini. Trafik rangkaian selamat anda mungkin dipantau atau diubah suai."</string>
@@ -920,6 +936,7 @@
<string name="pip_pause" msgid="1139598607050555845">"Jeda"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"Langkau ke seterusnya"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"Langkau ke sebelumnya"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"Ubah saiz"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"Telefon dimatikan kerana panas"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"Telefon anda kini berjalan seperti biasa"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Telefon anda terlalu panas, jadi telefon itu telah dimatikan untuk menyejuk. Sekarang, telefon anda berjalan seperti biasa.\n\nTelefon anda mungkin menjadi terlalu panas jika anda:\n • Menggunakan apl intensif sumber (seperti permainan, video atau apl navigasi)\n • Memuat turun atau memuat naik fail besar\n • Menggunakan telefon anda dalam suhu tinggi"</string>
@@ -1015,8 +1032,8 @@
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Tunggu sedia"</string>
<string name="priority_onboarding_title" msgid="2893070698479227616">"Perbualan ditetapkan kepada keutamaan"</string>
<string name="priority_onboarding_behavior" msgid="5342816047020432929">"Perbualan keutamaan akan:"</string>
- <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Tunjukkan di atas bahagian perbualan"</string>
- <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Tunjukkan gambar profil pada skrin kunci"</string>
+ <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Muncul di atas bahagian perbualan"</string>
+ <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Memaparkan gambar profil pada skrin kunci"</string>
<string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Dipaparkan sebagai gelembung terapung di atas apl"</string>
<string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Ganggu ciri Jangan Ganggu"</string>
<string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"OK"</string>
@@ -1045,7 +1062,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Tahan &amp; seret untuk mengatur semula kawalan"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"Semua kawalan dialih keluar"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Perubahan tidak disimpan"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"Senarai semua kawalan tidak dapat dimuatkan."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"Kawalan tidak dapat dimuatkan. Semak apl <xliff:g id="APP">%s</xliff:g> untuk memastikan bahawa tetapan apl tidak berubah."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"Kawalan serasi tidak tersedia"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Lain-lain"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"Tambahkan pada kawalan peranti"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"Tambah"</string>
@@ -1061,11 +1079,18 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"Sahkan perubahan untuk <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Leret untuk melihat selanjutnya"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Memuatkan cadangan"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"Tutup sesi media ini"</string>
+ <!-- no translation found for controls_media_title (1746947284862928133) -->
+ <skip />
+ <!-- no translation found for controls_media_close_session (3957093425905475065) -->
+ <skip />
+ <!-- no translation found for controls_media_dismiss_button (4485675693008031646) -->
+ <skip />
<string name="controls_media_resume" msgid="1933520684481586053">"Sambung semula"</string>
+ <!-- no translation found for controls_media_settings_button (5815790345117172504) -->
+ <skip />
<string name="controls_error_timeout" msgid="794197289772728958">"Tidak aktif, semak apl"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Ralat, mencuba semula…"</string>
- <string name="controls_error_removed" msgid="6675638069846014366">"Tidak ditemui"</string>
+ <string name="controls_error_removed" msgid="6675638069846014366">"Tidak ditemukan"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"Kawalan tidak tersedia"</string>
<string name="controls_error_removed_message" msgid="2885911717034750542">"Tidak dapat mengakses <xliff:g id="DEVICE">%1$s</xliff:g>. Periksa apl <xliff:g id="APPLICATION">%2$s</xliff:g> untuk memastikan kawalan masih tersedia dan tetapan apl tidak berubah."</string>
<string name="controls_open_app" msgid="483650971094300141">"Buka apl"</string>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index eaf4157ff4e1..29679d6a5650 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -454,8 +454,8 @@
<string name="notification_tap_again" msgid="4477318164947497249">"ဖွင့်ရန် ထပ်ပြီး ပုတ်ပါ"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"ဖွင့်ရန် အပေါ်သို့ပွတ်ဆွဲပါ"</string>
<string name="keyguard_retry" msgid="886802522584053523">"ထပ်စမ်းကြည့်ရန် အပေါ်သို့ပွတ်ဆွဲပါ"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"ဤစက်ပစ္စည်းကို သင်၏အဖွဲ့အစည်းက စီမံခန့်ခွဲထားပါသည်"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"ဤစက်ပစ္စည်းကို <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> က စီမံခန့်ခွဲထားပါသည်"</string>
+ <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="phone_hint" msgid="6682125338461375925">"ဖုန်းအတွက် သင်္ကေတပုံအား ပွတ်ဆွဲပါ"</string>
<string name="voice_hint" msgid="7476017460191291417">"အသံအကူအညီအတွက် သင်္ကေတပုံအား ပွတ်ဆွဲပါ"</string>
<string name="camera_hint" msgid="4519495795000658637">"ကင်မရာအတွက် သင်္ကေတပုံအား ပွတ်ဆွဲပါ"</string>
@@ -521,21 +521,21 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"ပရိုဖိုင်ကို စောင့်ကြပ်နိုင်သည်"</string>
<string name="vpn_footer" msgid="3457155078010607471">"ကွန်ရက်ကို ကို စောင့်ကြပ် နိုင်ပါသည်"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"ကွန်ရက်ကို စောင့်ကြည့်စစ်ဆေးမှု ရှိနိုင်ပါသည်"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"ဤစက်ပစ္စည်းကို သင်၏ အဖွဲ့အစည်းက စီမံခန့်ခွဲပြီး ကွန်ရက်ဒေတာ စီးဆင်းမှုကို စောင့်ကြည့်နိုင်ပါသည်"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"ဤစက်ပစ္စည်းကို <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> က စီမံခန့်ခွဲပြီး ကွန်ရက်ဒေတာ စီးဆင်းမှုကို စောင့်ကြည့်နိုင်ပါသည်"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"စက်ပစ္စည်းကို သင်၏ အဖွဲ့အစည်းက စီမံခန့်ခွဲထားပြီး <xliff:g id="VPN_APP">%1$s</xliff:g> သို့ ချိတ်ဆက်ထားပါသည်"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"စက်ပစ္စည်းကို <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> က စီမံခန့်ခွဲထားပြီး <xliff:g id="VPN_APP">%2$s</xliff:g> သို့ ချိတ်ဆက်ထားပါသည်"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"စက်ပစ္စည်းကို သင်၏ အဖွဲ့အစည်းက စီမံခန့်ခွဲထားသည်"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"စက်ပစ္စည်းကို <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> က စီမံခန့်ခွဲထားပါသည်"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"စက်ပစ္စည်းကို သင်၏ အဖွဲ့အစည်းက စီမံခန့်ခွဲထားပြီး VPN များသို့ ချိတ်ဆက်ထားပါသည်"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"စက်ပစ္စည်းကို <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> က စီမံခန့်ခွဲထားပြီး VPN များသို့ ချိတ်ဆက်ထားပါသည်"</string>
+ <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"ဤစက်ကို သင့်အဖွဲ့အစည်းကပိုင်ဆိုင်ပြီး ကွန်ရက်ဒေတာ စီးဆင်းမှုကို စောင့်ကြည့်နိုင်ပါသည်"</string>
+ <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"ဤစက်ကို <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> က ပိုင်ဆိုင်ပြီး ကွန်ရက်ဒေတာ စီးဆင်းမှုကို စောင့်ကြည့်နိုင်ပါသည်"</string>
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"ဤစက်ကို သင့်အဖွဲ့အစည်းကပိုင်ဆိုင်ပြီး <xliff:g id="VPN_APP">%1$s</xliff:g> သို့ ချိတ်ဆက်ထားပါသည်"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"ဤစက်ကို <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> က ပိုင်ဆိုင်ပြီး <xliff:g id="VPN_APP">%2$s</xliff:g> သို့ ချိတ်ဆက်ထားပါသည်"</string>
+ <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"ဤစက်ကို သင့်အဖွဲ့အစည်းက ပိုင်ဆိုင်သည်"</string>
+ <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"ဤစက်ကို <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> က ပိုင်ဆိုင်သည်"</string>
+ <string name="quick_settings_disclosure_management_vpns" msgid="371835422690053154">"ဤစက်ကို သင့်အဖွဲ့အစည်းကပိုင်ဆိုင်ပြီး VPN များသို့ ချိတ်ဆက်ထားပါသည်"</string>
+ <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_monitoring" msgid="8548019955631378680">"ကွန်ရက်ကို စောင့်ကြည့်နိုင်ပါသည်"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"စက်ပစ္စည်းကို VPN များသို့ ချိတ်ဆက်ထားသည်"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"အလုပ်ပရိုဖိုင်ကို <xliff:g id="VPN_APP">%1$s</xliff:g> သို့ ချိတ်ဆက်ထားသည်"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"ကိုယ်ပိုင်ပရိုဖိုင်ကို <xliff:g id="VPN_APP">%1$s</xliff:g> သို့ ချိတ်ဆက်ထားပါသည်"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"စက်ပစ္စည်းကို <xliff:g id="VPN_APP">%1$s</xliff:g> သို့ ချိတ်ဆက်ထားသည်"</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>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"သင်၏ ကိုယ်ပိုင်ပရိုဖိုင်ကို <xliff:g id="VPN_APP">%1$s</xliff:g> သို့ ချိတ်ဆက်ထားပါသည်"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"ဤစက်ကို <xliff:g id="VPN_APP">%1$s</xliff:g> သို့ ချိတ်ဆက်ထားပါသည်"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"စက်ပစ္စည်း စီမံခန့်ခွဲမှု"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"ပရိုဖိုင် စောင့်ကြပ်မှု"</string>
<string name="monitoring_title" msgid="4063890083735924568">"ကွန်ရက်ကို စောင့်ကြပ်ခြင်း"</string>
@@ -545,8 +545,8 @@
<string name="disable_vpn" msgid="482685974985502922">"VPN ကို ပိတ်ထားရန်"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"VPN ကို အဆက်ဖြတ်ရန်"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"မူဝါဒများကို ကြည့်ရန်"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"သင့်စက်ပစ္စည်းကို <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> အဖွဲ့အစည်းက စီမံခန့်ခွဲထားပါသည်။\n\nသင်၏ စီမံခန့်ခွဲသူသည် ဆက်တင်များ၊ အဖွဲ့အစည်း အသုံးပြုခွင့်များ၊ အက်ပ်များ၊ စက်ပစ္စည်းနှင့် ဆက်စပ်နေသည့် ဒေတာများနှင့် စက်ပစ္စည်း၏ တည်နေရာအချက်အလက်များကို စောင့်ကြည့်၍ စီမံနိုင်ပါသည်။\n\nနောက်ထပ် အချက်အလက်များအတွက် စီမံခန့်ခွဲသူကို ဆက်သွယ်ပါ။"</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"သင့်စက်ပစ္စည်းကို သင်၏အဖွဲ့အစည်းက စီမံခန့်ခွဲထားပါသည်။\n\nသင်၏ စီမံခန့်ခွဲသူသည် ဆက်တင်များ၊ အဖွဲ့အစည်း အသုံးပြုခွင့်များ၊ အက်ပ်များ၊ စက်ပစ္စည်းနှင့် ဆက်စပ်နေသည့် ဒေတာများနှင့် စက်ပစ္စည်း၏ တည်နေရာအချက်အလက်များကို စောင့်ကြည့်၍ စီမံနိုင်ပါသည်။\n\nနောက်ထပ် အချက်အလက်များအတွက် စီမံခန့်ခွဲသူကို ဆက်သွယ်ပါ။"</string>
+ <string name="monitoring_description_named_management" msgid="505833016545056036">"ဤစက်ကို <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> က ပိုင်ဆိုင်ပါသည်။\n\nဆက်တင်များ၊ ကော်ပိုရိတ် သုံးခွင့်၊ အက်ပ်များ၊ သင့်စက်နှင့် ဆက်စပ်နေသော ဒေတာများနှင့် သင့်စက်တည်နေရာတို့ကို သင်၏ IT စီမံခန့်ခွဲသူက စောင့်ကြည့် စီမံနိုင်သည်။\n\nနောက်ထပ်အချက်အလက်များအတွက် သင်၏ IT စီမံခန့်ခွဲသူကို ဆက်သွယ်ပါ။"</string>
+ <string name="monitoring_description_management" msgid="4308879039175729014">"ဤစက်ကို သင့်အဖွဲ့အစည်းက ပိုင်ဆိုင်သည်။\n\nဆက်တင်များ၊ ကော်ပိုရိတ် သုံးခွင့်၊ အက်ပ်များ၊ သင့်စက်နှင့် ဆက်စပ်နေသော ဒေတာများနှင့် သင့်စက်တည်နေရာတို့ကို သင်၏ IT စီမံခန့်ခွဲသူက စောင့်ကြည့် စီမံနိုင်သည်။\n\nနောက်ထပ်အချက်အလက်များအတွက် သင်၏ IT စီမံခန့်ခွဲသူကို ဆက်သွယ်ပါ။"</string>
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"သင်၏ အဖွဲ့အစည်းက ဤစက်ပစ္စည်းတွင် စီမံခန့်ခွဲမှုဆိုင်ရာ အသိအမှတ်ပြုလက်မှတ်ကို ထည့်သွင်းထားပါသည်။ လုံခြုံမှုရှိသော ကွန်ရက်ဒေတာစီးဆင်းမှုကို စောင့်ကြည့်ခြင်း သို့မဟုတ် ပြုပြင်ခြင်းများ ပြုလုပ်နိုင်ပါသည်။"</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"သင်၏ အဖွဲ့အစည်းသည် သင်၏ အလုပ်ပရိုဖိုင်တွင် စီမံခန့်ခွဲမှုဆိုင်ရာ အသိအမှတ်ပြုလက်မှတ်ကို ထည့်သွင်းထားပါသည်။ လုံခြုံမှုရှိသော ကွန်ရက်ဒေတာစီးဆင်းမှုကို စောင့်ကြည့်ခြင်း သို့မဟုတ် ပြုပြင်ခြင်းများ ပြုလုပ်နိုင်ပါသည်။"</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"ဤစက်ပစ္စည်းတွင် စီမံခန့်ခွဲမှုဆိုင်ရာ အသိအမှတ်ပြုလက်မှတ်ကို ထည့်သွင်းထားပါသည်။ လုံခြုံမှုရှိသော ကွန်ရက်ဒေတာစီးဆင်းမှုကို စောင့်ကြည့်ခြင်း သို့မဟုတ် ပြုပြင်ခြင်းများ ပြုလုပ်နိုင်ပါသည်။"</string>
@@ -920,6 +920,7 @@
<string name="pip_pause" msgid="1139598607050555845">"ခေတ္တရပ်ရန်"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"နောက်တစ်ခုသို့ ကျော်ရန်"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"ယခင်တစ်ခုသို့ ပြန်သွားရန်"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"အရွယ်အစားပြောင်းရန်"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"အပူရှိန်ကြောင့်ဖုန်းပိတ်ထားသည်"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"သင်၏ဖုန်းသည် ပုံမှန် အလုပ်လုပ်နေပါသည်"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"သင့်ဖုန်းအလွန်ပူနေသည့်အတွက် အေးသွားစေရန် ပိတ်ထားပါသည်။ ယခုပုံမှန် အလုပ်လုပ်ပါပြီ။\n\nအောက်ပါတို့ကိုသုံးလျှင် ပူလာပါမည်-\n • အရင်းအမြစ်များသောအက်ပ်ကို သုံးခြင်း (ဥပမာ ဂိမ်းကစားခြင်း၊ ဗီဒီယိုကြည့်ခြင်း (သို့) လမ်းညွှန်အက်ပ်)\n • ကြီးမားသောဖိုင်များ ဒေါင်းလုဒ် (သို့) အပ်လုဒ်လုပ်ခြင်း\n • အပူရှိန်မြင့်သောနေရာတွင် သုံးခြင်း"</string>
@@ -1045,7 +1046,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"ထိန်းချုပ်မှုများ ပြန်စီစဉ်ရန် ဖိပြီးဆွဲပါ"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"ထိန်းချုပ်မှုအားလုံး ဖယ်ရှားလိုက်သည်"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"အပြောင်းအလဲများကို သိမ်းမထားပါ"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"ထိန်းချုပ်မှုအားလုံး၏ စာရင်းကို ဖွင့်၍မရပါ။"</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"ထိန်းချုပ်မှုများကို ဖွင့်၍မရပါ။ အက်ပ်ဆက်တင်များ ပြောင်းမထားကြောင်း သေချာစေရန် <xliff:g id="APP">%s</xliff:g> အက်ပ်ကို စစ်ဆေးပါ။"</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"ကိုက်ညီသော ထိန်းချုပ်မှုများကို မရရှိနိုင်ပါ"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"အခြား"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"စက်ထိန်းစနစ်သို့ ထည့်ရန်"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"ထည့်ရန်"</string>
@@ -1061,12 +1063,15 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"<xliff:g id="DEVICE">%s</xliff:g> အတွက် အပြောင်းအလဲကို အတည်ပြုပါ"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"ပိုမိုကြည့်ရှုရန် ပွတ်ဆွဲပါ"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"အကြံပြုချက်များ ဖွင့်နေသည်"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"ဤမီဒီယာစက်ရှင်ကို ပိတ်ပါ"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"မီဒီယာ"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"လက်ရှိ စက်ရှင်ကို ဖျောက်ထားမည်။"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"ဖျောက်ထားမည်"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"ဆက်လုပ်ရန်"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"ဆက်တင်များ"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"ရပ်နေသည်၊ အက်ပ်ကို စစ်ဆေးပါ"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"မှားသွားသည်၊ ပြန်စမ်းနေသည်…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"မတွေ့ပါ"</string>
- <string name="controls_error_removed_title" msgid="1207794911208047818">"ထိန်းချုပ်၍ မရတော့ပါ"</string>
+ <string name="controls_error_removed_title" msgid="1207794911208047818">"ထိန်းချုပ်မှု မရနိုင်ပါ"</string>
<string name="controls_error_removed_message" msgid="2885911717034750542">"<xliff:g id="DEVICE">%1$s</xliff:g> အသုံးပြု၍ မရပါ။ ထိန်းချုပ်၍ ရသေးကြောင်းနှင့် အက်ပ်ဆက်တင်များ ပြောင်းမထားကြောင်း သေချာစေရန် <xliff:g id="APPLICATION">%2$s</xliff:g> အက်ပ်ကို စစ်ဆေးပါ။"</string>
<string name="controls_open_app" msgid="483650971094300141">"အက်ပ်ဖွင့်ရန်"</string>
<string name="controls_error_generic" msgid="352500456918362905">"အခြေအနေကို ဖွင့်၍မရပါ"</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index aee2dd288262..1cb6067a704f 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -454,8 +454,8 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Trykk på nytt for å åpne"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Sveip opp for å åpne"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Sveip opp for å prøve igjen"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"Denne enheten administreres av organisasjonen din"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"Denne enheten administreres av <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
+ <string name="do_disclosure_generic" msgid="4896482821974707167">"Denne enheten tilhører organisasjonen din"</string>
+ <string name="do_disclosure_with_name" msgid="2091641464065004091">"Denne enheten tilhører <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="6682125338461375925">"Sveip ikonet for å åpne telefon"</string>
<string name="voice_hint" msgid="7476017460191291417">"Sveip fra ikonet for å åpne talehjelp"</string>
<string name="camera_hint" msgid="4519495795000658637">"Sveip ikonet for å åpne kamera"</string>
@@ -521,21 +521,21 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"Profilen kan overvåkes"</string>
<string name="vpn_footer" msgid="3457155078010607471">"Nettverket kan være overvåket"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"Nettverket kan bli overvåket"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"Organisasjonen din administrerer denne enheten og kan overvåke nettverkstrafikken"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> administrerer denne enheten og kan overvåke nettverkstrafikken"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"Enheten administreres av organisasjonen din og er koblet til <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"Enheten administreres av <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> og er koblet til <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"Enheten administreres av organisasjonen din"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"Enheten administreres av <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"Enheten administreres av organisasjonen din og er koblet til VPN-er"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"Enheten administreres av <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> og er koblet til VPN-er"</string>
+ <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Organisasjonen din eier denne enheten og kan overvåke nettverkstrafikken"</string>
+ <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> eier denne enheten og kan overvåke nettverkstrafikken"</string>
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Denne enheten tilhører organisasjonen din og er koblet til <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Denne enheten tilhører <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> og er koblet til <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Denne enheten tilhører organisasjonen din"</string>
+ <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Denne enheten tilhører <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management_vpns" msgid="371835422690053154">"Denne enheten tilhører organisasjonen din og er koblet til VPN-er"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="4046375645500668555">"Denne enheten tilhører <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> og er koblet til VPN-er"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Organisasjonen din kan overvåke nettverkstrafikken i jobbprofilen din"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> kan overvåke nettverkstrafikken i jobbprofilen din"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Nettverket kan bli overvåket"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"Enheten er koblet til VPN-er"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"Jobbprofilen er koblet til <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"Den personlige profilen er koblet til <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"Enheten er koblet til <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_vpns" msgid="7213546797022280246">"Denne enheten er koblet til VPN-er"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Jobbprofilen din er koblet til <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Den personlige profilen din er koblet til <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Denne enheten er koblet til <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Enhetsadministrasjon"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Profilovervåking"</string>
<string name="monitoring_title" msgid="4063890083735924568">"Nettverksovervåking"</string>
@@ -545,8 +545,8 @@
<string name="disable_vpn" msgid="482685974985502922">"Deaktiver VPN"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"Koble fra VPN"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"Se retningslinjer"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"Enheten din administreres av <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nAdministratoren kan overvåke og administrere innstillinger, bedriftstilgang, apper, data som er tilknyttet enheten, og enhetens posisjonsinformasjon.\n\nKontakt administratoren for å få mer informasjon."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"Enheten din administreres av organisasjonen din.\n\nAdministratoren kan overvåke og administrere innstillinger, bedriftstilgang, apper, data som er tilknyttet enheten, og enhetens posisjonsinformasjon.\n\nKontakt administratoren for å få mer informasjon."</string>
+ <string name="monitoring_description_named_management" msgid="505833016545056036">"Denne enheten tilhører <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nIT-administratoren din kan overvåke og administrere innstillinger, bedriftstilgang, apper, data som er tilknyttet denne enheten, og enhetens posisjonsinformasjon.\n\nKontakt IT-administratoren for å få mer informasjon."</string>
+ <string name="monitoring_description_management" msgid="4308879039175729014">"Denne enheten tilhører organisasjonen din.\n\nIT-administratoren din kan overvåke og administrere innstillinger, bedriftstilgang, apper, data som er tilknyttet denne enheten, og enhetens posisjonsinformasjon.\n\nKontakt IT-administratoren for å få mer informasjon."</string>
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Organisasjonen din installerte en sertifiseringsinstans på denne enheten. Den sikre nettverkstrafikken din kan overvåkes eller endres."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Organisasjonen din installerte en sertifiseringsinstans i jobbprofilen din. Den sikre nettverkstrafikken din kan overvåkes eller endres."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"En sertifiseringsinstans er installert på denne enheten. Den sikre nettverkstrafikken din kan overvåkes eller endres."</string>
@@ -920,6 +920,7 @@
<string name="pip_pause" msgid="1139598607050555845">"Sett på pause"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"Hopp til neste"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"Hopp til forrige"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"Endre størrelse"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"Telefon ble slått av pga varme"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"Telefonen din kjører nå som normalt"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Telefonen din var for varm, så den ble slått av for å kjøles ned. Telefonen din kjører nå som normalt.\n\nTelefonen kan blir for varm hvis du:\n • bruker ressurskrevende apper (for eksempel spill-, video- eller navigeringsapper)\n • laster store filer opp eller ned\n • bruker telefonen ved høy temperatur"</string>
@@ -1013,10 +1014,10 @@
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Systemnavigeringen er oppdatert. For å gjøre endringer, gå til Innstillinger."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Gå til Innstillinger for å oppdatere systemnavigeringen"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Ventemodus"</string>
- <string name="priority_onboarding_title" msgid="2893070698479227616">"Samtalen er satt som prioritert"</string>
+ <string name="priority_onboarding_title" msgid="2893070698479227616">"Samtalen er prioritert"</string>
<string name="priority_onboarding_behavior" msgid="5342816047020432929">"Dette skjer med prioriterte samtaler:"</string>
- <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Vis øverst i samtaledelen"</string>
- <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Vis profilbildet på låseskjermen"</string>
+ <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"De vises øverst i samtaledelen."</string>
+ <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Profilbildet vises på låseskjermen."</string>
<string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Vises som en svevende boble over apper"</string>
<string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Overstyr «Ikke forstyrr»"</string>
<string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Greit"</string>
@@ -1045,7 +1046,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Hold og dra for å flytte kontroller"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"Alle kontroller er fjernet"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Endringene er ikke lagret"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"Listen over alle kontroller kunne ikke lastes inn."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"Kunne ikke laste inn kontrollene. Sjekk <xliff:g id="APP">%s</xliff:g>-appen for å sjekke at appinnstillingene ikke er endret."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"Kompatible kontroller er ikke tilgjengelige"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Annet"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"Legg til i enhetsstyring"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"Legg til"</string>
@@ -1061,8 +1063,11 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"Bekreft endringen for <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Sveip for å se flere"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Laster inn anbefalinger"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"Lukk denne medieøkten"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"Medier"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"Skjul den nåværende økten."</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Skjul"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Gjenoppta"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"Innstillinger"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inaktiv. Sjekk appen"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Feil. Prøver igjen …"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Ikke funnet"</string>
diff --git a/packages/SystemUI/res/values-nb/strings_tv.xml b/packages/SystemUI/res/values-nb/strings_tv.xml
index 22580e645ca0..9b466788d9e0 100644
--- a/packages/SystemUI/res/values-nb/strings_tv.xml
+++ b/packages/SystemUI/res/values-nb/strings_tv.xml
@@ -24,5 +24,5 @@
<string name="pip_close" msgid="5775212044472849930">"Lukk PIP"</string>
<string name="pip_fullscreen" msgid="3877997489869475181">"Fullskjerm"</string>
<string name="mic_active" msgid="5766614241012047024">"Mikrofonen er aktiv"</string>
- <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s brukte mikrofonen din"</string>
+ <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s fikk tilgang til mikrofonen din"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index fda85ccb542c..fdc36d52eb7d 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -454,8 +454,10 @@
<string name="notification_tap_again" msgid="4477318164947497249">"खोल्न पुनः ट्याप गर्नुहोस्"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"खोल्न माथितिर स्वाइप गर्नुहोस्"</string>
<string name="keyguard_retry" msgid="886802522584053523">"फेरि प्रयास गर्न माथितिर स्वाइप गर्नुहोस्"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"तपाईंको संगठनले यस यन्त्रलाई व्यवस्थापन गर्दछ"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"यो यन्त्र <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> द्वारा व्यवस्थापन गरिएको छ"</string>
+ <!-- no translation found for do_disclosure_generic (4896482821974707167) -->
+ <skip />
+ <!-- no translation found for do_disclosure_with_name (2091641464065004091) -->
+ <skip />
<string name="phone_hint" msgid="6682125338461375925">"फोनको लागि आइकनबाट स्वाइप गर्नुहोस्"</string>
<string name="voice_hint" msgid="7476017460191291417">"आवाज सहायताका लागि आइकनबाट स्वाइप गर्नुहोस्"</string>
<string name="camera_hint" msgid="4519495795000658637">"क्यामेराको लागि आइकनबाट स्वाइप गर्नुहोस्"</string>
@@ -510,8 +512,7 @@
<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>
- <!-- no translation found for notification_section_header_incoming (850925217908095197) -->
- <skip />
+ <string name="notification_section_header_incoming" msgid="850925217908095197">"नयाँ"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"मौन"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"सूचनाहरू"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"वार्तालापहरू"</string>
@@ -522,21 +523,33 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"प्रोफाइल अनुगमन हुन सक्छ"</string>
<string name="vpn_footer" msgid="3457155078010607471">"सञ्जाल अनुगमित हुन सक्छ"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"नेटवर्कको अनुगमन गरिने सम्भावना छ"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"तपाईंको संगठनले यो यन्त्रको व्यवस्थापन गर्छ र उसले नेटवर्कको ट्राफिकको अनुगमन गर्नसक्छ"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ले उक्त यन्त्रको व्यवस्थापन गर्छ र उसले नेटवर्क ट्राफिकको अनुगमन गर्न पनि सक्छ"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"तपाईंको संगठनले उक्त यन्त्रको व्यवस्थापन गर्छ र उक्त यन्त्रलाई <xliff:g id="VPN_APP">%1$s</xliff:g> मा जडान गरिएको छ"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ले उक्त यन्त्रको व्यवस्थापन गर्छ र उक्त यन्त्रलाई <xliff:g id="VPN_APP">%2$s</xliff:g> मा जडान गरिएको छ"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"तपाईंको संगठनले उक्त यन्त्रको व्यवस्थापन गर्छ"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ले उक्त यन्त्रको व्यवस्थापन गर्छ"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"तपाईंको संगठनले उक्त यन्त्रको व्यवस्थापन गर्छ र उक्त यन्त्रलाई VPN हरूमा जडान गरिएको छ"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ले उक्त यन्त्रको व्यवस्थापन गर्छ र उक्त यन्त्रलाई VPN हरूमा जडान गरिएको छ"</string>
+ <!-- no translation found for quick_settings_disclosure_management_monitoring (8231336875820702180) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_monitoring (2831423806103479812) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_named_vpn (6096715329056415588) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (5302786161534380104) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management (5515296598440684962) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management (3476472755775165827) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_vpns (371835422690053154) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_vpns (4046375645500668555) -->
+ <skip />
<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_monitoring" msgid="8548019955631378680">"नेटवर्कको अनुगमन हुनसक्छ"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"उक्त यन्त्रलाई VPN हरूमा जडान गरिएको छ"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"कार्य प्रोफाइल <xliff:g id="VPN_APP">%1$s</xliff:g> मा जडान छ"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"व्यक्तिगत प्रोफाइललाई <xliff:g id="VPN_APP">%1$s</xliff:g> मा जडान गरिएको छ"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"उक्त यन्त्रलाई <xliff:g id="VPN_APP">%1$s</xliff:g> मा जडान गरिएको छ"</string>
+ <!-- no translation found for quick_settings_disclosure_vpns (7213546797022280246) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (8117568745060010789) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (5481763430080807797) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_vpn (2350838218824492465) -->
+ <skip />
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"यन्त्रको व्यवस्थापन"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"प्रोफाइल अनुगमन गर्दै"</string>
<string name="monitoring_title" msgid="4063890083735924568">"सञ्जाल अनुगमन"</string>
@@ -546,8 +559,10 @@
<string name="disable_vpn" msgid="482685974985502922">"VPN असक्षम गर्नुहोस्"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"विच्छेद VPN"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"नीतिहरू हेर्नुहोस्"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ले तपाईंको यन्त्रको व्यवस्थापन गर्छ।BREAK\n\nतपाईंका प्रशासकले सेटिङहरू, संस्थागत पहुँच, एपहरू, तपाईंको यन्त्रसँग सम्बन्धित डेटा र तपाईंको यन्त्रको स्थानसम्बन्धी जानकारीको अनुगमन तथा व्यवस्थापन गर्न सक्नुहुन्छ।\n\nथप जानकारीका लागि आफ्नो प्रशासकलाई सम्पर्क गर्नुहोस्।"</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"तपाईंको संगठनले तपाईंको यन्त्रको व्यवस्थापन गर्छ।\n\nतपाईंका प्रशासकले सेटिङहरू, संस्थागत पहुँच, एपहरू, तपाईंको यन्त्रसँग सम्बन्धित डेटा र तपाईंको यन्त्रको स्थानसम्बन्धी जानकारीको अनुगमन तथा व्यवस्थापन गर्न सक्नुहुन्छ।\n\nथप जानकारीका लागि आफ्नो प्रशासकलाई सम्पर्क गर्नुहोस्।"</string>
+ <!-- no translation found for monitoring_description_named_management (505833016545056036) -->
+ <skip />
+ <!-- no translation found for monitoring_description_management (4308879039175729014) -->
+ <skip />
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"तपाईंको संगठनले तपाईंको कार्य प्रोफाइलमा एउटा प्रमाणपत्र सम्बन्धी अख्तियार सुविधा स्थापित गऱ्यो। तपाईंको सुरक्षित नेटवर्क ट्राफिकको अनुगमन वा परिमार्जन हुनसक्छ।"</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"तपाईंको संगठनले तपाईंको कार्य प्रोफाइलमा एउटा प्रमाणपत्र सम्बन्धी अख्तियार सुविधा स्थापना गरेको छ। तपाईंको सुरक्षित नेटवर्क ट्राफिकको अनुगमन वा परिमार्जन हुनसक्छ।"</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"यस यन्त्रमा एउटा प्रमाणपत्र सम्बन्धी अख्तियार सुविधा स्थापना गरिएको छ। तपाईंको सुरक्षित नेटवर्कको ट्राफिकको अनुगमन वा परिमार्जन हुनसक्छ।"</string>
@@ -921,6 +936,7 @@
<string name="pip_pause" msgid="1139598607050555845">"पज गर्नुहोस्"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"अर्कोमा जानुहोस्"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"अघिल्लोमा जानुहोस्"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"आकार बदल्नुहोस्"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"फोन अति नै तातिएकाले चिसिन बन्द भयो"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"तपाईंको फोन अब सामान्य ढंगले चल्दै छ"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"तपाईंको फोन अति नै तातिएकाले चिसिन बन्द भयो। तपाईंको फोन अब सामान्य ढंगले चल्दै छ।\n\nतपाईंले निम्न कुराहरू गर्नुभयो भने तपाईंको फोन अत्यन्त तातो हुनसक्छ:\n • धेरै संसाधन खपत गर्ने एपहरूको प्रयोग (जस्तै गेमिङ, भिडियो वा नेभिगेसन एपहरू)\n • ठूला फाइलहरूको डाउनलोड वा अपलोड\n • उच्च तापक्रममा फोनको प्रयोग"</string>
@@ -1008,16 +1024,16 @@
<string name="bubbles_user_education_title" msgid="5547017089271445797">"बबलहरू प्रयोग गरी कुराकानी गर्नुहोस्"</string>
<string name="bubbles_user_education_description" msgid="1160281719576715211">"नयाँ वार्तालापहरू तैरने आइकन वा बबलका रूपमा देखिन्छन्। बबल खोल्न ट्याप गर्नुहोस्। बबल सार्न सो बबललाई ड्र्याग गर्नुहोस्।"</string>
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"जुनसुकै बेला बबलहरू नियन्त्रण गर्नुहोस्"</string>
- <string name="bubbles_user_education_manage" msgid="1391639189507036423">"यो अनुप्रयोगबाट आएका बबलहरू निष्क्रिय पार्न व्यवस्थापन गर्नुहोस् नामक बटनमा ट्याप गर्नुहोस्"</string>
+ <string name="bubbles_user_education_manage" msgid="1391639189507036423">"यो एपबाट आएका बबलहरू अफ गर्न \"व्यवस्थापन गर्नुहोस्\" बटनमा ट्याप गर्नुहोस्"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"बुझेँ"</string>
<string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> का सेटिङहरू"</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"प्रणालीको नेभिगेसन अद्यावधिक गरियो। परिवर्तन गर्न सेटिङमा जानुहोस्।"</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"प्रणालीको नेभिगेसन अद्यावधिक गर्न सेटिङमा जानुहोस्"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"स्ट्यान्डबाई"</string>
- <string name="priority_onboarding_title" msgid="2893070698479227616">"वार्तालापको प्राथमिकता निर्धारण गरी महत्त्वपूर्ण बनाइयो"</string>
- <string name="priority_onboarding_behavior" msgid="5342816047020432929">"महत्वपूर्ण वार्तालापहरू यहाँ देखिने छन्:"</string>
- <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"वार्तालाप खण्डको सिरानमा देखाइयोस्"</string>
- <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"लक स्क्रिनमा प्रोफाइल तस्बिर देखाइयोस्"</string>
+ <string name="priority_onboarding_title" msgid="2893070698479227616">"वार्तालापको प्राथमिकता निर्धारण गरी \"महत्त्वपूर्ण\" बनाइयो"</string>
+ <string name="priority_onboarding_behavior" msgid="5342816047020432929">"महत्वपूर्ण वार्तालापहरू:"</string>
+ <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"वार्तालाप खण्डको सिरानमा देखिने छन्"</string>
+ <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"लक स्क्रिनमा प्रोफाइल तस्बिर देखाउने छन्"</string>
<string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"एपहरूमाथि तैरिने बबलका रूपमा देखाइयोस्"</string>
<string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"बाधा नपुऱ्याउनुहोस् मोडलाई बेवास्ता गरियोस्"</string>
<string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"बुझेँ"</string>
@@ -1046,7 +1062,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"नियन्त्रणहरूको क्रम मिलाउन तिनलाई थिचेर ड्र्याग गर्नुहोस्"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"सबै नियन्त्रणहरू हटाइए"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"परिवर्तनहरू सुरक्षित गरिएका छैनन्"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"सबै नियन्त्रणहरूको सूची लोड गर्न सकिएन।"</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"नियन्त्रण सुविधाहरू लोड गर्न सकिएन। <xliff:g id="APP">%s</xliff:g> एपका सेटिङ परिवर्तन गरिएका छैनन् भन्ने कुरा सुनिश्चित गर्न यो एप जाँच्नुहोस्।"</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"मिल्दा नियन्त्रण सुविधाहरू उपलब्ध छैनन्"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"अन्य"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"यन्त्र नियन्त्रण गर्ने विजेटहरूको सूचीमा थप्नुहोस्"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"थप्नुहोस्"</string>
@@ -1062,8 +1079,11 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"<xliff:g id="DEVICE">%s</xliff:g> का हकमा गरिएको परिवर्तन पुष्टि गर्नुहोस्"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"थप हेर्न स्वाइप गर्नुहोस्"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"सिफारिसहरू लोड गर्दै"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"यो मिडिया सत्र बन्द गर्नुहोस्"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"मिडिया"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"हालको सत्र लुकाउनुहोस्।"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"लुकाउनुहोस्"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"सुचारु गर्नुहोस्"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"सेटिङ"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"निष्क्रिय छ, एप जाँच गर्नु…"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"त्रुटि भयो, फेरि प्रयास गर्दै…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"फेला परेन"</string>
diff --git a/packages/SystemUI/res/values-night/colors.xml b/packages/SystemUI/res/values-night/colors.xml
index 196357c4794e..cb9e178de243 100644
--- a/packages/SystemUI/res/values-night/colors.xml
+++ b/packages/SystemUI/res/values-night/colors.xml
@@ -81,6 +81,8 @@
<color name="global_screenshot_dismiss_foreground">#FFFFFF</color>
<color name="global_screenshot_background_protection_start">#80000000</color> <!-- 50% black -->
+ <!-- Media -->
+ <color name="media_divider">#85ffffff</color>
<!-- Biometric dialog colors -->
<color name="biometric_dialog_gray">#ff888888</color>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 87f072b9e7dd..c7e0d6ecea07 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -454,8 +454,8 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Tik nog eens om te openen"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Veeg omhoog om te openen"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Veeg omhoog om het opnieuw te proberen"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"Dit apparaat wordt beheerd door je organisatie"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"Dit apparaat wordt beheerd door <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
+ <string name="do_disclosure_generic" msgid="4896482821974707167">"Dit apparaat is eigendom van je organisatie"</string>
+ <string name="do_disclosure_with_name" msgid="2091641464065004091">"Dit apparaat is eigendom van <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="6682125338461375925">"Vegen voor telefoon"</string>
<string name="voice_hint" msgid="7476017460191291417">"Vegen vanaf pictogram voor spraakassistent"</string>
<string name="camera_hint" msgid="4519495795000658637">"Vegen voor camera"</string>
@@ -521,21 +521,21 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"Profiel kan worden gecontroleerd"</string>
<string name="vpn_footer" msgid="3457155078010607471">"Netwerk kan worden gecontroleerd"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"Netwerk kan worden gecontroleerd"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"Je organisatie beheert dit apparaat en kan het netwerkverkeer bijhouden"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> beheert dit apparaat en kan het netwerkverkeer bijhouden"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"Apparaat wordt beheerd door je organisatie en is verbonden met <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"Apparaat wordt beheerd door <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> en is verbonden met <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"Apparaat wordt beheerd door je organisatie"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"Apparaat wordt beheerd door <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"Apparaat wordt beheerd door je organisatie en is verbonden met VPN\'s"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"Apparaat wordt beheerd door <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> en is verbonden met VPN\'s"</string>
+ <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Je organisatie is eigenaar van dit apparaat en kan het netwerkverkeer bijhouden"</string>
+ <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> is eigenaar van dit apparaat en kan het netwerkverkeer bijhouden"</string>
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Dit apparaat is eigendom van je organisatie en is verbonden met <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Dit apparaat is eigendom van <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> en is verbonden met <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Dit apparaat is eigendom van je organisatie"</string>
+ <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Dit apparaat is eigendom van <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management_vpns" msgid="371835422690053154">"Dit apparaat is eigendom van je organisatie en is verbonden met VPN\'s"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="4046375645500668555">"Dit apparaat is eigendom van <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> en is verbonden met VPN\'s"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Je organisatie kan het netwerkverkeer in je werkprofiel bijhouden"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> kan het netwerkverkeer in je werkprofiel bijhouden"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Netwerk kan worden bijgehouden"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"Apparaat verbonden met VPN\'s"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"Werkprofiel verbonden met <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"Persoonlijk profiel verbonden met <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"Apparaat verbonden met <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_vpns" msgid="7213546797022280246">"Dit apparaat is verbonden met VPN\'s"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Je werkprofiel is verbonden met <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Je persoonlijke profiel is verbonden met <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Dit apparaat is verbonden met <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Apparaatbeheer"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Profielcontrole"</string>
<string name="monitoring_title" msgid="4063890083735924568">"Netwerkcontrole"</string>
@@ -545,8 +545,8 @@
<string name="disable_vpn" msgid="482685974985502922">"VPN uitschakelen"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"Verbinding met VPN verbreken"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"Beleid bekijken"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"Je apparaat wordt beheerd door <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nJe beheerder kan instellingen, zakelijke toegang, apps, aan je apparaat gekoppelde gegevens en de locatiegegevens van je apparaat controleren en beheren.\n\nNeem contact op met je beheerder voor meer informatie."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"Je apparaat wordt beheerd door je organisatie.\n\nJe beheerder kan instellingen, zakelijke toegang, apps, aan je apparaat gekoppelde gegevens en de locatiegegevens van je apparaat controleren en beheren.\n\nNeem contact op met je beheerder voor meer informatie."</string>
+ <string name="monitoring_description_named_management" msgid="505833016545056036">"Dit apparaat is eigendom van <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nJe IT-beheerder kan instellingen, zakelijke toegang, apps, aan je apparaat gekoppelde gegevens en de locatiegegevens van je apparaat bekijken en beheren.\n\nNeem contact op met je IT-beheerder voor meer informatie."</string>
+ <string name="monitoring_description_management" msgid="4308879039175729014">"Dit apparaat is eigendom van je organisatie.\n\nJe IT-beheerder kan instellingen, zakelijke toegang, apps, aan je apparaat gekoppelde gegevens en de locatiegegevens van je apparaat bekijken en beheren.\n\nNeem contact op met je IT-beheerder voor meer informatie."</string>
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Je organisatie heeft een certificeringsinstantie geïnstalleerd op dit apparaat. Je beveiligde netwerkverkeer kan worden bijgehouden of aangepast."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Je organisatie heeft een certificeringsinstantie geïnstalleerd in je werkprofiel. Je beveiligde netwerkverkeer kan worden bijgehouden of aangepast."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Er is een certificeringsinstantie geïnstalleerd op dit apparaat. Je beveiligde netwerkverkeer kan worden bijgehouden of aangepast."</string>
@@ -920,6 +920,7 @@
<string name="pip_pause" msgid="1139598607050555845">"Onderbreken"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"Doorgaan naar volgende"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"Teruggaan naar vorige"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"Formaat aanpassen"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"Telefoon uitgezet wegens hitte"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"Je telefoon presteert nu weer zoals gebruikelijk"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Je telefoon was te warm en is uitgeschakeld om af te koelen. Je telefoon presteert nu weer zoals gebruikelijk.\n\nJe telefoon kan warm worden als je:\n • bronintensieve apps gebruikt (zoals game-, video-, of navigatie-apps),\n • grote bestanden up- of downloadt,\n • je telefoon gebruikt bij hoge temperaturen."</string>
@@ -1014,7 +1015,7 @@
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Ga naar Instellingen om de systeemnavigatie te updaten"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Stand-by"</string>
<string name="priority_onboarding_title" msgid="2893070698479227616">"Gesprek ingesteld als prioriteit"</string>
- <string name="priority_onboarding_behavior" msgid="5342816047020432929">"Bij prioriteitsgesprekken gebeurt het volgende:"</string>
+ <string name="priority_onboarding_behavior" msgid="5342816047020432929">"Prioriteitsgesprekken:"</string>
<string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Worden bovenaan het gespreksgedeelte weergegeven"</string>
<string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Tonen profielafbeelding op vergrendelscherm"</string>
<string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Worden als zwevende ballon weergegeven vóór apps"</string>
@@ -1045,7 +1046,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Houd vast en sleep om de bedieningselementen opnieuw in te delen"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"Alle bedieningselementen verwijderd"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Wijzigingen zijn niet opgeslagen"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"Kan lijst met alle bedieningselementen niet laden."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"Bedieningselementen kunnen niet worden geladen. Check de <xliff:g id="APP">%s</xliff:g>-app om na te gaan of de app-instellingen niet zijn gewijzigd."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"Geen geschikte bedieningselementen beschikbaar."</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Overig"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"Toevoegen aan apparaatbediening"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"Toevoegen"</string>
@@ -1061,8 +1063,11 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"Bevestig de wijziging voor <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Swipe om meer te zien"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Aanbevelingen laden"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"Deze mediasessie sluiten"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"Media"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"De huidige sessie verbergen."</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Verbergen"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Hervatten"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"Instellingen"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inactief, check de app"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Fout. Opnieuw proberen…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Niet gevonden"</string>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index 426bd2ec1ada..95d6f5f5a154 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -454,8 +454,10 @@
<string name="notification_tap_again" msgid="4477318164947497249">"ଖୋଲିବା ପାଇଁ ପୁଣି ଟାପ୍‍ କରନ୍ତୁ"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"ଖୋଲିବା ପାଇଁ ଉପରକୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ"</string>
<string name="keyguard_retry" msgid="886802522584053523">"ପୁଣି ଚେଷ୍ଟା କରିବା ପାଇଁ ଉପରକୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"ଏହି ଡିଭାଇସ୍‌ ଆପଣଙ୍କ ସଂସ୍ଥା ଦ୍ୱାରା ପରିଚାଳିତ।"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"ଏହି ଡିଭାଇସ୍‌ <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ଦ୍ୱାରା ପରିଚାଳିତ ହେଉଛି"</string>
+ <!-- no translation found for do_disclosure_generic (4896482821974707167) -->
+ <skip />
+ <!-- no translation found for do_disclosure_with_name (2091641464065004091) -->
+ <skip />
<string name="phone_hint" msgid="6682125338461375925">"ଫୋନ୍‍ ପାଇଁ ଆଇକନରୁ ସ୍ୱାଇପ୍‍ କରନ୍ତୁ"</string>
<string name="voice_hint" msgid="7476017460191291417">"ଭଏସ୍‍ ସହାୟକ ପାଇଁ ଆଇକନରୁ ସ୍ୱାଇପ୍‍ କରନ୍ତୁ"</string>
<string name="camera_hint" msgid="4519495795000658637">"କ୍ୟାମେରା ପାଇଁ ଆଇକନରୁ ସ୍ୱାଇପ୍‍ କରନ୍ତୁ"</string>
@@ -510,8 +512,7 @@
<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>
- <!-- no translation found for notification_section_header_incoming (850925217908095197) -->
- <skip />
+ <string name="notification_section_header_incoming" msgid="850925217908095197">"ନୂଆ"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"ନୀରବ"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"ବାର୍ତ୍ତାଳାପଗୁଡ଼ିକ"</string>
@@ -522,21 +523,33 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"ପ୍ରୋଫାଇଲ୍ ନିରୀକ୍ଷଣ କରାଯାଇପାରେ।"</string>
<string name="vpn_footer" msgid="3457155078010607471">"ନେଟ୍‌ୱର୍କ ନୀରିକ୍ଷଣ କରାଯାଇପାରେ"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"ନେଟ୍‌ୱର୍କକୁ ନିରୀକ୍ଷଣ କରାଯାଇପାରେ"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"ଆପଣଙ୍କ ସଂସ୍ଥା ଏହି ଡିଭାଇସକୁ ପରିଚାଳନା କରନ୍ତି ଏବଂ ନେଟୱର୍କ ଟ୍ରାଫିକ୍‍ ନୀରିକ୍ଷଣ କରିପାରନ୍ତି"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ଏହି ଡିଭାଇସକୁ ପରିଚାଳନା କରନ୍ତି ଏବଂ ନେଟୱର୍କ ଟ୍ରାଫିକ୍‍ ନୀରିକ୍ଷଣ କରନ୍ତି"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"ଡିଭାଇସ୍‌ ଆପଣଙ୍କ ସଂସ୍ଥା ଦ୍ୱାରା ପରିଚାଳିତ ଏବଂ <xliff:g id="VPN_APP">%1$s</xliff:g>ରେ ସଂଯୁକ୍ତ"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"ଡିଭାଇସ୍‌ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ଦ୍ୱାରା ପରିଚାଳିତ ଏବଂ <xliff:g id="VPN_APP">%2$s</xliff:g>ରେ ସଂଯୁକ୍ତ"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"ଡିଭାଇସ୍‌ ଆପଣଙ୍କ ସଂସ୍ଥା ଦ୍ୱାରା ପରିଚାଳିତ"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"ଡିଭାଇସ୍‍ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ଦ୍ୱାରା ପରିଚାଳିତ ହେଉଛି"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"ଡିଭାଇସ୍‌ ଆପଣଙ୍କ ସଂସ୍ଥା ଦ୍ୱାରା ପରିଚାଳିତ ଏବଂ VPNଗୁଡ଼ିକରେ ସଂଯୁକ୍ତ"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"ଡିଭାଇସ୍‌ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ଦ୍ୱାରା ପରିଚାଳିତ ଏବଂ VPNଗୁଡ଼ିକରେ ସଂଯୁକ୍ତ"</string>
+ <!-- no translation found for quick_settings_disclosure_management_monitoring (8231336875820702180) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_monitoring (2831423806103479812) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_named_vpn (6096715329056415588) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (5302786161534380104) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management (5515296598440684962) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management (3476472755775165827) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_vpns (371835422690053154) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_vpns (4046375645500668555) -->
+ <skip />
<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_monitoring" msgid="8548019955631378680">"ନେଟୱର୍କ ନୀରିକ୍ଷଣ କରାଯାଇପାରେ"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"ଡିଭାଇସ୍‍ VPNଗୁଡ଼ିକରେ ସଂଯୁକ୍ତ"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"ୱର୍କ ପ୍ରୋଫାଇଲ୍‍ <xliff:g id="VPN_APP">%1$s</xliff:g>ରେ ସଂଯୁକ୍ତ"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"ବ୍ୟକ୍ତିଗତ ପ୍ରୋଫାଇଲ୍‍ <xliff:g id="VPN_APP">%1$s</xliff:g>ରେ ସଂଯୁକ୍ତ"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"ଡିଭାଇସ୍‍ <xliff:g id="VPN_APP">%1$s</xliff:g>ରେ ସଂଯୁକ୍ତ"</string>
+ <!-- no translation found for quick_settings_disclosure_vpns (7213546797022280246) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (8117568745060010789) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (5481763430080807797) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_vpn (2350838218824492465) -->
+ <skip />
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"ଡିଭାଇସ୍‌ ପରିଚାଳନା"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"ପ୍ରୋଫାଇଲ୍ ନୀରିକ୍ଷଣ"</string>
<string name="monitoring_title" msgid="4063890083735924568">"ନେଟ୍‌ୱର୍କ ନୀରିକ୍ଷଣ"</string>
@@ -546,8 +559,10 @@
<string name="disable_vpn" msgid="482685974985502922">"VPN ଅକ୍ଷମ କରନ୍ତୁ"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"VPN ବିଛିନ୍ନ କରନ୍ତୁ"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"ପଲିସୀ ଦେଖନ୍ତୁ"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"ଆପଣଙ୍କ ଡିଭାଇସ୍‍ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ଦ୍ୱାରା ପରିଚାଳନା କରାଯାଉଛି।.\n\nଆପଣଙ୍କ ଆଡମିନ୍‍ ସେଟିଙ୍ଗ, କର୍ପୋରେଟ୍‍ ଆକ୍ସେସ୍‍, ଆପ୍‍, ଆପଣଙ୍କ ଡିଭାଇସ୍‍ ସମ୍ବନ୍ଧୀୟ ଡାଟା ଏବଂ ଆପଣଙ୍କ ଡିଭାଇସର ଲୋକେସନ୍‍ ନିରୀକ୍ଷଣ ଓ ପରିଚାଳନା କରିପାରନ୍ତି।\n\nଅଧିକ ସୂଚନା ପାଇଁ, ନିଜ ଆଡମିନଙ୍କ ସହ ଯୋଗାଯୋଗ କରନ୍ତୁ।"</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"ଆପଣଙ୍କ ଡିଭାଇସ୍‍ ଆପଣଙ୍କ ସଂସ୍ଥା ଦ୍ୱାରା ପରିଚାଳନା କରାଯାଉଛି।\n\nଆପଣଙ୍କ ଆଡମିନ୍‍ ସେଟିଙ୍ଗ, କର୍ପୋରେଟ୍‍ ଆକ୍ସେସ୍‍, ଆପ୍‍, ଆପଣଙ୍କ ଡିଭାଇସ୍‍ ସମ୍ବନ୍ଧୀୟ ଡାଟା ଏବଂ ଆପଣଙ୍କ ଡିଭାଇସର ଲୋକେସନ୍‍ ନିରୀକ୍ଷଣ ଓ ପରିଚାଳନା କରିପାରନ୍ତି।\n\nଅଧିକ ସୂଚନା ପାଇଁ, ନିଜ ଆଡମିନଙ୍କ ସହ ଯୋଗାଯୋଗ କରନ୍ତୁ।"</string>
+ <!-- no translation found for monitoring_description_named_management (505833016545056036) -->
+ <skip />
+ <!-- no translation found for monitoring_description_management (4308879039175729014) -->
+ <skip />
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"ଏହି ଡିଭାଇସରେ ଆପଣଙ୍କ ସଂସ୍ଥା ଏକ ସର୍ଟିଫିକେଟ୍‍ ଅଥରିଟି ଇନଷ୍ଟଲ୍‍ କରିଛନ୍ତି। ଆପଣଙ୍କ ସୁରକ୍ଷିତ ନେଟୱର୍କ ଟ୍ରାଫିକ୍‍ ନୀରିକ୍ଷଣ କିମ୍ବା ସଂଶୋଧନ କରାଯାଇ ପାରେ।"</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"ଆପଣଙ୍କ ୱର୍କ ପ୍ରୋଫାଇଲରେ ଆପଣଙ୍କ ସଂସ୍ଥା ଏକ ସର୍ଟିଫିକେଟ୍‍ ଅଥରିଟି ଇନଷ୍ଟଲ୍‍ କରିଛନ୍ତି। ଆପଣଙ୍କ ସୁରକ୍ଷିତ ନେଟୱର୍କ ଟ୍ରାଫିକ୍‍ ନୀରିକ୍ଷଣ କିମ୍ବା ସଂଶୋଧନ କରାଯାଇ ପାରେ।"</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"ଏହି ଡିଭାଇସରେ ଏକ ସର୍ଟିଫିକେଟ୍‍ ଅଥରିଟି ଇନଷ୍ଟଲ୍‍ କରାଯାଇଛି। ଆପଣଙ୍କ ସୁରକ୍ଷିତ ନେଟୱର୍କ ଟ୍ରାଫିକ୍‍ ନୀରିକ୍ଷଣ କିମ୍ବା ସଂଶୋଧନ କରାଯାଇ ପାରେ।"</string>
@@ -921,6 +936,7 @@
<string name="pip_pause" msgid="1139598607050555845">"ପଜ୍‍ କରନ୍ତୁ"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"ପରବର୍ତ୍ତୀକୁ ଯାଆନ୍ତୁ"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"ପୂର୍ବବର୍ତ୍ତୀକୁ ଛାଡ଼ନ୍ତୁ"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"ରିସାଇଜ୍ କରନ୍ତୁ"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"ଗରମ ହେତୁ ଫୋନ୍‍ ଅଫ୍‍ କରିଦିଆଗଲା"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"ଆପଣଙ୍କ ଫୋନ୍‍ ବର୍ତ୍ତମାନ ସାମାନ୍ୟ ଅବସ୍ଥାରେ ଚାଲୁଛି"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"ଆପଣଙ୍କ ଫୋନ୍‍ ବହୁତ ଗରମ ଥିଲା, ତେଣୁ ଏହାକୁ ଥଣ୍ଡା କରାଯିବାକୁ ଅଫ୍‍ କରିଦିଆଗଲା। ଆପଣଙ୍କ ଫୋନ୍‍ ବର୍ତ୍ତମାନ ସାମାନ୍ୟ ଅବସ୍ଥାରେ ଚାଲୁଛି।\n\nଆପଣଙ୍କ ଫୋନ୍‍ ଅଧିକ ଗରମ ହୋଇଯାଇପାରେ ଯଦି ଆପଣ:\n • ରିସୋର୍ସ-ଇଣ୍ଟେନସିଭ୍‍ ଆପ୍‍ (ଯେପରିକି ଗେମିଙ୍ଗ, ଭିଡିଓ, କିମ୍ବା ନେଭିଗେସନ୍‍ ଆପ୍‍) ବ୍ୟବହାର କରନ୍ତି\n • ବଡ ଫାଇଲ୍‍ ଡାଉନଲୋଡ୍ କିମ୍ବା ଅପଲୋଡ୍‍ କରନ୍ତି\n • ଅଧିକ ତାପମାତ୍ରାରେ ଆପଣଙ୍କ ଫୋନ୍‍ ବ୍ୟବହାର କରନ୍ତି"</string>
@@ -1014,8 +1030,8 @@
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"ସିଷ୍ଟମ୍ ନାଭିଗେସନ୍ ଅପ୍‌ଡେଟ୍ ହୋଇଛି। ପରିବର୍ତ୍ତନ କରିବା ପାଇଁ, ସେଟିଂସ୍‌କୁ ଯାଆନ୍ତୁ।"</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"ସିଷ୍ଟମ୍ ନାଭିଗେସନ୍ ଅପ୍‌ଡେଟ୍ କରିବା ପାଇଁ ସେଟିଂସ୍‍କୁ ଯାଆନ୍ତୁ"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"ଷ୍ଟାଣ୍ଡବାଏ"</string>
- <string name="priority_onboarding_title" msgid="2893070698479227616">"ବାର୍ତ୍ତାଳାପ ପ୍ରାଥମିକରେ ସେଟ୍ କରାଯାଇଛି"</string>
- <string name="priority_onboarding_behavior" msgid="5342816047020432929">"ପ୍ରାଥମିକ ବାର୍ତ୍ତାଳାପଗୁଡ଼ିକ ଏଠାରେ ଦେଖାଯିବ:"</string>
+ <string name="priority_onboarding_title" msgid="2893070698479227616">"ବାର୍ତ୍ତାଳାପ ପ୍ରାଥମିକତାରେ ସେଟ୍ କରାଯାଇଛି"</string>
+ <string name="priority_onboarding_behavior" msgid="5342816047020432929">"ପ୍ରାଥମିକତା ଦିଆଯାଇଥିବା ବାର୍ତ୍ତାଳାପଗୁଡ଼ିକ ଏଠାରେ ଦେଖାଯିବ:"</string>
<string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"ବାର୍ତ୍ତାଳାପ ବିଭାଗର ଶୀର୍ଷରେ ଦେଖାନ୍ତୁ"</string>
<string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"ଲକ୍ ସ୍କ୍ରିନରେ ପ୍ରୋଫାଇଲ୍ ଛବି ଦେଖାନ୍ତୁ"</string>
<string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"ଆପଗୁଡ଼ିକ ଉପରେ ଫ୍ଲୋଟିଂ ବବଲ୍ ପରି ଦେଖାଯିବ"</string>
@@ -1026,7 +1042,7 @@
<string name="magnification_window_title" msgid="4863914360847258333">"ମ୍ୟାଗ୍ନିଫିକେସନ୍ ୱିଣ୍ଡୋ"</string>
<string name="magnification_controls_title" msgid="8421106606708891519">"ମ୍ୟାଗ୍ନିଫିକେସନ୍ ୱିଣ୍ଡୋ ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକ"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"ଡିଭାଇସ୍ ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକ"</string>
- <string name="quick_controls_subtitle" msgid="1667408093326318053">"ଆପଣଙ୍କ ସଂଯୁକ୍ତ ଥିବା ଡିଭାଇସଗୁଡ଼ିକ ପାଇଁ ନିୟନ୍ତ୍ରଣ ଯୋଗ କରନ୍ତୁ"</string>
+ <string name="quick_controls_subtitle" msgid="1667408093326318053">"ଆପଣଙ୍କ ସଂଯୁକ୍ତ ଡିଭାଇସଗୁଡ଼ିକ ପାଇଁ ନିୟନ୍ତ୍ରଣ ଯୋଗ କରନ୍ତୁ"</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"ଡିଭାଇସ୍ ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକୁ ସେଟ୍ ଅପ୍ କରନ୍ତୁ"</string>
<string name="quick_controls_setup_subtitle" msgid="1681506617879773824">"ଆପଣଙ୍କ ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକୁ ଆକ୍ସେସ୍ କରିବାକୁ ପାୱାର ବଟନକୁ ଧରି ରଖନ୍ତୁ"</string>
<string name="controls_providers_title" msgid="6879775889857085056">"ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକୁ ଯୋଗ କରିବାକୁ ଆପ୍ ବାଛନ୍ତୁ"</string>
@@ -1046,7 +1062,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକ ପୁଣି ସଜାଇବାକୁ ସେଗୁଡ଼ିକୁ ଧରି ଟାଣନ୍ତୁ"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"ସମସ୍ତ ନିୟନ୍ତ୍ରଣ କାଢ଼ି ଦିଆଯାଇଛି"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"ପରିବର୍ତ୍ତନଗୁଡ଼ିକ ସେଭ୍ କରାଯାଇନାହିଁ"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"ସବୁ ନିୟନ୍ତ୍ରଣର ତାଲିକା ଲୋଡ୍ କରିପାରିଲା ନାହିଁ।"</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକୁ ଲୋଡ୍ କରାଯାଇପାରିଲା ନାହିଁ। ଆପ୍ ସେଟିଂସ୍ ପରିବର୍ତ୍ତନ ହୋଇନାହିଁ ବୋଲି ନିଶ୍ଚିତ କରିବାକୁ <xliff:g id="APP">%s</xliff:g> ଆପ୍ ଯାଞ୍ଚ କରନ୍ତୁ।"</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"ସୁସଙ୍ଗତ ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକ ଉପଲବ୍ଧ ନାହିଁ"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"ଅନ୍ୟ"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"ଡିଭାଇସ୍ ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକରେ ଯୋଗ କରନ୍ତୁ"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"ଯୋଗ କରନ୍ତୁ"</string>
@@ -1062,8 +1079,11 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"<xliff:g id="DEVICE">%s</xliff:g> ପାଇଁ ପରିବର୍ତ୍ତନ ସୁନିଶ୍ଚିତ କରନ୍ତୁ"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"ଅଧିକ ଦେଖିବାକୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"ସୁପାରିଶଗୁଡ଼ିକ ଲୋଡ୍ କରାଯାଉଛି"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"ଏହି ମିଡିଆ ସେସନ୍ ବନ୍ଦ କରନ୍ତୁ"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"ମିଡିଆ"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"ବର୍ତ୍ତମାନର ସେସନ୍ ଲୁଚାନ୍ତୁ।"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"ଲୁଚାନ୍ତୁ"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"ପୁଣି ଆରମ୍ଭ କରନ୍ତୁ"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"ସେଟିଂସ୍"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"ନିଷ୍କ୍ରିୟ ଅଛି, ଆପ ଯାଞ୍ଚ କରନ୍ତୁ"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"ତ୍ରୁଟି, ପୁଣି ଚେଷ୍ଟା କରୁଛି…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"ମିଳିଲା ନାହିଁ"</string>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index ccafc49614bb..43ab5aae7d12 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -454,8 +454,10 @@
<string name="notification_tap_again" msgid="4477318164947497249">"ਖੋਲ੍ਹਣ ਲਈ ਦੁਬਾਰਾ ਟੈਪ ਕਰੋ"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"ਖੋਲ੍ਹਣ ਲਈ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰੋ"</string>
<string name="keyguard_retry" msgid="886802522584053523">"ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰਨ ਲਈ ਉੱਤੇ ਵੱਲ ਸਵਾਈਪ ਕਰੋ"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"ਇਸ ਡੀਵਾਈਸ ਦਾ ਪ੍ਰਬੰਧਨ ਤੁਹਾਡੇ ਸੰਗਠਨ ਵੱਲੋਂ ਕੀਤਾ ਜਾਂਦਾ ਹੈ"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"ਇਹ ਡੀਵਾਈਸ <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ਵੱਲੋਂ ਪ੍ਰਬੰਧਿਤ ਕੀਤਾ ਗਿਆ ਹੈ"</string>
+ <!-- no translation found for do_disclosure_generic (4896482821974707167) -->
+ <skip />
+ <!-- no translation found for do_disclosure_with_name (2091641464065004091) -->
+ <skip />
<string name="phone_hint" msgid="6682125338461375925">"ਫ਼ੋਨ ਲਈ ਪ੍ਰਤੀਕ ਤੋਂ ਸਵਾਈਪ ਕਰੋ"</string>
<string name="voice_hint" msgid="7476017460191291417">"ਅਵਾਜ਼ੀ ਸਹਾਇਕ ਲਈ ਪ੍ਰਤੀਕ ਤੋਂ ਸਵਾਈਪ ਕਰੋ"</string>
<string name="camera_hint" msgid="4519495795000658637">"ਕੈਮਰੇ ਲਈ ਪ੍ਰਤੀਕ ਤੋਂ ਸਵਾਈਪ ਕਰੋ"</string>
@@ -510,7 +512,7 @@
<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>
- <string name="notification_section_header_incoming" msgid="850925217908095197">"ਨਵਾਂ"</string>
+ <string name="notification_section_header_incoming" msgid="850925217908095197">"ਨਵੀਆਂ"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"ਸ਼ਾਂਤ"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"ਸੂਚਨਾਵਾਂ"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"ਗੱਲਾਂਬਾਤਾਂ"</string>
@@ -521,21 +523,33 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"ਪ੍ਰੋਫਾਈਲ ਦਾ ਨਿਰੀਖਣ ਕੀਤਾ ਜਾ ਸਕਦਾ ਹੈ"</string>
<string name="vpn_footer" msgid="3457155078010607471">"ਨੈੱਟਵਰਕ ਦਾ ਨਿਰੀਖਣ ਕੀਤਾ ਜਾ ਸਕਦਾ ਹੈ"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"ਹੋ ਸਕਦਾ ਹੈ ਨੈੱਟਵਰਕ ਦੀ ਨਿਗਰਾਨੀ ਹੋ ਰਹੀ ਹੋਵੇ"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"ਤੁਹਾਡੀ ਸੰਸਥਾ ਇਸ ਡੀਵਾਈਸ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰਦੀ ਹੈ ਅਤੇ ਨੈੱਟਵਰਕ ਟਰੈਫਿਕ ਦੀ ਨਿਗਰਾਨੀ ਕਰ ਸਕਦੀ ਹੈ"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ਇਸ ਡੀਵਾਈਸ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰਦੀ ਹੈ ਅਤੇ ਨੈੱਟਵਰਕ ਟਰੈਫਿਕ ਦੀ ਨਿਗਰਾਨੀ ਕਰ ਸਕਦੀ ਹੈ"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"ਡੀਵਾਈਸ ਦਾ ਪ੍ਰਬੰਧਨ ਤੁਹਾਡੀ ਸੰਸਥਾ ਵੱਲੋਂ ਕੀਤਾ ਜਾਂਦਾ ਹੈ ਅਤੇ ਇਹ <xliff:g id="VPN_APP">%1$s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਹੈ"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"ਡੀਵਾਈਸ ਦਾ ਪ੍ਰਬੰਧਨ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ਵੱਲੋਂ ਕੀਤਾ ਜਾਂਦਾ ਹੈ ਅਤੇ ਇਹ <xliff:g id="VPN_APP">%2$s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਹੈ"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"ਡੀਵਾਈਸ ਦਾ ਪ੍ਰਬੰਧਨ ਤੁਹਾਡੀ ਸੰਸਥਾ ਵੱਲੋਂ ਕੀਤਾ ਜਾਂਦਾ ਹੈ"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"ਡੀਵਾਈਸ ਦਾ ਪ੍ਰਬੰਧਨ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ਵੱਲੋਂ ਕੀਤਾ ਜਾਂਦਾ ਹੈ"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"ਡੀਵਾਈਸ ਦਾ ਪ੍ਰਬੰਧਨ ਤੁਹਾਡੀ ਸੰਸਥਾ ਵੱਲੋਂ ਕੀਤਾ ਜਾਂਦਾ ਹੈ ਅਤੇ ਇਹ VPNs ਨਾਲ ਕਨੈਕਟ ਹੈ"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"ਡੀਵਾਈਸ ਦਾ ਪ੍ਰਬੰਧਨ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ਵੱਲੋਂ ਕੀਤਾ ਜਾਂਦਾ ਹੈ ਅਤੇ ਇਹ VPNs ਨਾਲ ਕਨੈਕਟ ਹੈ"</string>
+ <!-- no translation found for quick_settings_disclosure_management_monitoring (8231336875820702180) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_monitoring (2831423806103479812) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_named_vpn (6096715329056415588) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (5302786161534380104) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management (5515296598440684962) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management (3476472755775165827) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_vpns (371835422690053154) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_vpns (4046375645500668555) -->
+ <skip />
<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_monitoring" msgid="8548019955631378680">"ਨੈੱਟਵਰਕ ਦੀ ਨਿਗਰਾਨੀ ਕੀਤੀ ਜਾ ਸਕਦੀ ਹੈ"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"ਡੀਵਾਈਸ VPNs ਨਾਲ ਕਨੈਕਟ ਹੈ"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ <xliff:g id="VPN_APP">%1$s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ ਗਿਆ"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"ਨਿੱਜੀ ਪ੍ਰੋਫਾਈਲ <xliff:g id="VPN_APP">%1$s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਹੈ"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"ਡੀਵਾਈਸ <xliff:g id="VPN_APP">%1$s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਹੈ"</string>
+ <!-- no translation found for quick_settings_disclosure_vpns (7213546797022280246) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (8117568745060010789) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (5481763430080807797) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_vpn (2350838218824492465) -->
+ <skip />
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"ਡੀਵਾਈਸ ਪ੍ਰਬੰਧਨ"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"ਪ੍ਰੋਫਾਈਲ ਦਾ ਨਿਰੀਖਣ ਕਰਨਾ"</string>
<string name="monitoring_title" msgid="4063890083735924568">"ਨੈੱਟਵਰਕ ਨਿਰੀਖਣ ਕਰ ਰਿਹਾ ਹੈ"</string>
@@ -545,8 +559,10 @@
<string name="disable_vpn" msgid="482685974985502922">"VPN ਨੂੰ ਅਸਮਰੱਥ ਬਣਾਓ"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"VPN ਨੂੰ ਡਿਸਕਨੈਕਟ ਕਰੋ"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"ਨੀਤੀਆਂ ਦੇਖੋ"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਦਾ ਪ੍ਰਬੰਧਨ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ਵੱਲੋਂ ਕੀਤਾ ਜਾਂਦਾ ਹੈ।\n\nਤੁਹਾਡਾ ਪ੍ਰਸ਼ਾਸਕ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਨਾਲ ਸਬੰਧਿਤ ਸੈਟਿੰਗਾਂ, ਕਾਰਪੋਰੇਟ ਪਹੁੰਚ, ਐਪਾਂ, ਡਾਟਾ ਅਤੇ ਤੁਹਾਡੀ ਡੀਵਾਈਸ ਦੀ ਟਿਕਾਣਾ ਜਾਣਕਾਰੀ ਦੀ ਨਿਗਰਾਨੀ ਅਤੇ ਉਹਨਾਂ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰ ਸਕਦਾ ਹੈ।\n\nਹੋਰ ਜਾਣਕਾਰੀ ਲਈ, ਆਪਣੇ ਪ੍ਰਸ਼ਾਸਕ ਨੂੰ ਸੰਪਰਕ ਕਰੋ।"</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਦਾ ਪ੍ਰਬੰਧਨ ਤੁਹਾਡੀ ਸੰਸਥਾ ਵੱਲੋਂ ਕੀਤਾ ਜਾਂਦਾ ਹੈ।\n\nਤੁਹਾਡਾ ਪ੍ਰਸ਼ਾਸਕ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਨਾਲ ਸਬੰਧਿਤ ਸੈਟਿੰਗਾਂ, ਕਾਰਪੋਰੇਟ ਪਹੁੰਚ, ਐਪਾਂ, ਡਾਟਾ ਅਤੇ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਦੀ ਟਿਕਾਣਾ ਜਾਣਕਾਰੀ ਦੀ ਨਿਗਰਾਨੀ ਕਰ ਸਕਦਾ ਹੈ ਅਤੇ ਉਹਨਾਂ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰ ਸਕਦਾ ਹੈ।\n\nਹੋਰ ਜਾਣਕਾਰੀ ਲਈ, ਆਪਣੇ ਪ੍ਰਸ਼ਾਸਕ ਨੂੰ ਸੰਪਰਕ ਕਰੋ।"</string>
+ <!-- no translation found for monitoring_description_named_management (505833016545056036) -->
+ <skip />
+ <!-- no translation found for monitoring_description_management (4308879039175729014) -->
+ <skip />
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"ਤੁਹਾਡੀ ਸੰਸਥਾ ਵੱਲੋਂ ਇਸ ਡੀਵਾਈਸ \'ਤੇ ਇੱਕ ਪ੍ਰਮਾਣ-ਪੱਤਰ ਅਥਾਰਟੀ ਸਥਾਪਤ ਕੀਤੀ ਗਈ ਹੈ। ਤੁਹਾਡੇ ਸੁਰੱਖਿਅਤ ਨੈੱਟਵਰਕ ਟਰੈਫਿਕ ਦੀ ਨਿਗਰਾਨੀ ਕੀਤੀ ਜਾ ਸਕਦੀ ਹੈ ਜਾਂ ਉਸਨੂੰ ਸੋਧਿਆ ਜਾ ਸਕਦਾ ਹੈ।"</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"ਤੁਹਾਡੀ ਸੰਸਥਾ ਵੱਲੋਂ ਤੁਹਾਡੇ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਵਿੱਚ ਇੱਕ ਪ੍ਰਮਾਣ-ਪੱਤਰ ਅਥਾਰਟੀ ਸਥਾਪਤ ਕੀਤੀ ਗਈ ਹੈ। ਤੁਹਾਡੇ ਸੁਰੱਖਿਅਤ ਨੈੱਟਵਰਕ ਟਰੈਫਿਕ ਦੀ ਨਿਗਰਾਨੀ ਕੀਤੀ ਜਾ ਸਕਦੀ ਹੈ ਜਾਂ ਉਸਨੂੰ ਸੋਧਿਆ ਜਾ ਸਕਦਾ ਹੈ।"</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"ਇੱਕ ਪ੍ਰਮਾਣ-ਪੱਤਰ ਅਥਾਰਟੀ ਇਸ ਡੀਵਾਈਸ \'ਤੇ ਸਥਾਪਤ ਕੀਤੀ ਜਾਂਦੀ ਹੈ। ਤੁਹਾਡੇ ਸੁਰੱਖਿਅਤ ਨੈੱਟਵਰਕ ਟਰੈਫਿਕ ਦੀ ਨਿਗਰਾਨੀ ਕੀਤੀ ਜਾ ਸਕਦੀ ਹੈ ਜਾਂ ਉਸਨੂੰ ਸੋਧਿਆ ਜਾ ਸਕਦਾ ਹੈ।"</string>
@@ -920,6 +936,7 @@
<string name="pip_pause" msgid="1139598607050555845">"ਵਿਰਾਮ ਦਿਓ"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"ਅਗਲੇ \'ਤੇ ਜਾਓ"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"ਪਿਛਲੇ \'ਤੇ ਜਾਓ"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"ਆਕਾਰ ਬਦਲੋ"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"ਗਰਮ ਹੋਣ ਕਾਰਨ ਫ਼ੋਨ ਬੰਦ ਹੋ ਗਿਆ"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"ਤੁਹਾਡਾ ਫ਼ੋਨ ਹੁਣ ਸਹੀ ਚੱਲ ਰਿਹਾ ਹੈ"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">\n"ਤੁਹਾਡਾ ਫ਼ੋਨ ਬਹੁਤ ਗਰਮ ਸੀ, ਇਸ ਲਈ ਇਹ ਠੰਡਾ ਹੋਣ ਵਾਸਤੇ ਬੰਦ ਹੋ ਗਿਆ ਸੀ। ਤੁਹਾਡਾ ਫ਼ੋਨ ਹੁਣ ਸਹੀ ਚੱਲ ਰਿਹਾ ਹੈ।\n\nਤੁਹਾਡਾ ਫ਼ੋਨ ਬਹੁਤ ਗਰਮ ਹੋ ਸਕਦਾ ਹੈ ਜੇ:\n • ਤੁਸੀਂ ਸਰੋਤਾਂ ਦੀ ਵੱਧ ਵਰਤੋਂ ਵਾਲੀਆਂ ਐਪਾਂ (ਜਿਵੇਂ ਗੇਮਿੰਗ, ਵੀਡੀਓ, ਜਾਂ ਦਿਸ਼ਾ-ਨਿਰਦੇਸ਼ ਐਪਾਂ) ਵਰਤਦੇ ਹੋ • ਵੱਡੀਆਂ ਫ਼ਾਈਲਾਂ ਡਾਊਨਲੋਡ ਜਾਂ ਅੱਪਲੋਡ ਕਰਦੇ ਹੋ\n • ਆਪਣੇ ਫ਼ੋਨ ਨੂੰ ਉੱਚ ਤਾਪਮਾਨਾਂ ਵਿੱਚ ਵਰਤਦੇ ਹੋ"</string>
@@ -1014,7 +1031,7 @@
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"ਸਿਸਟਮ ਨੈਵੀਗੇਸ਼ਨ ਨੂੰ ਅੱਪਡੇਟ ਕਰਨ ਲਈ ਸੈਟਿੰਗਾਂ \'ਤੇ ਜਾਓ"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"ਸਟੈਂਡਬਾਈ"</string>
<string name="priority_onboarding_title" msgid="2893070698479227616">"ਗੱਲਬਾਤ ਨੂੰ ਤਰਜੀਹੀ ਗੱਲਬਾਤ ਵਜੋਂ ਸੈੱਟ ਕੀਤਾ ਗਿਆ"</string>
- <string name="priority_onboarding_behavior" msgid="5342816047020432929">"ਤਰਜੀਹੀ ਗੱਲਾਂਬਾਤਾਂ ਇਹ ਹੋਣਗੀਆਂ:"</string>
+ <string name="priority_onboarding_behavior" msgid="5342816047020432929">"ਤਰਜੀਹੀ ਗੱਲਾਂਬਾਤਾਂ ਨਾਲ ਇਹ ਵਿਹਾਰ ਹੋਵੇਗਾ:"</string>
<string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"ਗੱਲਬਾਤ ਸੈਕਸ਼ਨ ਦੇ ਸਿਖਰ \'ਤੇ ਦਿਖਾਓ"</string>
<string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"ਲਾਕ ਸਕ੍ਰੀਨ \'ਤੇ ਪ੍ਰੋਫਾਈਲ ਤਸਵੀਰ ਦਿਖਾਓ"</string>
<string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"ਐਪਾਂ ਦੇ ਸਿਖਰ \'ਤੇ ਫਲੋਟਿੰਗ ਬਬਲ ਵਜੋਂ ਦਿਸਦੀਆਂ ਹਨ"</string>
@@ -1045,7 +1062,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"ਕੰਟਰੋਲਾਂ ਨੂੰ ਮੁੜ-ਵਿਵਸਥਿਤ ਕਰਨ ਲਈ ਫੜ੍ਹ ਕੇ ਘਸੀਟੋ"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"ਸਾਰੇ ਕੰਟਰੋਲ ਹਟਾਏ ਗਏ"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"ਤਬਦੀਲੀਆਂ ਨੂੰ ਰੱਖਿਅਤ ਨਹੀਂ ਕੀਤਾ ਗਿਆ"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"ਸਾਰੇ ਕੰਟਰੋਲਾਂ ਦੀ ਸੂਚੀ ਨੂੰ ਲੋਡ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ।"</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"ਕੰਟਰੋਲਾਂ ਨੂੰ ਲੋਡ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ। ਇਹ ਪੱਕਾ ਕਰਨ ਲਈ <xliff:g id="APP">%s</xliff:g> ਐਪ ਦੀ ਜਾਂਚ ਕਰੋ ਕਿ ਐਪ ਸੈਟਿੰਗਾਂ ਨਹੀਂ ਬਦਲੀਆਂ ਹਨ।"</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"ਕੋਈ ਅਨੁਰੂਪ ਕੰਟਰੋਲ ਉਪਲਬਧ ਨਹੀਂ ਹੈ"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"ਹੋਰ"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"ਡੀਵਾਈਸ ਕੰਟਰੋਲਾਂ ਵਿੱਚ ਸ਼ਾਮਲ ਕਰੋ"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"ਸ਼ਾਮਲ ਕਰੋ"</string>
@@ -1061,8 +1079,11 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"<xliff:g id="DEVICE">%s</xliff:g> ਲਈ ਤਬਦੀਲੀ ਦੀ ਤਸਦੀਕ ਕਰੋ"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"ਹੋਰ ਦੇਖਣ ਲਈ ਸਵਾਈਪ ਕਰੋ"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"ਸਿਫ਼ਾਰਸ਼ਾਂ ਲੋਡ ਹੋ ਰਹੀਆਂ ਹਨ"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"ਇਸ ਮੀਡੀਆ ਸੈਸ਼ਨ ਨੂੰ ਬੰਦ ਕਰੋ"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"ਮੀਡੀਆ"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"ਮੌਜੂਦਾ ਸੈਸ਼ਨ ਨੂੰ ਲੁਕਾਓ।"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"ਲੁਕਾਓ"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"ਮੁੜ-ਚਾਲੂ ਕਰੋ"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"ਸੈਟਿੰਗਾਂ"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"ਅਕਿਰਿਆਸ਼ੀਲ, ਐਪ ਦੀ ਜਾਂਚ ਕਰੋ"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"ਗੜਬੜ, ਮੁੜ ਕੋਸ਼ਿਸ਼ ਹੋ ਰਹੀ ਹੈ…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"ਨਹੀਂ ਮਿਲਿਆ"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index cf63b1122da7..e4c98e0d807e 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -458,8 +458,10 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Kliknij ponownie, by otworzyć"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Przesuń w górę, by otworzyć"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Przesuń w górę, by spróbować ponownie"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"Tym urządzeniem zarządza Twoja organizacja"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"Tym urządzeniem zarządza <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for do_disclosure_generic (4896482821974707167) -->
+ <skip />
+ <!-- no translation found for do_disclosure_with_name (2091641464065004091) -->
+ <skip />
<string name="phone_hint" msgid="6682125338461375925">"Aby włączyć telefon, przesuń palcem od ikony"</string>
<string name="voice_hint" msgid="7476017460191291417">"Aby uzyskać pomoc głosową, przesuń palcem od ikony"</string>
<string name="camera_hint" msgid="4519495795000658637">"Przesuń palcem od ikony, by włączyć aparat"</string>
@@ -527,21 +529,33 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"Profil może być monitorowany"</string>
<string name="vpn_footer" msgid="3457155078010607471">"Sieć może być monitorowana"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"Sieć może być monitorowana"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"Twoja organizacja zarządza tym urządzeniem i może monitorować ruch w sieci"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"Organizacja <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> zarządza tym urządzeniem i może monitorować ruch w sieci"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"Twoim urządzeniem zarządza Twoja organizacja i jest ono połączone z aplikacją <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"Urządzeniem zarządza organizacja <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> i jest ono połączone z aplikacją <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"Urządzeniem zarządza Twoja organizacja"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"Tym urządzeniem zarządza organizacja <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"Tym urządzeniem zarządza Twoja organizacja i jest ono połączone z sieciami VPN"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"Urządzeniem zarządza organizacja <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> i jest ono połączone z sieciami VPN"</string>
+ <!-- no translation found for quick_settings_disclosure_management_monitoring (8231336875820702180) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_monitoring (2831423806103479812) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_named_vpn (6096715329056415588) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (5302786161534380104) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management (5515296598440684962) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management (3476472755775165827) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_vpns (371835422690053154) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_vpns (4046375645500668555) -->
+ <skip />
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Twoja organizacja może monitorować ruch w sieci w Twoim profilu do pracy"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"Organizacja <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> może monitorować ruch w sieci w Twoim profilu do pracy"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Sieć może być monitorowana"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"Urządzenie połączone z sieciami VPN"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"Profil służbowy połączony z aplikacją <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"Profil osobisty połączony z aplikacją <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"Urządzenie połączone z aplikacją <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <!-- no translation found for quick_settings_disclosure_vpns (7213546797022280246) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (8117568745060010789) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (5481763430080807797) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_vpn (2350838218824492465) -->
+ <skip />
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Zarządzanie urządzeniami"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Monitorowanie profilu"</string>
<string name="monitoring_title" msgid="4063890083735924568">"Monitorowanie sieci"</string>
@@ -551,8 +565,10 @@
<string name="disable_vpn" msgid="482685974985502922">"Wyłącz VPN"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"Rozłącz z VPN"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"Zobacz zasady"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"Urządzeniem zarządza <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nAdministrator może monitorować ustawienia, firmowe uprawnienia dostępu, aplikacje, dane dotyczące urządzenia i lokalizacji oraz nimi zarządzać.\n\nAby dowiedzieć się więcej, skontaktuj się z administratorem."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"Urządzeniem zarządza Twoja organizacja.\n\nAdministrator może monitorować ustawienia, firmowe uprawnienia dostępu, aplikacje, dane dotyczące urządzenia i lokalizacji oraz nimi zarządzać.\n\nAby dowiedzieć się więcej, skontaktuj się z administratorem."</string>
+ <!-- no translation found for monitoring_description_named_management (505833016545056036) -->
+ <skip />
+ <!-- no translation found for monitoring_description_management (4308879039175729014) -->
+ <skip />
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Twoja organizacja zainstalowała urząd certyfikacji na tym urządzeniu. Zabezpieczony ruch w sieci może być monitorowany i zmieniany."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Twoja organizacja zainstalowała urząd certyfikacji w Twoim profilu do pracy. Zabezpieczony ruch w sieci może być monitorowany i zmieniany."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Urząd certyfikacji zainstalowany na tym urządzeniu. Twój zabezpieczony ruch w sieci może być monitorowany i zmieniany."</string>
@@ -930,6 +946,7 @@
<string name="pip_pause" msgid="1139598607050555845">"Wstrzymaj"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"Dalej"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"Wstecz"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"Zmień rozmiar"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"Telefon wyłączony: przegrzanie"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"Telefon działa teraz normalnie"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Telefon był zbyt gorący i wyłączył się, by obniżyć temperaturę. Urządzenie działa teraz normalnie.\n\nTelefon może się przegrzać, gdy:\n • Używasz aplikacji zużywających dużo zasobów (np. gier, nawigacji czy odtwarzaczy filmów)\n • Pobierasz lub przesyłasz duże pliki\n • Używasz telefonu w wysokiej temperaturze"</string>
@@ -1057,7 +1074,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Przytrzymaj i przeciągnij, aby przestawić elementy sterujące"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"Usunięto wszystkie elementy sterujące"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Zmiany nie zostały zapisane"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"Nie udało się wczytać listy elementów sterujących."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"Nie udało się wczytać elementów sterujących. Sprawdź aplikację <xliff:g id="APP">%s</xliff:g>, aby upewnić się, że jej ustawienia się nie zmieniły."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"Zgodne elementy sterujące niedostępne"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Inne"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"Dodaj do sterowania urządzeniami"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"Dodaj"</string>
@@ -1073,13 +1091,16 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"Potwierdź zmianę dotyczącą urządzenia <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Przesuń palcem, by zobaczyć więcej"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Wczytuję rekomendacje"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"Zamknij tę sesję multimediów"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"Multimedia"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"Ukryj bieżącą sesję."</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ukryj"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Wznów"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"Ustawienia"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Nieaktywny, sprawdź aplikację"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Błąd, próbuję jeszcze raz…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Nie znaleziono"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"Element jest niedostępny"</string>
- <string name="controls_error_removed_message" msgid="2885911717034750542">"Nie udało się połączyć z urządzeniem: <xliff:g id="DEVICE">%1$s</xliff:g>. Sprawdź aplikację <xliff:g id="APPLICATION">%2$s</xliff:g>, aby upewnić się, że element sterujący jest wciąż dostępny i ustawienia aplikacji się nie zmieniły."</string>
+ <string name="controls_error_removed_message" msgid="2885911717034750542">"Nie udało się połączyć z urządzeniem <xliff:g id="DEVICE">%1$s</xliff:g>. Sprawdź aplikację <xliff:g id="APPLICATION">%2$s</xliff:g>, aby upewnić się, że element sterujący jest wciąż dostępny i ustawienia aplikacji się nie zmieniły."</string>
<string name="controls_open_app" msgid="483650971094300141">"Otwórz aplikację"</string>
<string name="controls_error_generic" msgid="352500456918362905">"Nie udało się wczytać stanu"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Błąd, spróbuj ponownie"</string>
diff --git a/packages/SystemUI/res/values-pl/strings_tv.xml b/packages/SystemUI/res/values-pl/strings_tv.xml
index 5921aa7a9963..852ea5056460 100644
--- a/packages/SystemUI/res/values-pl/strings_tv.xml
+++ b/packages/SystemUI/res/values-pl/strings_tv.xml
@@ -24,5 +24,5 @@
<string name="pip_close" msgid="5775212044472849930">"Zamknij PIP"</string>
<string name="pip_fullscreen" msgid="3877997489869475181">"Pełny ekran"</string>
<string name="mic_active" msgid="5766614241012047024">"Mikrofon aktywny"</string>
- <string name="app_accessed_mic" msgid="2754428675130470196">"Aplikacja %1$s korzystała z mikrofonu"</string>
+ <string name="app_accessed_mic" msgid="2754428675130470196">"Aplikacja %1$s uzyskała dostęp do mikrofonu"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index 9b3976eaffb8..334b19e6eda5 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -454,8 +454,8 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Toque novamente para abrir"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Deslize para cima para abrir"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Deslize para cima para tentar novamente"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"Este dispositivo é gerenciado pela sua organização"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"Este dispositivo é gerenciado por <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
+ <string name="do_disclosure_generic" msgid="4896482821974707167">"Este dispositivo pertence à sua organização"</string>
+ <string name="do_disclosure_with_name" msgid="2091641464065004091">"Este dispositivo pertence a <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="6682125338461375925">"Deslize a partir do ícone do telefone"</string>
<string name="voice_hint" msgid="7476017460191291417">"Deslize a partir do ícone de assistência de voz"</string>
<string name="camera_hint" msgid="4519495795000658637">"Deslize a partir do ícone da câmera"</string>
@@ -521,21 +521,21 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"O perfil pode ser monitorado"</string>
<string name="vpn_footer" msgid="3457155078010607471">"A rede pode ser monitorada"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"A rede pode ser monitorada"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"Sua organização gerencia este dispositivo e pode monitorar o tráfego de rede"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> gerencia este dispositivo e pode monitorar o tráfego de rede"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"O dispositivo é gerenciado pela sua organização e está conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"O dispositivo é gerenciado por <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> e está conectado a <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"O dispositivo é gerenciado pela sua organização"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"O dispositivo é gerenciado por <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"O dispositivo é gerenciado pela sua organização e está conectado a VPNs"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"O dispositivo é gerenciado por <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> e está conectado a VPNs"</string>
+ <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Sua organização é dona deste dispositivo e pode monitorar o tráfego de rede"</string>
+ <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> é dona deste dispositivo e pode monitorar o tráfego de rede"</string>
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Este dispositivo pertence à sua organização e está conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Este dispositivo pertence a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> e está conectado a <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Este dispositivo pertence à sua organização"</string>
+ <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Este dispositivo pertence a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management_vpns" msgid="371835422690053154">"Este dispositivo pertence à sua organização e está conectado a VPNs"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="4046375645500668555">"Este dispositivo pertence a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> e está conectado a VPNs"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Sua organização pode monitorar o tráfego de rede no seu perfil de trabalho"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> pode monitorar o tráfego de rede no seu perfil de trabalho"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"A rede pode ser monitorada"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"Dispositivo conectado a VPNs"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"Perfil de trabalho conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"Perfil pessoal conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"O dispositivo está conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_vpns" msgid="7213546797022280246">"Este dispositivo está conectado a VPNs"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Seu perfil de trabalho está conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Seu perfil pessoal está conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Este dispositivo está conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Gerenciamento de dispositivos"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Monitoramento de perfis"</string>
<string name="monitoring_title" msgid="4063890083735924568">"Monitoramento de rede"</string>
@@ -545,8 +545,8 @@
<string name="disable_vpn" msgid="482685974985502922">"Desativar VPN"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"Desconectar VPN"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"Ver políticas"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"Seu dispositivo é gerenciado por <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nO administrador pode monitorar e gerenciar configurações, acesso corporativo, apps, dados associados ao dispositivo e informações de localização do dispositivo.\n\nPara ver mais informações, entre em contato com o administrador."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"Seu dispositivo é gerenciado pela sua organização.\n\nO administrador pode monitorar e gerenciar configurações, acesso corporativo, apps, dados associados ao dispositivo e informações de localização do dispositivo.\n\nPara ver mais informações, entre em contato com o administrador."</string>
+ <string name="monitoring_description_named_management" msgid="505833016545056036">"Este dispositivo pertence a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nO administrador de TI pode monitorar e gerenciar configurações, acesso corporativo, apps, dados associados ao dispositivo e informações de local do dispositivo.\n\nPara saber mais, entre em contato com seu administrador de TI."</string>
+ <string name="monitoring_description_management" msgid="4308879039175729014">"Este dispositivo pertence à sua organização.\n\nO administrador de TI pode monitorar e gerenciar configurações, acesso corporativo, apps, dados associados ao dispositivo e informações de local do dispositivo.\n\nPara saber mais, entre em contato com seu administrador de TI."</string>
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Sua organização instalou uma autoridade de certificação neste dispositivo. É possível monitorar ou modificar seu tráfego de rede seguro."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Sua organização instalou uma autoridade de certificação no seu perfil de trabalho. É possível monitorar ou modificar seu tráfego de rede seguro."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Uma autoridade de certificação foi instalada neste dispositivo. É possível monitorar ou modificar seu tráfego de rede seguro."</string>
@@ -920,6 +920,7 @@
<string name="pip_pause" msgid="1139598607050555845">"Pausar"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"Pular para a próxima"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"Pular para a anterior"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"Redimensionar"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"O smartphone foi desligado devido ao aquecimento"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"O smartphone está sendo executado normalmente agora"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"O smartphone estava muito quente e foi desligado para resfriar. Agora, ele está sendo executado normalmente.\n\nO smartphone pode ficar quente demais se você:\n • usar apps que consomem muitos recursos (como apps de jogos, vídeos ou navegação);\n • fizer o download ou upload de arquivos grandes;\n • usar o smartphone em temperaturas altas."</string>
@@ -1015,8 +1016,8 @@
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Em espera"</string>
<string name="priority_onboarding_title" msgid="2893070698479227616">"A conversa foi definida como prioritária"</string>
<string name="priority_onboarding_behavior" msgid="5342816047020432929">"As conversas prioritárias:"</string>
- <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Aparecer na parte superior da seção de conversa"</string>
- <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Mostrar foto do perfil na tela de bloqueio"</string>
+ <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Aparecem na parte superior da seção de conversa"</string>
+ <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Mostram a foto do perfil na tela de bloqueio"</string>
<string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Aparecer como balões flutuantes sobre outros apps"</string>
<string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Interromper o \"Não perturbe\""</string>
<string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Ok"</string>
@@ -1045,7 +1046,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Toque no controle, mantenha-o pressionado e arraste para reorganizar as posições."</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"Todos os controles foram removidos"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"As mudanças não foram salvas"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"Não foi possível carregar a lista de controles."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"Não foi possível carregar os controles. Verifique o app <xliff:g id="APP">%s</xliff:g> para garantir que as configurações não tenham sido modificadas."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"Controles compatíveis indisponíveis"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Outro"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"Adicionar aos controles do dispositivo"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"Adicionar"</string>
@@ -1061,8 +1063,11 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"Confirme a mudança para <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Deslize para ver mais"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Carregando recomendações"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"Encerrar esta sessão de mídia"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"Mídia"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"Ocultar a sessão atual."</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ocultar"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Retomar"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"Configurações"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inativo, verifique o app"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Erro. Tentando novamente…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Não encontrado"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 55b5af121f37..512057febe63 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -104,7 +104,7 @@
<string name="screenrecord_taps_label" msgid="1595690528298857649">"Mostrar toques no ecrã"</string>
<string name="screenrecord_stop_text" msgid="6549288689506057686">"Toque para parar"</string>
<string name="screenrecord_stop_label" msgid="72699670052087989">"Parar"</string>
- <string name="screenrecord_pause_label" msgid="6004054907104549857">"Colocar em pausa"</string>
+ <string name="screenrecord_pause_label" msgid="6004054907104549857">"Pausar"</string>
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Retomar"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Cancelar"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Partilhar"</string>
@@ -454,8 +454,8 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Toque novamente para abrir"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Deslize rapidamente para cima para abrir"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Deslize rapidamente para cima para tentar novamente."</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"Este dispositivo é gerido pela sua entidade"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"Este dispositivo é gerido por <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
+ <string name="do_disclosure_generic" msgid="4896482821974707167">"Este dispositivo pertence à sua entidade."</string>
+ <string name="do_disclosure_with_name" msgid="2091641464065004091">"Este dispositivo pertence à entidade <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>."</string>
<string name="phone_hint" msgid="6682125338461375925">"Deslize rapid. a partir do ícone para aceder ao telemóvel"</string>
<string name="voice_hint" msgid="7476017460191291417">"Deslize rapid. a partir do ícone para aceder ao assist. voz"</string>
<string name="camera_hint" msgid="4519495795000658637">"Deslize rapidamente a partir do ícone para aceder à câmara"</string>
@@ -521,21 +521,21 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"O perfil pode ser monitorizado"</string>
<string name="vpn_footer" msgid="3457155078010607471">"A rede pode ser monitorizada"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"A rede pode ser monitorizada"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"A sua entidade gere este dispositivo e pode monitorizar o tráfego de rede"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"A <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> gere este dispositivo e pode monitorizar o tráfego de rede"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"O dispositivo é gerido pela sua entidade e está ligado à rede <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"O dispositivo é gerido pela <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> e está ligado à rede <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"O dispositivo é gerido pela sua entidade"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"O dispositivo é gerido pela <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"O dispositivo é gerido pela sua entidade e está ligado a VPNs"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"O dispositivo é gerido pela <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> e está ligado a VPNs"</string>
+ <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"A sua entidade gere este dispositivo e pode monitorizar o tráfego de rede."</string>
+ <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"A entidade <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> é proprietária deste dispositivo e pode monitorizar o tráfego de rede."</string>
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Este dispositivo pertence à sua entidade e está ligado a <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Este dispositivo pertence à entidade <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> e está ligado a <xliff:g id="VPN_APP">%2$s</xliff:g>."</string>
+ <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Este dispositivo pertence à sua entidade."</string>
+ <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Este dispositivo pertence à entidade <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>."</string>
+ <string name="quick_settings_disclosure_management_vpns" msgid="371835422690053154">"Este dispositivo pertence à sua entidade e está ligado a VPNs."</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="4046375645500668555">"Este dispositivo pertence à entidade <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> e está ligado a VPNs."</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"A sua entidade pode monitorizar o tráfego de rede no seu perfil de trabalho"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"A <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> pode monitorizar o tráfego de rede no seu perfil de trabalho"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"A rede pode ser monitorizada"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"Dispositivo ligado a VPNs"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"Perfil de trabalho ligado à rede <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"Perfil pessoal ligado à rede <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"Dispositivo ligado à rede <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_vpns" msgid="7213546797022280246">"Este dispositivo está ligado a VPNs."</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"O seu perfil de trabalho está ligado a <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"O seu perfil pessoal está ligado a <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Este dispositivo está ligado a <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Gestão de dispositivos"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Monitorização de perfis"</string>
<string name="monitoring_title" msgid="4063890083735924568">"Monitorização da rede"</string>
@@ -545,8 +545,8 @@
<string name="disable_vpn" msgid="482685974985502922">"Desativar a VPN"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"Desligar VPN"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"Ver Políticas"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"O dispositivo é gerido pela <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nO gestor pode monitorizar e gerir definições, acesso empresarial, aplicações, dados associados ao dispositivo e informações de localização do dispositivo.\n\nContacte o gestor para obter mais informações."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"O dispositivo é gerido pela sua entidade.\n\nO gestor pode monitorizar e gerir definições, acesso empresarial, aplicações, dados associados ao dispositivo e informações de localização do dispositivo.\n\nContacte o gestor para obter mais informações."</string>
+ <string name="monitoring_description_named_management" msgid="505833016545056036">"Este dispositivo pertence à entidade <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nO administrador de TI pode monitorizar e gerir as definições, o acesso empresarial, as apps, os dados associados ao dispositivo e as informações de localização do mesmo.\n\nContacte o administrador de TI para obter mais informações."</string>
+ <string name="monitoring_description_management" msgid="4308879039175729014">"Este dispositivo pertence à sua entidade.\n\nO administrador de TI pode monitorizar e gerir as definições, o acesso empresarial, as apps, os dados associados ao dispositivo e as informações de localização do mesmo.\n\nContacte o administrador de TI para obter mais informações."</string>
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"A sua entidade instalou uma autoridade de certificação neste dispositivo. O tráfego da sua rede segura pode ser monitorizado ou alterado."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"A sua entidade instalou uma autoridade de certificação no seu perfil de trabalho. O tráfego da sua rede segura pode ser monitorizado ou alterado."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Está instalada uma autoridade de certificação neste dispositivo. O tráfego da sua rede segura pode ser monitorizado ou alterado."</string>
@@ -917,9 +917,10 @@
<string name="pip_notification_title" msgid="8661573026059630525">"A app <xliff:g id="NAME">%s</xliff:g> está no modo de ecrã no ecrã"</string>
<string name="pip_notification_message" msgid="4991831338795022227">"Se não pretende que a app <xliff:g id="NAME">%s</xliff:g> utilize esta funcionalidade, toque para abrir as definições e desative-a."</string>
<string name="pip_play" msgid="333995977693142810">"Reproduzir"</string>
- <string name="pip_pause" msgid="1139598607050555845">"Colocar em pausa"</string>
+ <string name="pip_pause" msgid="1139598607050555845">"Pausar"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"Mudar para o seguinte"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"Mudar para o anterior"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"Redimensionar"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"Telem. deslig. devido ao calor"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"O telemóvel está a funcionar normalmente"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"O telemóvel estava muito quente, por isso desligou-se para arrefecer. Agora funciona normalmente.\n\nO telemóvel pode sobreaquecer se:\n • Utilizar aplicações que utilizam mais recursos (jogos, vídeo ou aplicações de navegação)\n • Transferir ou carregar ficheiros grandes\n • Utilizar em altas temperaturas"</string>
@@ -1014,9 +1015,9 @@
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Aceda às Definições para atualizar a navegação no sistema."</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Modo de espera"</string>
<string name="priority_onboarding_title" msgid="2893070698479227616">"Conversa definida como prioritária"</string>
- <string name="priority_onboarding_behavior" msgid="5342816047020432929">"As conversas com prioridade irão:"</string>
- <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Aparecem na parte superior da secção de conversas."</string>
- <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Mostram a imagem do perfil no ecrã de bloqueio."</string>
+ <string name="priority_onboarding_behavior" msgid="5342816047020432929">"As conversas prioritárias irão:"</string>
+ <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Aparecer na parte superior da secção de conversas."</string>
+ <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Mostrar a imagem do perfil no ecrã de bloqueio."</string>
<string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Aparecem como balões flutuantes por cima de apps."</string>
<string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Interrompem o modo Não incomodar."</string>
<string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"OK"</string>
@@ -1045,7 +1046,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Toque sem soltar e arraste para reorganizar os controlos."</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"Todos os controlos foram removidos."</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Alterações não guardadas."</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"Não foi possível carregar a lista dos controlos."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"Não foi possível carregar os controlos. Verifique a app <xliff:g id="APP">%s</xliff:g> para se certificar de que as definições da mesma não foram alteradas."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"Controlos compatíveis indisponíveis"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Outro"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"Adicione aos controlos de dispositivos"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"Adicionar"</string>
@@ -1061,8 +1063,11 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"Confirme a alteração para <xliff:g id="DEVICE">%s</xliff:g>."</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Deslize rapidamente para ver mais."</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"A carregar recomendações…"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"Fechar esta sessão multimédia"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"Multimédia"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"Oculte a sessão atual."</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ocultar"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Retomar"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"Definições"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inativa. Consulte a app."</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Erro. A tentar novamente…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Não encontrado."</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 9b3976eaffb8..334b19e6eda5 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -454,8 +454,8 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Toque novamente para abrir"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Deslize para cima para abrir"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Deslize para cima para tentar novamente"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"Este dispositivo é gerenciado pela sua organização"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"Este dispositivo é gerenciado por <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
+ <string name="do_disclosure_generic" msgid="4896482821974707167">"Este dispositivo pertence à sua organização"</string>
+ <string name="do_disclosure_with_name" msgid="2091641464065004091">"Este dispositivo pertence a <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="6682125338461375925">"Deslize a partir do ícone do telefone"</string>
<string name="voice_hint" msgid="7476017460191291417">"Deslize a partir do ícone de assistência de voz"</string>
<string name="camera_hint" msgid="4519495795000658637">"Deslize a partir do ícone da câmera"</string>
@@ -521,21 +521,21 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"O perfil pode ser monitorado"</string>
<string name="vpn_footer" msgid="3457155078010607471">"A rede pode ser monitorada"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"A rede pode ser monitorada"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"Sua organização gerencia este dispositivo e pode monitorar o tráfego de rede"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> gerencia este dispositivo e pode monitorar o tráfego de rede"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"O dispositivo é gerenciado pela sua organização e está conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"O dispositivo é gerenciado por <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> e está conectado a <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"O dispositivo é gerenciado pela sua organização"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"O dispositivo é gerenciado por <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"O dispositivo é gerenciado pela sua organização e está conectado a VPNs"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"O dispositivo é gerenciado por <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> e está conectado a VPNs"</string>
+ <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Sua organização é dona deste dispositivo e pode monitorar o tráfego de rede"</string>
+ <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> é dona deste dispositivo e pode monitorar o tráfego de rede"</string>
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Este dispositivo pertence à sua organização e está conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Este dispositivo pertence a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> e está conectado a <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Este dispositivo pertence à sua organização"</string>
+ <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Este dispositivo pertence a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management_vpns" msgid="371835422690053154">"Este dispositivo pertence à sua organização e está conectado a VPNs"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="4046375645500668555">"Este dispositivo pertence a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> e está conectado a VPNs"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Sua organização pode monitorar o tráfego de rede no seu perfil de trabalho"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> pode monitorar o tráfego de rede no seu perfil de trabalho"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"A rede pode ser monitorada"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"Dispositivo conectado a VPNs"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"Perfil de trabalho conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"Perfil pessoal conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"O dispositivo está conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_vpns" msgid="7213546797022280246">"Este dispositivo está conectado a VPNs"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Seu perfil de trabalho está conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Seu perfil pessoal está conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Este dispositivo está conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Gerenciamento de dispositivos"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Monitoramento de perfis"</string>
<string name="monitoring_title" msgid="4063890083735924568">"Monitoramento de rede"</string>
@@ -545,8 +545,8 @@
<string name="disable_vpn" msgid="482685974985502922">"Desativar VPN"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"Desconectar VPN"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"Ver políticas"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"Seu dispositivo é gerenciado por <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nO administrador pode monitorar e gerenciar configurações, acesso corporativo, apps, dados associados ao dispositivo e informações de localização do dispositivo.\n\nPara ver mais informações, entre em contato com o administrador."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"Seu dispositivo é gerenciado pela sua organização.\n\nO administrador pode monitorar e gerenciar configurações, acesso corporativo, apps, dados associados ao dispositivo e informações de localização do dispositivo.\n\nPara ver mais informações, entre em contato com o administrador."</string>
+ <string name="monitoring_description_named_management" msgid="505833016545056036">"Este dispositivo pertence a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nO administrador de TI pode monitorar e gerenciar configurações, acesso corporativo, apps, dados associados ao dispositivo e informações de local do dispositivo.\n\nPara saber mais, entre em contato com seu administrador de TI."</string>
+ <string name="monitoring_description_management" msgid="4308879039175729014">"Este dispositivo pertence à sua organização.\n\nO administrador de TI pode monitorar e gerenciar configurações, acesso corporativo, apps, dados associados ao dispositivo e informações de local do dispositivo.\n\nPara saber mais, entre em contato com seu administrador de TI."</string>
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Sua organização instalou uma autoridade de certificação neste dispositivo. É possível monitorar ou modificar seu tráfego de rede seguro."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Sua organização instalou uma autoridade de certificação no seu perfil de trabalho. É possível monitorar ou modificar seu tráfego de rede seguro."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Uma autoridade de certificação foi instalada neste dispositivo. É possível monitorar ou modificar seu tráfego de rede seguro."</string>
@@ -920,6 +920,7 @@
<string name="pip_pause" msgid="1139598607050555845">"Pausar"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"Pular para a próxima"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"Pular para a anterior"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"Redimensionar"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"O smartphone foi desligado devido ao aquecimento"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"O smartphone está sendo executado normalmente agora"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"O smartphone estava muito quente e foi desligado para resfriar. Agora, ele está sendo executado normalmente.\n\nO smartphone pode ficar quente demais se você:\n • usar apps que consomem muitos recursos (como apps de jogos, vídeos ou navegação);\n • fizer o download ou upload de arquivos grandes;\n • usar o smartphone em temperaturas altas."</string>
@@ -1015,8 +1016,8 @@
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Em espera"</string>
<string name="priority_onboarding_title" msgid="2893070698479227616">"A conversa foi definida como prioritária"</string>
<string name="priority_onboarding_behavior" msgid="5342816047020432929">"As conversas prioritárias:"</string>
- <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Aparecer na parte superior da seção de conversa"</string>
- <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Mostrar foto do perfil na tela de bloqueio"</string>
+ <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Aparecem na parte superior da seção de conversa"</string>
+ <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Mostram a foto do perfil na tela de bloqueio"</string>
<string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Aparecer como balões flutuantes sobre outros apps"</string>
<string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Interromper o \"Não perturbe\""</string>
<string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Ok"</string>
@@ -1045,7 +1046,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Toque no controle, mantenha-o pressionado e arraste para reorganizar as posições."</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"Todos os controles foram removidos"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"As mudanças não foram salvas"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"Não foi possível carregar a lista de controles."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"Não foi possível carregar os controles. Verifique o app <xliff:g id="APP">%s</xliff:g> para garantir que as configurações não tenham sido modificadas."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"Controles compatíveis indisponíveis"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Outro"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"Adicionar aos controles do dispositivo"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"Adicionar"</string>
@@ -1061,8 +1063,11 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"Confirme a mudança para <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Deslize para ver mais"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Carregando recomendações"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"Encerrar esta sessão de mídia"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"Mídia"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"Ocultar a sessão atual."</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ocultar"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Retomar"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"Configurações"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inativo, verifique o app"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Erro. Tentando novamente…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Não encontrado"</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 0f0f598cebf4..e5a9db0562bb 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -456,8 +456,8 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Atingeți din nou pentru a deschide"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Glisați în sus pentru a deschide"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Glisați pentru a încerca din nou"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"Acest dispozitiv este gestionat de organizația dvs."</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"Acest dispozitiv este gestionat de <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
+ <string name="do_disclosure_generic" msgid="4896482821974707167">"Dispozitivul aparține organizației dvs."</string>
+ <string name="do_disclosure_with_name" msgid="2091641464065004091">"Acest dispozitiv aparține organizației <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="6682125338461375925">"Glisați dinspre telefon"</string>
<string name="voice_hint" msgid="7476017460191291417">"Glisați dinspre pictogramă pentru asistentul vocal"</string>
<string name="camera_hint" msgid="4519495795000658637">"Glisați pentru a fotografia"</string>
@@ -524,21 +524,21 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"Profilul poate fi monitorizat"</string>
<string name="vpn_footer" msgid="3457155078010607471">"Rețeaua poate fi monitorizată"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"Este posibil ca rețeaua să fie monitorizată"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"Organizația dvs. gestionează acest dispozitiv și poate monitoriza traficul de rețea"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> gestionează acest dispozitiv și poate monitoriza traficul de rețea"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"Dispozitivul este gestionat de organizația dvs. și conectat la <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"Dispozitivul este gestionat de <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> și conectat la <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"Dispozitivul este gestionat de organizația dvs."</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"Dispozitivul este gestionat de <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"Dispozitivul este gestionat de organizația dvs. și conectat la rețelele VPN"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"Dispozitivul este gestionat de <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> și conectat la rețelele VPN"</string>
+ <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Organizația dvs. gestionează acest dispozitiv și poate monitoriza traficul de rețea"</string>
+ <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> deține acest dispozitiv și poate monitoriza traficul din rețea"</string>
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Dispozitivul aparține organizației dvs. și este conectat la <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Dispozitivul aparține organizației <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> și este conectat la <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Dispozitivul aparține organizației dvs."</string>
+ <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Acest dispozitiv aparține organizației <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management_vpns" msgid="371835422690053154">"Dispozitivul aparține organizației dvs. și este conectat la VPN-uri"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="4046375645500668555">"Dispozitivul aparține organizației <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> și este conectat la VPN-uri"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Este posibil ca organizația dvs. să monitorizeze traficul de rețea în profilul dvs. de serviciu"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"Este posibil ca <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> să monitorizeze traficul de rețea din profilul dvs. de serviciu"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Este posibil ca rețeaua să fie monitorizată"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"Dispozitiv conectat la rețelele VPN"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"Profilul de serviciu este conectat la <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"Profil personal conectat la <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"Dispozitiv conectat la <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_vpns" msgid="7213546797022280246">"Dispozitivul este conectat la VPN-uri"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Profilul dvs. de serviciu este conectat la <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Profilul dvs. personal este conectat la <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Dispozitivul este conectat la <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Gestionarea dispozitivului"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Monitorizarea profilului"</string>
<string name="monitoring_title" msgid="4063890083735924568">"Monitorizarea rețelei"</string>
@@ -548,8 +548,8 @@
<string name="disable_vpn" msgid="482685974985502922">"Dezactivați conexiunea prin VPN"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"Deconectați rețeaua VPN"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"Afișați politicile"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"Dispozitivul este gestionat de <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nAdministratorul dvs. poate să monitorizeze și să gestioneze setările, accesul la nivelul companiei, aplicațiile, datele asociate dispozitivului și informațiile despre locația dispozitivului.\n\nPentru mai multe informații, contactați administratorul."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"Dispozitivul este gestionat de organizația dvs.\n\nAdministratorul dvs. poate să monitorizeze și să gestioneze setările, accesul la nivelul companiei, aplicațiile, datele asociate dispozitivului și informațiile despre locația dispozitivului.\n\nPentru mai multe informații, contactați administratorul."</string>
+ <string name="monitoring_description_named_management" msgid="505833016545056036">"Dispozitivul aparține organizației <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nAdministratorul dvs. IT poate să monitorizeze și să gestioneze setările, accesul la nivelul companiei, aplicațiile, datele asociate dispozitivului și informațiile despre locația dispozitivului.\n\nPentru mai multe informații, contactați administratorul IT."</string>
+ <string name="monitoring_description_management" msgid="4308879039175729014">"Dispozitivul aparține organizației dvs.\n\nAdministratorul dvs. IT poate să monitorizeze și să gestioneze setările, accesul la nivelul companiei, aplicațiile, datele asociate dispozitivului și informațiile despre locația dispozitivului.\n\nPentru mai multe informații, contactați administratorul IT."</string>
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Organizația dvs. a instalat un certificat CA pe acest dispozitiv. Traficul dvs. sigur de rețea poate fi monitorizat sau modificat."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Organizația dvs. a instalat un certificat CA în profilul dvs. de serviciu. Traficul dvs. sigur de rețea poate fi monitorizat sau modificat."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Pe acest dispozitiv este instalat un certificat CA. Traficul dvs. sigur de rețea poate fi monitorizat sau modificat."</string>
@@ -925,6 +925,7 @@
<string name="pip_pause" msgid="1139598607050555845">"Întrerupeți"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"Treceți la următorul"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"Treceți la cel anterior"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"Redimensionați"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"Telefonul s-a oprit din cauza încălzirii"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"Acum telefonul funcționează normal"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Telefonul se încălzise prea mult și s-a oprit pentru a se răci. Acum telefonul funcționează normal.\n\nTelefonul s-ar putea încălzi prea mult dacă:\n • folosiți aplicații care consumă multe resurse (de ex., jocuri, aplicații video/de navigare);\n • descărcați/încărcați fișiere mari;\n • folosiți telefonul la temperaturi ridicate."</string>
@@ -1051,7 +1052,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Țineți apăsat și trageți pentru a rearanja comenzile"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"Au fost șterse toate comenzile"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Modificările nu au fost salvate"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"Lista cu toate comenzile nu a putut fi încărcată."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"Comenzile nu au putut fi încărcate. Accesați aplicația <xliff:g id="APP">%s</xliff:g> pentru a vă asigura că setările aplicației nu s-au schimbat."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"Nu sunt disponibile comenzi compatibile"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Altul"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"Adăugați la comenzile dispozitivelor"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"Adăugați"</string>
@@ -1067,8 +1069,15 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"Confirmați schimbarea pentru <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Glisați pentru a vedea mai multe"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Se încarcă recomandările"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"Închideți această sesiune media"</string>
+ <!-- no translation found for controls_media_title (1746947284862928133) -->
+ <skip />
+ <!-- no translation found for controls_media_close_session (3957093425905475065) -->
+ <skip />
+ <!-- no translation found for controls_media_dismiss_button (4485675693008031646) -->
+ <skip />
<string name="controls_media_resume" msgid="1933520684481586053">"Reia"</string>
+ <!-- no translation found for controls_media_settings_button (5815790345117172504) -->
+ <skip />
<string name="controls_error_timeout" msgid="794197289772728958">"Inactiv, verificați aplicația"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Eroare, se încearcă din nou…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Nu s-a găsit"</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index d2bda6e4e259..5352ab4f80c6 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -419,7 +419,7 @@
<string name="quick_settings_cellular_detail_data_limit" msgid="1791389609409211628">"Ограничение: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
<string name="quick_settings_cellular_detail_data_warning" msgid="7957253810481086455">"Предупреждение: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
<string name="quick_settings_work_mode_label" msgid="2754212289804324685">"Рабочий профиль"</string>
- <string name="quick_settings_night_display_label" msgid="8180030659141778180">"Ночной режим"</string>
+ <string name="quick_settings_night_display_label" msgid="8180030659141778180">"Ночная подсветка"</string>
<string name="quick_settings_night_secondary_label_on_at_sunset" msgid="3358706312129866626">"Вкл. на закате"</string>
<string name="quick_settings_night_secondary_label_until_sunrise" msgid="4063448287758262485">"До рассвета"</string>
<string name="quick_settings_night_secondary_label_on_at" msgid="3584738542293528235">"Включить в <xliff:g id="TIME">%s</xliff:g>"</string>
@@ -458,8 +458,8 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Нажмите ещё раз, чтобы открыть"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Проведите вверх, чтобы открыть"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Чтобы повторить попытку, проведите вверх"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"Этим устройством управляет ваша организация"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"Этим устройством управляет компания \"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>\""</string>
+ <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="phone_hint" msgid="6682125338461375925">"Телефон: проведите от значка"</string>
<string name="voice_hint" msgid="7476017460191291417">"Аудиоподсказки: проведите от значка"</string>
<string name="camera_hint" msgid="4519495795000658637">"Камера: проведите от значка"</string>
@@ -527,21 +527,21 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"Действия в профиле могут отслеживаться"</string>
<string name="vpn_footer" msgid="3457155078010607471">"Сеть может отслеживаться"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"Сеть может отслеживаться"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"Ваша организация управляет этим устройством и может отслеживать сетевой трафик"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"Организация \"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>\" управляет этим устройством и может отслеживать сетевой трафик"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"Устройством управляет ваша организация. На нем запущено приложение \"<xliff:g id="VPN_APP">%1$s</xliff:g>\"."</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"Устройством управляет организация \"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>\". На нем запущено приложение \"<xliff:g id="VPN_APP">%2$s</xliff:g>\"."</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"Устройством управляет ваша организация"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"Этим устройством управляет организация \"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>\"."</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"Устройством управляет ваша организация. Оно подключено к сетям VPN."</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"Устройством управляет организация \"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>\". Оно подключено к сетям VPN."</string>
+ <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Ваша организация управляет этим устройством и может отслеживать сетевой трафик"</string>
+ <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Организация \"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>\" управляет этим устройством и может отслеживать сетевой трафик"</string>
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Это устройство принадлежит вашей организации и подключено к приложению \"<xliff:g id="VPN_APP">%1$s</xliff:g>\""</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Это устройство принадлежит организации \"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>\" и подключено к приложению \"<xliff:g id="VPN_APP">%2$s</xliff:g>\""</string>
+ <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Это устройство принадлежит вашей организации"</string>
+ <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Это устройство принадлежит организации \"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>\""</string>
+ <string name="quick_settings_disclosure_management_vpns" msgid="371835422690053154">"Это устройство принадлежит вашей организации и подключено к приложениям для VPN"</string>
+ <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_monitoring" msgid="8548019955631378680">"Сеть может отслеживаться"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"Устройство подключено к сетям VPN"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"В рабочем профиле запущено приложение \"<xliff:g id="VPN_APP">%1$s</xliff:g>\""</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"В личном профиле запущено приложение \"<xliff:g id="VPN_APP">%1$s</xliff:g>\""</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"На устройстве запущено приложение \"<xliff:g id="VPN_APP">%1$s</xliff:g>\""</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>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Ваш личный профиль подключен к приложению \"<xliff:g id="VPN_APP">%1$s</xliff:g>\""</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Это устройство подключено к приложению \"<xliff:g id="VPN_APP">%1$s</xliff:g>\""</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Управление устройством"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Мониторинг профиля"</string>
<string name="monitoring_title" msgid="4063890083735924568">"Отслеживание сетей"</string>
@@ -551,8 +551,8 @@
<string name="disable_vpn" msgid="482685974985502922">"Отключить VPN"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"Отключить VPN"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"Просмотреть политику"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"Вашим устройством управляет организация \"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>\".\n\nАдминистратор может контролировать настройки, приложения и параметры доступа к корпоративным ресурсам на этом устройстве, а также связанные с ним данные (например, сведения о местоположении).\n\nЗа подробной информацией обращайтесь к администратору."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"Этим устройством управляет ваша организация.\n\nАдминистратор может контролировать настройки, приложения и параметры доступа к корпоративным ресурсам на этом устройстве, а также связанные с ним данные (например, сведения о местоположении).\n\nЗа подробной информацией обращайтесь к администратору."</string>
+ <string name="monitoring_description_named_management" msgid="505833016545056036">"Этим устройством управляет организация \"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>\".\n\nВаш системный администратор может управлять настройками, приложениями и параметрами доступа к корпоративным ресурсам на этом устройстве, а также связанными с ним данными (например, сведениями о местоположении).\n\nЗа подробной информацией обращайтесь к системному администратору."</string>
+ <string name="monitoring_description_management" msgid="4308879039175729014">"Это устройство принадлежит вашей организации.\n\nСистемный администратор может управлять настройками, приложениями и параметрами доступа к корпоративным ресурсам на этом устройстве, а также связанными с ним данными (например, сведениями о местоположении).\n\nЗа подробной информацией обращайтесь к системному администратору."</string>
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Ваша организация установила сертификат ЦС на устройство. Она может отслеживать и изменять защищенный сетевой трафик."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Ваша организация установила сертификат ЦС в рабочем профиле. Она может отслеживать и изменять защищенный сетевой трафик."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"На устройстве установлен сертификат ЦС. Ваш защищенный сетевой трафик могут отслеживать и изменять."</string>
@@ -930,6 +930,7 @@
<string name="pip_pause" msgid="1139598607050555845">"Приостановить"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"Перейти к следующему"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"Перейти к предыдущему"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"Изменить размер"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"Телефон выключился из-за перегрева"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"Сейчас телефон работает нормально"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Ваш телефон выключился из-за перегрева. Сейчас он работает нормально.\n\nВозможные причины перегрева телефона:\n • использование ресурсоемких игр и приложений, связанных с видео или навигацией);\n • скачивание или загрузка больших файлов;\n • высокая температура окружающей среды."</string>
@@ -1012,21 +1013,21 @@
<string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Перенести в правый верхний угол"</string>
<string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Перенести в левый нижний угол"</string>
<string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Перенести в правый нижний угол"</string>
- <string name="bubble_dismiss_text" msgid="1314082410868930066">"Закрыть всплывающий чат"</string>
- <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Не показывать всплывающие чаты для разговоров"</string>
+ <string name="bubble_dismiss_text" msgid="1314082410868930066">"Скрыть всплывающий чат"</string>
+ <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Не показывать всплывающий чат для разговора"</string>
<string name="bubbles_user_education_title" msgid="5547017089271445797">"Всплывающие чаты"</string>
<string name="bubbles_user_education_description" msgid="1160281719576715211">"Новые разговоры будут появляться в виде плавающих значков, или всплывающих чатов. Чтобы открыть чат, нажмите на него, а чтобы переместить – перетащите."</string>
- <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Настройки всплывающих чатов"</string>
- <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Чтобы отключить всплывающие чаты от приложения, нажмите \"Настроить\"."</string>
+ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Всплывающие чаты"</string>
+ <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Чтобы отключить всплывающие чаты из этого приложения, нажмите \"Настроить\"."</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"ОК"</string>
<string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>: настройки"</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Параметры навигации в системе обновлены. Чтобы изменить их, перейдите в настройки."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Чтобы обновить параметры навигации в системе, перейдите в настройки."</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Переход в режим ожидания"</string>
<string name="priority_onboarding_title" msgid="2893070698479227616">"Разговор помечен как важный"</string>
- <string name="priority_onboarding_behavior" msgid="5342816047020432929">"Важные разговоры:"</string>
- <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Показывать в верхней части списка разговоров"</string>
- <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Показывать фото профиля на заблокированном экране"</string>
+ <string name="priority_onboarding_behavior" msgid="5342816047020432929">"Преимущества:"</string>
+ <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Важные разговоры показываются в верхней части списка разговоров."</string>
+ <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Фото профиля показывается на заблокированном экране."</string>
<string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Показывать как всплывающий чат над приложениями"</string>
<string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Показывать в режиме \"Не беспокоить\""</string>
<string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"ОК"</string>
@@ -1034,8 +1035,8 @@
<string name="magnification_overlay_title" msgid="6584179429612427958">"Наложение окна увеличения"</string>
<string name="magnification_window_title" msgid="4863914360847258333">"Окно увеличения"</string>
<string name="magnification_controls_title" msgid="8421106606708891519">"Настройки окна увеличения"</string>
- <string name="quick_controls_title" msgid="6839108006171302273">"Виджеты управления устройствами"</string>
- <string name="quick_controls_subtitle" msgid="1667408093326318053">"Добавьте элементы управления для подключенных устройств"</string>
+ <string name="quick_controls_title" msgid="6839108006171302273">"Управление устройствами"</string>
+ <string name="quick_controls_subtitle" msgid="1667408093326318053">"Добавьте виджеты для управления устройствами."</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"Настройте виджеты управления устройствами"</string>
<string name="quick_controls_setup_subtitle" msgid="1681506617879773824">"Чтобы перейти к элементам управления, удерживайте кнопку питания."</string>
<string name="controls_providers_title" msgid="6879775889857085056">"Чтобы добавить элементы управления, выберите приложение"</string>
@@ -1057,7 +1058,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Чтобы изменить порядок элементов управления, перетащите их"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"Все элементы управления удалены"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Изменения не сохранены."</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"Не удалось загрузить список элементов управления."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"Не удалось загрузить список доступных для управления устройств. Проверьте, не изменились ли настройки приложения \"<xliff:g id="APP">%s</xliff:g>\"."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"Управление недоступно"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Другое"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"Добавьте виджеты управления устройствами"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"Добавить"</string>
@@ -1073,13 +1075,20 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"Подтвердите изменения для устройства \"<xliff:g id="DEVICE">%s</xliff:g>\""</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Проведите по экрану, чтобы увидеть больше"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Загрузка рекомендаций…"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"Закрыть этот мультимедийный сеанс"</string>
+ <!-- no translation found for controls_media_title (1746947284862928133) -->
+ <skip />
+ <!-- no translation found for controls_media_close_session (3957093425905475065) -->
+ <skip />
+ <!-- no translation found for controls_media_dismiss_button (4485675693008031646) -->
+ <skip />
<string name="controls_media_resume" msgid="1933520684481586053">"Возобновить"</string>
+ <!-- no translation found for controls_media_settings_button (5815790345117172504) -->
+ <skip />
<string name="controls_error_timeout" msgid="794197289772728958">"Нет ответа. Проверьте приложение."</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Ошибка. Повторная попытка…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Не найдено."</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"Управление недоступно"</string>
- <string name="controls_error_removed_message" msgid="2885911717034750542">"Нет доступа к устройству (<xliff:g id="DEVICE">%1$s</xliff:g>). Проверьте, доступно ли управление в приложении \"<xliff:g id="APPLICATION">%2$s</xliff:g>\" и не изменились ли настройки этого приложения."</string>
+ <string name="controls_error_removed_message" msgid="2885911717034750542">"Нет доступа к устройству \"<xliff:g id="DEVICE">%1$s</xliff:g>\". Проверьте, доступно ли управление в приложении \"<xliff:g id="APPLICATION">%2$s</xliff:g>\" и не изменились ли настройки этого приложения."</string>
<string name="controls_open_app" msgid="483650971094300141">"Открыть приложение"</string>
<string name="controls_error_generic" msgid="352500456918362905">"Не удалось загрузить статус."</string>
<string name="controls_error_failed" msgid="960228639198558525">"Ошибка. Повторите попытку."</string>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index b9b95ac45f81..162bea8050c1 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -454,8 +454,8 @@
<string name="notification_tap_again" msgid="4477318164947497249">"විවෘත කිරීමට නැවත තට්ටු කරන්න"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"විවෘත කිරීමට ස්වයිප් කරන්න"</string>
<string name="keyguard_retry" msgid="886802522584053523">"නැවත උත්සාහ කිරීමට ඉහළට ස්වයිප් කරන්න"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"මෙම උපාංගය ඔබගේ සංවිධානය විසින් කළමනාකරණය කරනු ලැබේ"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"මෙම උපාංගය <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> මගින් කළමනාකරණය කෙරේ"</string>
+ <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="phone_hint" msgid="6682125338461375925">"දුරකථනය සඳහා නිරූපකය වෙතින් ස්වයිප් කරන්න"</string>
<string name="voice_hint" msgid="7476017460191291417">"හඬ සහාය සඳහා නිරූපකය වෙතින් ස්වයිප් කරන්න"</string>
<string name="camera_hint" msgid="4519495795000658637">"කැමරාව සඳහා නිරූපකය වෙතින් ස්වයිප් කරන්න"</string>
@@ -521,21 +521,21 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"ඇතැම් විට පැතිකඩ නිරීක්ෂණය කරන ලදි"</string>
<string name="vpn_footer" msgid="3457155078010607471">"ඇතැම් විට ජාලය නිරීක්ෂණය විය හැක"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"ඇතැම් විට ජාලය නිරීක්ෂණය විය හැක"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"ඔබගේ සංවිධානය මෙම උපාංගය කළමනාකරණය කරන අතර එය ජාල තදබදය නිරීක්ෂණය කළ හැක"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> මෙම උපාංගය කළමනාකරණය කරන අතර එය ජාල තදබදය නිරීක්ෂණය කළ හැක"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"උපාංගය ඔබගේ සංවිධානය විසින් කළමනාකරණය කරනු ලැබෙන අතර එය <xliff:g id="VPN_APP">%1$s</xliff:g> වෙත සම්බන්ධිතයි"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"උපාංගය <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> මගින් කළමනාකරණය කෙරෙන අතර <xliff:g id="VPN_APP">%2$s</xliff:g> වෙත සම්බන්ධිතයි"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"උපාංගය ඔබගේ සංවිධානය විසින් කළමනාකරණය කරනු ලැබේ"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"උපාංගය <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> මගින් කළමනාකරණය කෙරේ"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"උපාංගය ඔබගේ සංවිධානය විසින් කළමනාකරණය කරනු ලැබෙන අතර එය VPN වෙත සම්බන්ධිතයි"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"උපාංගය <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> මගින් කළමනාකරණය කෙරෙන අතර VPN වෙත සම්බන්ධිතයි"</string>
+ <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"ඔබේ සංවිධානයට මෙම උපාංගය අයිති අතර ජාල තදබදය නිරීක්ෂණය කළ හැකිය"</string>
+ <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> සංවිධානයට මෙම උපාංගය අයිති අතර ජාල තදබදය නිරීක්ෂණය කළ හැකිය"</string>
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"මෙම උපාංගය ඔබේ සංවිධානයට අයිති අතර <xliff:g id="VPN_APP">%1$s</xliff:g> වෙත සම්බන්ධ කර ඇත"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"මෙම උපාංගය <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> සංවිධානයට අයිති අතර <xliff:g id="VPN_APP">%2$s</xliff:g> වෙත සම්බන්ධ කර ඇත"</string>
+ <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"මෙම උපාංගය ඔබේ සංවිධානයට අයිතිය"</string>
+ <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"මෙම උපාංගය <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> සංවිධානයට අයිතිය"</string>
+ <string name="quick_settings_disclosure_management_vpns" msgid="371835422690053154">"මෙම උපාංගය ඔබේ සංවිධානයට අයිති අතර VPNs වෙත සම්බන්ධ කර ඇත"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="4046375645500668555">"මෙම උපාංගය <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> සංවිධානයට අයිති අතර VPNs වෙත සම්බන්ධ කර ඇත"</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_monitoring" msgid="8548019955631378680">"ඇතැම් විට ජාලය නිරීක්ෂණය විය හැක"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"උපාංගය VPN වෙත සම්බන්ධිතයි"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"කාර්යාල පැතිකඩ <xliff:g id="VPN_APP">%1$s</xliff:g> වෙත සම්බන්ධ වුණි"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"පුද්ගලික පැතිකඩ <xliff:g id="VPN_APP">%1$s</xliff:g> වෙත සම්බන්ධ වුණි"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"උපාංගය <xliff:g id="VPN_APP">%1$s</xliff:g> වෙත සම්බන්ධ වුණි"</string>
+ <string name="quick_settings_disclosure_vpns" msgid="7213546797022280246">"මෙම උපාංගය VPNs වෙත සම්බන්ධ කර ඇත"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"ඔබේ කාර්යාල පැතිකඩ <xliff:g id="VPN_APP">%1$s</xliff:g> වෙත සම්බන්ධ කර ඇත"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"ඔබේ පෞද්ගලික පැතිකඩ <xliff:g id="VPN_APP">%1$s</xliff:g> වෙත සම්බන්ධ කර ඇත"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"මෙම උපාංගය <xliff:g id="VPN_APP">%1$s</xliff:g> වෙත සම්බන්ධ කර ඇත"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"උපාංග කළමනාකරණය"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"පැතිකඩ නිරීක්ෂණය කිරීම"</string>
<string name="monitoring_title" msgid="4063890083735924568">"ජාල නිරීක්ෂණය"</string>
@@ -545,8 +545,8 @@
<string name="disable_vpn" msgid="482685974985502922">"VPN අබල කරන්න."</string>
<string name="disconnect_vpn" msgid="26286850045344557">"VPN විසන්ධි කරන්න"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"ප්‍රතිපත්ති පෙන්වන්න"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"ඔබගේ උපාංගය ඔබගේ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> විසින් කළමනාකරණය කරනු ලැබේ. \n\nඔබේ පරිපාලකට ඔබේ උපාංගය හා සම්බන්ධිත සැකසීම්, ආයතනික ප්‍රවේශය, යෙදුම්, දත්ත සහ ඔබේ උපාංග ස්ථාන තොරතුරු නිරීක්ෂණය සහ කළමනාකරණය කිරීමට හැකිය.\n\nවැඩිදුර තොරතුරු සඳහා, ඔබගේ පරිපාලක අමතන්න."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"ඔබගේ උපාංගය ඔබගේ සංවිධානය විසින් කළමනාකරණය කරනු ලැබේ.\n\nඔබේ පරිපාලකට ඔබේ උපාංගය හා සම්බන්ධිත සැකසීම්, ආයතනික ප්‍රවේශය, යෙදුම්, දත්ත සහ ඔබේ උපාංග ස්ථාන තොරතුරු නිරීක්ෂණය සහ කළමනාකරණය කිරීමට හැකිය.\n\nවැඩිදුර තොරතුරු සඳහා, ඔබගේ පරිපාලක අමතන්න."</string>
+ <string name="monitoring_description_named_management" msgid="505833016545056036">"මෙම උපාංගය <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> සංවිධානයට අයිතිය.\n\nඔබේ IT පරිපාලකට ඔබේ උපාංගය හා සම්බන්ධිත සැකසීම්, ආයතනික ප්‍රවේශය, යෙදුම්, දත්ත සහ ඔබේ උපාංගයේ ස්ථාන තොරතුරු නිරීක්ෂණය කර කළමනාකරණය කිරීමට හැකිය.\n\nවැඩිදුර තොරතුරු සඳහා, ඔබේ IT අමතන්න."</string>
+ <string name="monitoring_description_management" msgid="4308879039175729014">"මෙම උපාංගය ඔබේ සංවිධානයට අයිතිය.\n\nඔබේ IT පරිපාලකට ඔබේ උපාංගය හා සම්බන්ධිත සැකසීම්, ආයතනික ප්‍රවේශය, යෙදුම්, දත්ත සහ ඔබේ උපාංගයේ ස්ථාන තොරතුරු නිරීක්ෂණය කර කළමනාකරණය කිරීමට හැකිය.\n\nවැඩිදුර තොරතුරු සඳහා, ඔබේ IT අමතන්න."</string>
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"ඔබගේ සංවිධානය ඔබගේ උපාංගය තුළ සහතික අධිකාරියක් ස්ථාපනය කර තිබේ. ඔබගේ ආරක්ෂක ජාල තදබදය නිරීක්ෂණය හෝ වෙනස් කිරීමට පුළුවනි."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"ඔබගේ සංවිධානය ඔබගේ කාර්යාල පැතිකඩ තුළ සහතික අධිකාරියක් ස්ථාපනය කර තිබේ. ඔබගේ ආරක්ෂක ජාල තදබදය නිරීක්ෂණය හෝ වෙනස් කිරීමට පුළුවනි."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"මෙම උපාංගය තුළ සහතික අධිකාරියක් ස්ථාපනය කර තිබේ. ඔබගේ ආරක්ෂක ජාල තදබදය නිරීක්ෂණය හෝ වෙනස් කිරීමට පුළුවනි."</string>
@@ -920,6 +920,7 @@
<string name="pip_pause" msgid="1139598607050555845">"විරාම කරන්න"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"ඊළඟ එකට පනින්න"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"පෙර එකට පනින්න"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"ප්‍රතිප්‍රමාණ කරන්න"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"දුරකථනය රත් වීම නිසා ක්‍රියාවිරහිත කරන ලදී"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"ඔබගේ දුරකථනය දැන් සාමාන්‍ය ලෙස ධාවනය වේ"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"ඔබේ දුරකථනය ඉතාම උණුසුම්ය, එම නිසා එය සිසිල් වීමට ක්‍රියාවිරහිත කරන ලදී. ධැන් ඔබේ දුරකථනය සාමාන්‍ය පරිදි ධාවනය වේ.\n\nඔබ පහත දේවල් සිදු කළහොත් ඔබේ දුරකථනය ඉතාම උණුසුම් විය හැකිය:\n • සම්පත්-දැඩි සත්කාරක යෙදුම් භාවිතය (ක්‍රීඩා, වීඩියෝ, හෝ සංචලන යෙදුම් යනාදී)\n • විශාල ගොනු බාගැනීම හෝ උඩුගත කිරීම\n • ඔබේ දුරකථනය අධික උෂ්ණත්වයේදී භාවිත කිරීම"</string>
@@ -1045,7 +1046,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"පාලන නැවත පිළියෙළ කිරීමට අල්ලාගෙන සිට අදින්න"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"සියලු පාලන ඉවත් කර ඇත"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"වෙනස් කිරීම් නොසුරැකිණි"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"සියලු පාලනවල ලැයිස්තුව පූරණය කළ නොහැකි විය."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"පාලන පූරණය කළ නොහැකි විය. යෙදුම් සැකසීම් වෙනස් වී නැති බව සහතික කර ගැනීමට <xliff:g id="APP">%s</xliff:g> යෙදුම පරීක්ෂා කරන්න."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"ගැළපෙන පාලන ලබා ගත නොහැකිය"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"වෙනත්"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"උපාංග පාලන වෙත එක් කරන්න"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"එක් කරන්න"</string>
@@ -1061,8 +1063,11 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"<xliff:g id="DEVICE">%s</xliff:g> සඳහා වෙනස තහවුරු කරන්න"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"තව බැලීමට ස්වයිප් කරන්න"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"නිර්දේශ පූරණය කරමින්"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"මෙම මාධ්‍ය සැසිය වසන්න"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"මාධ්‍ය"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"වත්මන් සැසිය සඟවන්න."</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"සඟවන්න"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"නැවත පටන් ගන්න"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"සැකසීම්"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"අක්‍රියයි, යෙදුම පරීක්ෂා කරන්න"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"දෝෂයකි, නැවත උත්සාහ කරමින්…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"හමු නොවිණි"</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index c776f2e7a3f0..bfd007593432 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -458,8 +458,10 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Upozornenie otvoríte opätovným klepnutím"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Otvorte potiahnutím prstom nahor"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Potiahnutím nahor to skúste znova"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"Toto zariadenie spravuje vaša organizácia"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"Toto zariadenie spravuje organizácia <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for do_disclosure_generic (4896482821974707167) -->
+ <skip />
+ <!-- no translation found for do_disclosure_with_name (2091641464065004091) -->
+ <skip />
<string name="phone_hint" msgid="6682125338461375925">"Telefón otvoríte prejdením prstom od ikony"</string>
<string name="voice_hint" msgid="7476017460191291417">"Hlasového asistenta otvoríte prejdením prstom od ikony"</string>
<string name="camera_hint" msgid="4519495795000658637">"Fotoaparát otvoríte prejdením prstom od ikony"</string>
@@ -527,21 +529,33 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"Profil môže byť monitorovaný"</string>
<string name="vpn_footer" msgid="3457155078010607471">"Sieť môže byť sledovaná"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"Sieť môže byť monitorovaná"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"Vaša organizácia spravuje toto zariadenie a môže sledovať sieťovú premávku"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"Organizácia <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> spravuje toto zariadenie a môže sledovať sieťovú premávku"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"Zariadenie spravuje vaša organizácia a je pripojené k aplikácii <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"Zariadenie spravuje organizácia <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> a je pripojené k aplikácii <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"Zariadenie spravuje vaša organizácia"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"Zariadenie spravuje organizácia <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"Zariadenie spravuje vaša organizácia a je pripojené k aplikáciám VPN"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"Zariadenie spravuje organizácia <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> a je pripojené k aplikáciám VPN"</string>
+ <!-- no translation found for quick_settings_disclosure_management_monitoring (8231336875820702180) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_monitoring (2831423806103479812) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_named_vpn (6096715329056415588) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (5302786161534380104) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management (5515296598440684962) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management (3476472755775165827) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_vpns (371835422690053154) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_vpns (4046375645500668555) -->
+ <skip />
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Organizácia môže sledovať sieťovú premávku vo vašom pracovnom profile"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"Organizácia <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> môže sledovať sieťovú premávku vo vašom pracovnom profile"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Sieť môže byť sledovaná"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"Zariadenie je pripojené k aplikáciám VPN"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"Pracovný profil je pripojený k aplikácii <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"Osobný profil je pripojený k aplikácii <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"Zariadenie je pripojené k aplikácii <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <!-- no translation found for quick_settings_disclosure_vpns (7213546797022280246) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (8117568745060010789) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (5481763430080807797) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_vpn (2350838218824492465) -->
+ <skip />
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Správa zariadení"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Monitorovanie profilu"</string>
<string name="monitoring_title" msgid="4063890083735924568">"Sledovanie siete"</string>
@@ -551,8 +565,10 @@
<string name="disable_vpn" msgid="482685974985502922">"Deaktivovať VPN"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"Odpojiť sieť VPN"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"Zobraziť pravidlá"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"Zariadenie spravuje organizácia <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nSprávca môže sledovať a spravovať nastavenia, firemný prístup, aplikácie a údaje súvisiace s týmto zariadením vrátane informácií o polohe vášho zariadenia.\n\nĎalšie informácie vám poskytne správca."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"Zariadenie spravuje vaša organizácia.\n\nSprávca môže sledovať a spravovať nastavenia, firemný prístup, aplikácie a údaje súvisiace s týmto zariadením vrátane informácií o polohe vášho zariadenia.\n\nĎalšie informácie vám poskytne správca."</string>
+ <!-- no translation found for monitoring_description_named_management (505833016545056036) -->
+ <skip />
+ <!-- no translation found for monitoring_description_management (4308879039175729014) -->
+ <skip />
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Organizácia nainštalovala pre toto zariadenie certifikačnú autoritu. Zabezpečená sieťová premávka môže byť sledovaná či upravená."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Organizácia nainštalovala pre váš pracovný profil certifikačnú autoritu. Zabezpečená sieťová premávka môže byť sledovaná či upravená."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"V tomto zariadení je nainštalovaná certifikačná autorita. Zabezpečená sieťová premávka môže byť sledovaná či upravená."</string>
@@ -930,6 +946,7 @@
<string name="pip_pause" msgid="1139598607050555845">"Pozastaviť"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"Preskočiť na ďalšie"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"Preskočiť na predchádzajúce"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"Zmeniť veľkosť"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"Telefón sa vypol z dôvodu prehriatia"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"Teraz telefón funguje ako obvykle"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Telefón bol príliš horúci, preto sa vypol, aby vychladol. Teraz funguje ako obvykle.\n\nTelefón sa môže príliš zahriať v týchto prípadoch:\n • používanie náročných aplikácií (napr. hier, videí alebo navigácie);\n • sťahovanie alebo nahrávanie veľkých súborov;\n • používanie telefónu pri vysokých teplotách."</string>
@@ -1016,17 +1033,17 @@
<string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Nezobrazovať konverzáciu ako bublinu"</string>
<string name="bubbles_user_education_title" msgid="5547017089271445797">"Čet pomocou bublín"</string>
<string name="bubbles_user_education_description" msgid="1160281719576715211">"Nové konverzácie sa zobrazujú ako plávajúce ikony či bubliny. Bublinu otvoríte klepnutím. Premiestnite ju presunutím."</string>
- <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Ovládajte bubliny kedykoľvek"</string>
- <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Klepnutím na Spravovať vypnite bubliny z tejto aplikácie"</string>
+ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Nastavenie bublín môžete kedykoľvek zmeniť"</string>
+ <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Bubliny pre túto aplikáciu môžete vypnúť klepnutím na Spravovať"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Dobre"</string>
- <string name="bubbles_app_settings" msgid="5779443644062348657">"Nastavenia upozornenia <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
+ <string name="bubbles_app_settings" msgid="5779443644062348657">"Nastavenia aplikácie <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Navigácia v systéme bola aktualizovaná. Ak chcete vykonať zmeny, prejdite do Nastavení."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Prejdite do Nastavení a aktualizujte navigáciu v systéme"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Pohotovostný režim"</string>
<string name="priority_onboarding_title" msgid="2893070698479227616">"Konverzácia je nastavená ako prioritná"</string>
- <string name="priority_onboarding_behavior" msgid="5342816047020432929">"Správanie prioritných konverzácií:"</string>
- <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Zobrazovať hore v sekcii konverzácií"</string>
- <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Zobrazovať profilovú fotku na uzamknutej obrazovke"</string>
+ <string name="priority_onboarding_behavior" msgid="5342816047020432929">"Prioritné konverzácie:"</string>
+ <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"sa zobrazujú navrchu sekcie konverzácií"</string>
+ <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"zobrazujú profilovú fotku na uzamknutej obrazovke"</string>
<string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Zobrazovať ako plávajúce bubliny nad aplikáciami"</string>
<string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Prerušovať režim bez vyrušení"</string>
<string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Dobre"</string>
@@ -1057,7 +1074,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Polohu každého ovládača môžete zmeniť jeho pridržaním a presunutím"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"Všetky ovládače boli odstránené"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Zmeny neboli uložené"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"Zoznam všetkých ovl. prvkov sa nepodarilo načítať."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"Ovládacie prvky sa nepodarilo načítať. V aplikácii <xliff:g id="APP">%s</xliff:g> skontrolujte, či sa nezmenili nastavenia."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"Kompatibilné ovládacie prvky nie sú k dispozícii"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Iné"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"Pridanie do ovládania zariadení"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"Pridať"</string>
@@ -1073,13 +1091,16 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"Potvrdenie zmeny zariadenia <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Potiahnutím zobrazíte ďalšie položky"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Načítavajú sa odporúčania"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"Zavrieť túto reláciu média"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"Médiá"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"Skryť aktuálnu reláciu."</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Skryť"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Pokračovať"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"Nastavenia"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Neaktívne, preverte aplikáciu"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Chyba, skúša sa znova…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Nenájdené"</string>
- <string name="controls_error_removed_title" msgid="1207794911208047818">"Ovládanie nie je k dispozícii"</string>
- <string name="controls_error_removed_message" msgid="2885911717034750542">"Nepodarilo sa získať prístup k zariadeniu <xliff:g id="DEVICE">%1$s</xliff:g>. V aplikácii <xliff:g id="APPLICATION">%2$s</xliff:g> skontrolujte, či je ovládanie stále k dispozícii a či sa nezmenili nastavenia."</string>
+ <string name="controls_error_removed_title" msgid="1207794911208047818">"Ovládač nie je k dispozícii"</string>
+ <string name="controls_error_removed_message" msgid="2885911717034750542">"Nepodarilo sa získať prístup k zariadeniu <xliff:g id="DEVICE">%1$s</xliff:g>. V aplikácii <xliff:g id="APPLICATION">%2$s</xliff:g> skontrolujte, či je ovládač stále k dispozícii a či sa nezmenili nastavenia."</string>
<string name="controls_open_app" msgid="483650971094300141">"Otvoriť aplikáciu"</string>
<string name="controls_error_generic" msgid="352500456918362905">"Stav sa nepodarilo načítať"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Chyba, skúste to znova"</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 326ae97cdec3..05c71431a030 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -458,8 +458,8 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Znova se dotaknite, da odprete"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Povlecite navzgor, da odprete"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Povlecite navzgor za vnovičen poskus"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"To napravo upravlja vaša organizacija"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"To napravo upravlja <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
+ <string name="do_disclosure_generic" msgid="4896482821974707167">"Ta naprava pripada vaši organizaciji"</string>
+ <string name="do_disclosure_with_name" msgid="2091641464065004091">"Ta naprava pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="6682125338461375925">"Povlecite z ikone za telefon"</string>
<string name="voice_hint" msgid="7476017460191291417">"Povlecite z ikone za glasovnega pomočnika"</string>
<string name="camera_hint" msgid="4519495795000658637">"Povlecite z ikone za fotoaparat"</string>
@@ -527,21 +527,21 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"Profil je morda nadziran"</string>
<string name="vpn_footer" msgid="3457155078010607471">"Omrežje je lahko nadzorovano"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"Omrežje je morda nadzorovano"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"To napravo upravlja vaša organizacija in lahko nadzira omrežni promet."</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"To napravo upravlja <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> in lahko nadzira omrežni promet."</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"Naprava, ki jo upravlja vaša organizacija, je povezana z aplikacijo <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"Naprava, ki jo upravlja <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>, je povezana z aplikacijo <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"Napravo upravlja vaša organizacija"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"Napravo upravlja <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>."</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"Naprava, ki jo upravlja vaša organizacija, je povezana z omrežji VPN"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"Naprava, ki jo upravlja <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>, je povezana z omrežji VPN"</string>
+ <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Vaša organizacija je lastnica te naprave in lahko nadzira omrežni promet"</string>
+ <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Organizacija <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> je lastnica te naprave in lahko nadzira omrežni promet"</string>
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Ta naprava pripada vaši organizaciji in je povezana v aplikacijo <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Ta naprava pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> in je povezana v aplikacijo <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Ta naprava pripada vaši organizaciji"</string>
+ <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Ta naprava pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management_vpns" msgid="371835422690053154">"Ta naprava pripada vaši organizaciji in je povezana v omrežja VPN"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="4046375645500668555">"Ta naprava pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> in je povezana v omrežja VPN"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Vaša organizacija lahko nadzira omrežni promet v vašem delovnem profilu"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> lahko nadzira omrežni promet v vašem delovnem profilu"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Omrežje je morda nadzorovano"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"Naprava je povezana z omrežji VPN"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"Delovni profil je povezan z aplikacijo <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"Osebni profil je povezan z aplikacijo <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"Naprava je povezana z aplikacijo <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_vpns" msgid="7213546797022280246">"Ta naprava je povezana v omrežja VPN"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Vaš delovni profil je povezan v aplikacijo <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Vaš osebni profil je povezan v aplikacijo <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Ta naprava je povezava v aplikacijo <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Upravljanje naprav"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Nadzor nad profilom"</string>
<string name="monitoring_title" msgid="4063890083735924568">"Nadzor omrežja"</string>
@@ -551,8 +551,8 @@
<string name="disable_vpn" msgid="482685974985502922">"Onemogoči VPN"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"Prekini povezavo z VPN-jem"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"Prikaži pravilnike"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"Napravo upravlja organizacija <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nSkrbnik lahko nadzira in upravlja nastavitve, dostop za podjetje, aplikacije, z napravo povezane podatke in podatke o lokaciji naprave.\n\nZa več informacij se obrnite na skrbnika."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"Napravo upravlja vaša organizacija.\n\nSkrbnik lahko nadzira in upravlja nastavitve, dostop za podjetje, aplikacije, z napravo povezane podatke in podatke o lokaciji naprave.\n\nZa več informacij se obrnite na skrbnika."</string>
+ <string name="monitoring_description_named_management" msgid="505833016545056036">"Ta naprava pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nSkrbnik za IT lahko nadzira in upravlja nastavitve, dostop za podjetje, aplikacije, z napravo povezane podatke in podatke o lokaciji naprave.\n\nZa več informacij se obrnite na skrbnika za IT."</string>
+ <string name="monitoring_description_management" msgid="4308879039175729014">"Ta naprava pripada vaši organizaciji.\n\nSkrbnik za IT lahko nadzira in upravlja nastavitve, dostop za podjetje, aplikacije, z napravo povezane podatke in podatke o lokaciji naprave.\n\nZa več informacij se obrnite na skrbnika za IT."</string>
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Vaša organizacija je v to napravo namestila overitelja potrdil. Varni omrežni promet se lahko nadzira ali spreminja."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Vaša organizacija je v vaš delovni profil namestila overitelja potrdil. Varni omrežni promet se lahko nadzira ali spreminja."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"V tej napravi je nameščen overitelj potrdil. Varni omrežni promet se lahko nadzira ali spreminja."</string>
@@ -930,6 +930,7 @@
<string name="pip_pause" msgid="1139598607050555845">"Začasno ustavi"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"Preskoči na naslednjega"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"Preskoči na prejšnjega"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"Spremeni velikost"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"Tel. izklopljen zaradi vročine"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"Zdaj telefon normalno deluje"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Telefon je bil prevroč, zato se je izklopil, da se ohladi. Zdaj normalno deluje.\n\nTelefon lahko postane prevroč ob:\n • uporabi aplikacij, ki intenzivno porabljajo sredstva (npr. za igranje iger, videoposnetke ali navigacijo)\n • prenosu ali nalaganju velikih datotek\n • uporabi telefona pri visokih temp."</string>
@@ -1016,7 +1017,7 @@
<string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Pogovora ne prikaži v oblačku"</string>
<string name="bubbles_user_education_title" msgid="5547017089271445797">"Klepet z oblački"</string>
<string name="bubbles_user_education_description" msgid="1160281719576715211">"Novi pogovori so prikazani kot lebdeče ikone ali oblački. Če želite odpreti oblaček, se ga dotaknite. Če ga želite premakniti, ga povlecite."</string>
- <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Upravljanje oblačkov kadar koli"</string>
+ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Upravljanje oblačkov"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"Dotaknite se »Upravljanje«, da izklopite oblačke iz te aplikacije"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Razumem"</string>
<string name="bubbles_app_settings" msgid="5779443644062348657">"Nastavitve za <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
@@ -1025,8 +1026,8 @@
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Stanje pripravljenosti"</string>
<string name="priority_onboarding_title" msgid="2893070698479227616">"Pogovor je nastavljen kot prednosten"</string>
<string name="priority_onboarding_behavior" msgid="5342816047020432929">"Prednostni pogovori bodo:"</string>
- <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Prikazano na vrhu razdelka s pogovorom"</string>
- <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Prikaz profilne slike na zaklenjenem zaslonu"</string>
+ <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Prikazani na vrhu razdelka s pogovorom"</string>
+ <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Prikazali profilno sliko na zaklenjenem zaslonu"</string>
<string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Prikazano kot lebdeč oblaček čez druge aplikacije"</string>
<string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Preglasi način »ne moti«"</string>
<string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"V redu"</string>
@@ -1057,7 +1058,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Držite in povlecite, da prerazporedite kontrolnike"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"Vsi kontrolniki so bili odstranjeni"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Spremembe niso shranjene"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"Seznama vseh kontrolnikov ni bilo mogoče naložiti."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"Kontrolnikov ni bilo mogoče naložiti. Preverite aplikacijo <xliff:g id="APP">%s</xliff:g> in se prepričajte, da se njene nastavitve niso spremenile."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"Združljivi kontrolniki niso na voljo"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Drugo"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"Dodajanje med kontrolnike naprave"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"Dodaj"</string>
@@ -1073,8 +1075,11 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"Potrdite spremembo za napravo <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Če si želite ogledati več, povlecite"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Nalaganje priporočil"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"Zapri to sejo predstavnosti"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"Predstavnost"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"Skrije trenutno sejo."</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Skrij"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Nadaljuj"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"Nastavitve"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Neaktivno, poglejte aplikacijo"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Napaka, vnovični poskus …"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Ni mogoče najti"</string>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index d0d16c367b2c..184825c200ef 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -454,8 +454,8 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Trokit përsëri për ta hapur"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Rrëshqit lart për ta hapur"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Rrëshqit lart për të provuar përsëri"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"Kjo pajisje menaxhohet nga organizata jote"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"Kjo pajisje menaxhohet nga <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
+ <string name="do_disclosure_generic" msgid="4896482821974707167">"Kjo pajisje i përket organizatës sate"</string>
+ <string name="do_disclosure_with_name" msgid="2091641464065004091">"Kjo pajisje i përket <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="6682125338461375925">"Rrëshqit për të hapur telefonin"</string>
<string name="voice_hint" msgid="7476017460191291417">"Rrëshqit për të hapur ndihmën zanore"</string>
<string name="camera_hint" msgid="4519495795000658637">"Rrëshqit për të hapur kamerën"</string>
@@ -521,21 +521,21 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"Profili mund të monitorohet"</string>
<string name="vpn_footer" msgid="3457155078010607471">"Rrjeti mund të jetë i monitoruar"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"Rrjeti mund të jetë i monitoruar"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"Organizata jote e menaxhon këtë pajisje dhe mund të monitorojë trafikun e rrjetit."</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> menaxhon këtë pajisje dhe mund të monitorojë trafikun e rrjetit"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"Pajisja menaxhohet nga organizata jote dhe është lidhur me <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"Pajisja menaxhohet nga <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> dhe është e lidhur me <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"Pajisja menaxhohet nga organizata jote"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"Pajisja menaxhohet nga <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"Pajisja menaxhohet nga organizata jote dhe është e lidhur me VPN"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"Pajisja menaxhohet nga <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> dhe është e lidhur me VPN"</string>
+ <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Organizata jote e zotëron këtë pajisje dhe mund të monitorojë trafikun e rrjetit"</string>
+ <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> e zotëron këtë pajisje dhe mund të monitorojë trafikun e rrjetit"</string>
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Kjo pajisje i përket organizatës sate dhe është e lidhur me <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Kjo pajisje i përket <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> dhe është e lidhur me <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Kjo pajisje i përket organizatës sate"</string>
+ <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Kjo pajisje i përket <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management_vpns" msgid="371835422690053154">"Kjo pajisje i përket organizatës sate dhe është e lidhur me rrjetet VPN"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="4046375645500668555">"Kjo pajisje i përket <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> dhe është e lidhur me rrjetet VPN"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Organizata jote mund të monitorojë trafikun e rrjetit në profilin tënd të punës"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> mund të monitorojë trafikun e rrjetit në profilin tënd të punës"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Rrjeti mund të jetë i monitoruar"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"Pajisja është e lidhur me VPN"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"Profili i punës është i lidhur me <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"Profili personal është i lidhur me <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"Pajisja është e lidhur me <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_vpns" msgid="7213546797022280246">"Kjo pajisje është e lidhur me rrjetet VPN"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Profili yt i punës është i lidhur me <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Profili yt personal është i lidhur me <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Kjo pajisje është e lidhur me <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Menaxhimi i pajisjes"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Monitorimi i profilit"</string>
<string name="monitoring_title" msgid="4063890083735924568">"Monitorimi i rrjetit"</string>
@@ -545,8 +545,8 @@
<string name="disable_vpn" msgid="482685974985502922">"Çaktivizo VPN-në"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"Shkëput VPN-në"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"Shiko politikat"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"Pajisja jote menaxhohet nga <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nAdministratori mund të monitorojë dhe menaxhojë cilësimet, qasjen e korporatës, aplikacionet, të dhënat e lidhura me pajisjen tënde, si dhe informacionet e vendndodhjes së pajisjes tënde.\n\nPër më shumë informacione, kontakto me administratorin."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"Pajisja jote menaxhohet nga organizata jote.\n\nAdministratori mund të monitorojë dhe menaxhojë cilësimet, qasjen e korporatës, aplikacionet, të dhënat e lidhura me pajisjen tënde, si dhe informacionet e vendndodhjes së pajisjes tënde.\n\nPër më shumë informacione, kontakto me administratorin."</string>
+ <string name="monitoring_description_named_management" msgid="505833016545056036">"Kjo pajisje i përket <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nAdministratori i teknologjisë së informacionit mund të monitorojë dhe menaxhojë cilësimet, qasjen e korporatës, aplikacionet, të dhënat e lidhura me pajisjen tënde, si dhe informacionet e vendndodhjes së pajisjes tënde.\n\nPër më shumë informacione, kontakto me administratorin e teknologjisë së informacionit."</string>
+ <string name="monitoring_description_management" msgid="4308879039175729014">"Kjo pajisje i përket organizatës sate.\n\nAdministratori i teknologjisë së informacionit mund të monitorojë dhe menaxhojë cilësimet, qasjen e korporatës, aplikacionet, të dhënat e lidhura me pajisjen tënde, si dhe informacionet e vendndodhjes së pajisjes tënde.\n\nPër më shumë informacione, kontakto me administratorin e teknologjisë së informacionit."</string>
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Organizata jote instaloi një autoritet certifikate në këtë pajisje. Trafiku i rrjetit tënd të sigurt mund të monitorohet ose modifikohet."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Organizata jote instaloi një autoritet certifikate në profilin tënd të punës. Trafiku i rrjetit tënd të sigurt mund të monitorohet ose modifikohet."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Në këtë pajisje është instaluar një autoritet certifikate. Trafiku i rrjetit tënd të sigurt mund të monitorohet ose modifikohet."</string>
@@ -920,6 +920,7 @@
<string name="pip_pause" msgid="1139598607050555845">"Ndërprit"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"Kalo te tjetra"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"Kalo tek e mëparshmja"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"Ndrysho përmasat"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"Telefoni u fik për shkak të nxehtësisë"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"Telefoni tani punon normalisht"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Telefoni yt ishte tepër i nxehtë, prandaj u fik për t\'u ftohur. Telefoni tani punon normalisht.\n\nTelefoni mund të nxehet së tepërmi nëse ti:\n • Përdor aplikacione intensive për burimet (siç janë aplikacionet e lojërave, videove apo aplikacionet e navigimit)\n • Shkarkon ose ngarkon skedarë të mëdhenj\n • E përdor telefonin në temperatura të larta"</string>
@@ -1015,8 +1016,8 @@
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Në gatishmëri"</string>
<string name="priority_onboarding_title" msgid="2893070698479227616">"Biseda u caktua me përparësi"</string>
<string name="priority_onboarding_behavior" msgid="5342816047020432929">"Bisedat me përparësi do të:"</string>
- <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Shfaq në krye të seksionit të bisedës"</string>
- <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Shfaq figurën e profilit në ekranin e kyçjes"</string>
+ <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Shfaqen në krye të seksionit të bisedës"</string>
+ <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Shfaqin fotografinë e profilit në ekranin e kyçjes"</string>
<string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Shfaq si flluskë pluskuese mbi aplikacione"</string>
<string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Ndërprit \"Mos shqetëso\""</string>
<string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"E kuptova"</string>
@@ -1045,7 +1046,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Mbaje të shtypur dhe zvarrit për të risistemuar kontrollet"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"Të gjitha kontrollet u hoqën"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Ndryshimet nuk u ruajtën"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"Lista e të gjitha kontrolleve nuk mund të ngarkohej."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"Kontrollet nuk mund të ngarkoheshin. Kontrollo aplikacionin <xliff:g id="APP">%s</xliff:g> për t\'u siguruar që cilësimet e aplikacionit nuk janë ndryshuar."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"Kontrollet e përputhshme nuk ofrohen"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Tjetër"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"Shto te kontrollet e pajisjes"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"Shto"</string>
@@ -1061,8 +1063,11 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"Konfirmo ndryshimin për <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Rrëshqit shpejt për të shikuar më shumë"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Po ngarkon rekomandimet"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"Mbyll këtë sesion të medias"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"Media"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"Fshih sesionin aktual."</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Fshih"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Vazhdo"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"Cilësimet"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Joaktive, kontrollo aplikacionin"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Gabim, po provohet përsëri"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Nuk u gjet"</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index f692e1cc20d9..9be52e6cb40c 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -456,8 +456,8 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Додирните поново да бисте отворили"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Превуците нагоре да бисте отворили"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Превуците нагоре да бисте пробали поново"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"Овим уређајем управља организација"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"Овим уређајем управља <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
+ <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="phone_hint" msgid="6682125338461375925">"Превуците од иконе за телефон"</string>
<string name="voice_hint" msgid="7476017460191291417">"Превуците од иконе за гласовну помоћ"</string>
<string name="camera_hint" msgid="4519495795000658637">"Превуците од иконе за камеру"</string>
@@ -524,21 +524,21 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"Профил се можда надгледа"</string>
<string name="vpn_footer" msgid="3457155078010607471">"Мрежа се можда надгледа"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"Мрежа се можда надгледа"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"Организација управља овим уређајем и може да надгледа мрежни саобраћај"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> управља овим уређајем и може да надгледа мрежни саобраћај"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"Уређајем управља организација и повезан је са апликацијом <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"Уређајем управља <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> и повезан је са апликацијом <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"Уређајем управља организација"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"Овим уређајем управља <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"Уређајем управља организација и повезан је са VPN-овима"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"Уређајем управља <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> и повезан је са VPN-овима"</string>
+ <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Организација је власник уређаја и може да надгледа мрежни саобраћај"</string>
+ <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> је власник овог уређаја и може да надгледа мрежни саобраћај"</string>
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Овај уређај припада организацији и повезан је са апликацијом <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Овај уређај припада организацији <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> и повезан је са апликацијом <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Овај уређај припада организацији"</string>
+ <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Овај уређај припада организацији <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management_vpns" msgid="371835422690053154">"Овај уређај припада организацији и повезан је са VPN-овима"</string>
+ <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_monitoring" msgid="8548019955631378680">"Мрежа се можда надгледа"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"Уређај је повезан са VPN-овима"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"Пословни профил је повезан са апликацијом <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"Лични профил је повезан са апликацијом <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"Уређај је повезан са апликацијом <xliff:g id="VPN_APP">%1$s</xliff:g>"</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>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Ваш лични профил је повезан са апликацијом <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Овај уређај је повезан са апликацијом <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Управљање уређајима"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Надгледање профила"</string>
<string name="monitoring_title" msgid="4063890083735924568">"Надгледање мреже"</string>
@@ -548,8 +548,8 @@
<string name="disable_vpn" msgid="482685974985502922">"Онемогући VPN"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"Прекини везу са VPN-ом"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"Прикажи смернице"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"Уређајем управља <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nАдминистратор може да надгледа подешавања, корпоративни приступ, апликације, податке повезане са уређајем и информације о локацији уређаја, као и да управља њима.\n\nВише информација потражите од администратора."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"Уређајем управља организација.\n\nАдминистратор може да надгледа подешавања, корпоративни приступ, апликације, податке повезане са уређајем и информације о локацији уређаја, као и да управља њима.\n\nВише информација потражите од администратора."</string>
+ <string name="monitoring_description_named_management" msgid="505833016545056036">"Овај уређај припада организацији <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nИТ администратор може да надгледа подешавања, корпоративни приступ, апликације, податке повезане са уређајем и информације о локацији уређаја, као и да управља њима.\n\nВише информација потражите од ИТ администратора."</string>
+ <string name="monitoring_description_management" msgid="4308879039175729014">"Овај уређај припада организацији.\n\nИТ администратор може да надгледа подешавања, корпоративни приступ, апликације, податке повезане са уређајем и информације о локацији уређаја, као и да управља њима.\n\nВише информација потражите од ИТ администратора."</string>
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Организација је на овом уређају инсталирала ауторитет за издавање сертификата. Безбедни мрежни саобраћај може да се прати или мења."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Организација је на пословном профилу инсталирала ауторитет за издавање сертификата. Безбедни мрежни саобраћај може да се прати или мења."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"На овом уређају је инсталиран ауторитет за издавање сертификата. Безбедни мрежни саобраћај може да се прати или мења."</string>
@@ -925,6 +925,7 @@
<string name="pip_pause" msgid="1139598607050555845">"Паузирај"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"Пређи на следеће"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"Пређи на претходно"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"Промените величину"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"Телефон се искључио због топлоте"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"Телефон сада нормално ради"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Телефон је био преврућ, па се искључио да се охлади. Сада ради нормално.\n\nТелефон може превише да се угреје ако:\n • Користите апликације које захтевају пуно ресурса (нпр. видео игре, видео или апликације за навигацију)\n • Преузимате/отпремате велике датотеке\n • Користите телефон на високој температури"</string>
@@ -1007,7 +1008,7 @@
<string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Премести горе десно"</string>
<string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Премести доле лево"</string>
<string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Премести доле десно"</string>
- <string name="bubble_dismiss_text" msgid="1314082410868930066">"Одбацивање облачића"</string>
+ <string name="bubble_dismiss_text" msgid="1314082410868930066">"Одбаци облачић"</string>
<string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Не користи облачиће за конверзацију"</string>
<string name="bubbles_user_education_title" msgid="5547017089271445797">"Ћаскајте у облачићима"</string>
<string name="bubbles_user_education_description" msgid="1160281719576715211">"Нове конверзације се приказују као плутајуће иконе или облачићи. Додирните да бисте отворили облачић. Превуците да бисте га преместили."</string>
@@ -1019,9 +1020,9 @@
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Идите у Подешавања да бисте ажурирали навигацију система"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Стање приправности"</string>
<string name="priority_onboarding_title" msgid="2893070698479227616">"Конверзација је подешена на приоритетну"</string>
- <string name="priority_onboarding_behavior" msgid="5342816047020432929">"Приоритетне конверзације ће:"</string>
- <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Приказује се у врху одељка за конверзације"</string>
- <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Приказује слику профила на закључаном екрану"</string>
+ <string name="priority_onboarding_behavior" msgid="5342816047020432929">"Приоритетне конверзације:"</string>
+ <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"се приказују у врху одељка за конверзације"</string>
+ <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"приказују слику профила на закључаном екрану"</string>
<string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Приказују се плутајући облачићи преко апликација"</string>
<string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Омета подешавање Не узнемиравај"</string>
<string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Важи"</string>
@@ -1051,7 +1052,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Задржите и превуците да бисте променили распоред контрола"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"Све контроле су уклоњене"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Промене нису сачуване"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"Учитавање листе свих контрола није успело."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"Учитавање контрола није успело. Погледајте апликацију <xliff:g id="APP">%s</xliff:g> да бисте се уверили да се подешавања апликације нису променила."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"Компатибилне контроле нису доступне"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Друго"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"Додајте у контроле уређаја"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"Додај"</string>
@@ -1067,8 +1069,11 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"Потврдите промену за: <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Превуците да бисте видели још"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Учитавају се препоруке"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"Затворите ову сесију медија"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"Медији"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"Сакријте актуелну сесију."</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Сакриј"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Настави"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"Подешавања"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Неактивно. Видите апликацију"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Грешка, покушава се поново…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Није пронађено"</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index f7d19ac3472d..f723c84fdfe3 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -454,8 +454,10 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Tryck igen för att öppna"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Öppna genom att svepa uppåt"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Svep uppåt om du vill försöka igen"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"Den här enheten hanteras av organisationen"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"Den här enheten hanteras av <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for do_disclosure_generic (4896482821974707167) -->
+ <skip />
+ <!-- no translation found for do_disclosure_with_name (2091641464065004091) -->
+ <skip />
<string name="phone_hint" msgid="6682125338461375925">"Svep från ikonen och öppna telefonen"</string>
<string name="voice_hint" msgid="7476017460191291417">"Svep från ikonen och öppna röstassistenten"</string>
<string name="camera_hint" msgid="4519495795000658637">"Svep från ikonen och öppna kameran"</string>
@@ -521,21 +523,33 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"Det kan hända att profilen övervakas"</string>
<string name="vpn_footer" msgid="3457155078010607471">"Nätverket kan vara övervakat"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"Nätverket kan vara övervakat"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"Organisationen hanterar enheten och kan övervaka nätverkstrafiken"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> hanterar enheten och kan övervaka nätverkstrafiken"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"Enheten hanteras av organisationen och är ansluten till <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"Enheten hanteras av <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> och är ansluten till <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"Enheten hanteras av organisationen"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"Enheten hanteras av <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"Enheten hanteras av organisationen och är ansluten till VPN"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"Enheten hanteras av <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> och är ansluten till VPN"</string>
+ <!-- no translation found for quick_settings_disclosure_management_monitoring (8231336875820702180) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_monitoring (2831423806103479812) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_named_vpn (6096715329056415588) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (5302786161534380104) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management (5515296598440684962) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management (3476472755775165827) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_vpns (371835422690053154) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_vpns (4046375645500668555) -->
+ <skip />
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Organisationen kan övervaka nätverkstrafik i jobbprofilen"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> kan övervaka nätverkstrafiken i jobbprofilen"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Nätverket kan vara övervakat"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"Enheten är ansluten till VPN"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"Jobbprofilen är ansluten till <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"Den personliga profilen är ansluten till <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"Enheten är ansluten till <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <!-- no translation found for quick_settings_disclosure_vpns (7213546797022280246) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (8117568745060010789) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (5481763430080807797) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_vpn (2350838218824492465) -->
+ <skip />
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Enhetshantering"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Profilövervakning"</string>
<string name="monitoring_title" msgid="4063890083735924568">"Nätverksövervakning"</string>
@@ -545,8 +559,10 @@
<string name="disable_vpn" msgid="482685974985502922">"Inaktivera VPN"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"Koppla från VPN"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"Visa policyer"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"Din enhet hanteras av <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nAdministratören kan övervaka och hantera inställningar, företagsåtkomst, appar, data med koppling till enheten och enhetens plats.\n\nKontakta administratören om du vill veta mer."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"Din enhet hanteras av organisationen.\n\nAdministratören kan övervaka och hantera inställningar, företagsåtkomst, appar, data med koppling till enheten och enhetens plats.\n\nKontakta administratören om du vill veta mer."</string>
+ <!-- no translation found for monitoring_description_named_management (505833016545056036) -->
+ <skip />
+ <!-- no translation found for monitoring_description_management (4308879039175729014) -->
+ <skip />
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Organisationen har installerat en certifikatutfärdare på enheten. Din säkra nätverkstrafik kan övervakas och ändras."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Organisationen har installerat en certifikatutfärdare i jobbprofilen. Din säkra nätverkstrafik kan övervakas och ändras."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"En certifikatutfärdare är installerad på enheten. Din säkra nätverkstrafik kan övervakas och ändras."</string>
@@ -920,6 +936,7 @@
<string name="pip_pause" msgid="1139598607050555845">"Pausa"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"Hoppa till nästa"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"Hoppa till föregående"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"Ändra storlek"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"Mobilen stängdes av pga. värme"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"Mobilen fungerar nu som vanligt"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Mobilen var för varm och stängdes av för att kylas ned. Den fungerar nu som vanligt.\n\nMobilen kan bli för varm om du\n • använder resurskrävande appar (till exempel spel-, video- eller navigeringsappar)\n • laddar ned eller laddar upp stora filer\n • använder mobilen vid höga temperaturer."</string>
@@ -1015,8 +1032,8 @@
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Viloläge"</string>
<string name="priority_onboarding_title" msgid="2893070698479227616">"Konversationen har angetts som prioriterad"</string>
<string name="priority_onboarding_behavior" msgid="5342816047020432929">"Följande gäller för prioriterade konversationer:"</string>
- <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Visa högst upp bland konversationerna"</string>
- <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Visa profilbild på låsskärmen"</string>
+ <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"De visas högst upp bland konversationerna"</string>
+ <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Profilbilden visas på låsskärmen"</string>
<string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Visa som en flytande bubbla ovanpå appar"</string>
<string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Avbryt Stör ej"</string>
<string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"OK"</string>
@@ -1045,7 +1062,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Ändra ordning på kontrollerna genom att trycka och dra"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"Alla kontroller har tagits bort"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Ändringarna har inte sparats"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"Listan med alla kontroller kunde inte läsas in."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"Det gick inte att läsa in enhetsstyrning. Kontrollera att inställningarna inte har ändrats i <xliff:g id="APP">%s</xliff:g>-appen."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"Ingen kompatibel enhetsstyrning tillgänglig"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Övrigt"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"Lägg till i enhetsstyrning"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"Lägg till"</string>
@@ -1061,15 +1079,18 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"Bekräfta ändring av <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Svep om du vill se mer"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Rekommendationer läses in"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"Stäng den här sessionen"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"Media"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"Dölj den aktuella sessionen."</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Dölj"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Återuppta"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"Inställningar"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inaktiv, kolla appen"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Fel, försöker igen …"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Hittades inte"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"Styrning är inte tillgänglig"</string>
<string name="controls_error_removed_message" msgid="2885911717034750542">"Det gick inte att komma åt <xliff:g id="DEVICE">%1$s</xliff:g>. Kontrollera att enheten fortfarande är tillgänglig för styrning och att appinställningarna inte har ändrats i <xliff:g id="APPLICATION">%2$s</xliff:g>-appen."</string>
<string name="controls_open_app" msgid="483650971094300141">"Öppna appen"</string>
- <string name="controls_error_generic" msgid="352500456918362905">"Ingen status lästes in"</string>
+ <string name="controls_error_generic" msgid="352500456918362905">"Status otillgänglig"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Fel, försök igen"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"Pågår"</string>
<string name="controls_added_tooltip" msgid="4842812921719153085">"De nya snabbkontrollerna visas om du håller strömbrytaren nedtryckt"</string>
diff --git a/packages/SystemUI/res/values-sv/strings_tv.xml b/packages/SystemUI/res/values-sv/strings_tv.xml
index 64d61621b001..cf40057a005a 100644
--- a/packages/SystemUI/res/values-sv/strings_tv.xml
+++ b/packages/SystemUI/res/values-sv/strings_tv.xml
@@ -24,5 +24,5 @@
<string name="pip_close" msgid="5775212044472849930">"Stäng PIP"</string>
<string name="pip_fullscreen" msgid="3877997489869475181">"Helskärm"</string>
<string name="mic_active" msgid="5766614241012047024">"Mikrofonen är aktiv"</string>
- <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s har använt mikrofonen"</string>
+ <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s har fått åtkomst till mikrofonen"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 1a0b9ec653ae..2ae2b3c4e00f 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -454,8 +454,8 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Gusa tena ili ufungue"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Telezesha kidole juu ili ufungue"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Telezesha kidole juu ili ujaribu tena"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"Kifaa hiki kinasimamiwa na shirika lako"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"Kifaa hiki kinadhibitiwa na <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
+ <string name="do_disclosure_generic" msgid="4896482821974707167">"Kifaa hiki kinamilikiwa na shirika lako"</string>
+ <string name="do_disclosure_with_name" msgid="2091641464065004091">"Kifaa hiki kinamilikiwa na <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="6682125338461375925">"Telezesha kidole kutoka kwa aikoni ili ufikie simu"</string>
<string name="voice_hint" msgid="7476017460191291417">"Telezesha kidole kutoka aikoni ili upate mapendekezo ya sauti"</string>
<string name="camera_hint" msgid="4519495795000658637">"Telezesha kidole kutoka aikoni ili ufikie kamera"</string>
@@ -521,21 +521,21 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"Huenda wasifu ukafuatiliwa"</string>
<string name="vpn_footer" msgid="3457155078010607471">"Huenda mtandao unafuatiliwa"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"Huenda mtandao unafuatiliwa"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"Shirika lako linadhibiti kifaa hiki na huenda likafuatilia shughuli kwenye mtandao"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> inadhibiti kifaa hiki na huenda ikafuatilia shughuli kwenye mtandao"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"Kifaa kinasimamiwa na shirika lako na kimeunganishwa kwenye <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"Kifaa hiki kinasimamiwa na <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> na kimeunganishwa kwenye <xliff:g id="VPN_APP">%2$s</xliff:g>."</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"Kifaa kinasimamiwa na shirika lako"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"Kifaa hiki kinasimamiwa na <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"Kifaa kinasimamiwa na shirika lako na kimeunganishwa kwenye VPN"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"Kifaa hiki kinasimamiwa na <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> na kimeunganishwa kwenye VPN."</string>
+ <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Shirika lako linamiliki kifaa hiki na huenda likafuatilia trafiki ya mtandao"</string>
+ <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> inamiliki kifaa hiki na huenda ikafuatilia trafiki ya mtandao"</string>
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Kifaa hiki kinamilikiwa na shirika lako na kimeunganishwa kwenye <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Kifaa hiki kinamilikiwa na <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> na kimeunganishwa kwenye <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Kifaa hiki kinamilikiwa na shirika lako"</string>
+ <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Kifaa hiki kinamilikiwa na <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management_vpns" msgid="371835422690053154">"Kifaa hiki kinamilikiwa na shirika lako na kimeunganishwa kwenye VPN"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="4046375645500668555">"Kifaa hiki kinamilikiwa na <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> na kimeunganishwa kwenye VPN"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Huenda shirika lako likafuatilia shughuli kwenye mtandao katika wasifu wako wa kazini"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"Huenda <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ikafuatilia shughuli kwenye mtandao katika wasifu wako wa kazini"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Huenda mtandao unafuatiliwa"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"Kifaa kimeunganishwa kwenye VPN"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"Wasifu wa kazini umeunganishwa kwenye <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"Wasifu wa binafsi umeunganishwa kwenye <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"Kifaa kimeunganishwa kwenye <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_vpns" msgid="7213546797022280246">"Kifaa hiki kimeunganishwa kwenye VPN"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Wasifu wako wa kazini umeunganishwa kwenye <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Wasifu wako wa binafsi umeunganishwa kwenye <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Kifaa hiki kimeunganishwa kwenye <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Udhibiti wa kifaa"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Ufuatiliaji wasifu"</string>
<string name="monitoring_title" msgid="4063890083735924568">"Ufuatiliaji wa mtandao"</string>
@@ -545,8 +545,8 @@
<string name="disable_vpn" msgid="482685974985502922">"Zima VPN"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"Ondoa VPN"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"Angalia Sera"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"Kifaa chako kinadhibitiwa na <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nMsimamizi wako anaweza kufuatilia na kudhibiti mipangilio, ufikiaji wa maudhui ya shirika, programu, data inayohusiana na kifaa chako na maelezo kuhusu mahali kifaa kipo.\n\nKwa maelezo zaidi, wasiliana na msimamizi wako."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"Kifaa chako kinadhibitiwa na shirika lako.\n\nMsimamizi wako anaweza kufuatilia na kudhibiti mipangilio, ufikiaji wa maudhui ya shirika, programu, data inayohusiana na kifaa chako na maelezo kuhusu mahali kifaa kipo.\n\nKwa maelezo zaidi, wasiliana na msimamizi wako."</string>
+ <string name="monitoring_description_named_management" msgid="505833016545056036">"Kifaa hiki kinamilikiwa na <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nMsimamizi wako wa TEHAMA anaweza kufuatilia na kudhibiti mipangilio, ufikiaji wa maudhui ya shirika, programu, data inayohusiana na kifaa chako na maelezo kuhusu mahali kifaa chako kilipo.\n\nKwa maelezo zaidi, wasiliana na msimamizi wako wa TEHAMA."</string>
+ <string name="monitoring_description_management" msgid="4308879039175729014">"Kifaa hiki kinamilikiwa na shirika lako.\n\nMsimamizi wako wa TEHAMA anaweza kufuatilia na kudhibiti mipangilio, ufikiaji wa maudhui ya shirika, programu, data inayohusiana na kifaa chako na maelezo kuhusu mahali kifaa chako kilipo.\n\nKwa maelezo zaidi, wasiliana na msimamizi wako wa TEHAMA."</string>
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Shirika lako limesakinisha mamlaka ya cheti kwenye kifaa hiki. Huenda shughuli kwenye mtandao wako salama zikafuatiliwa au kubadilishwa."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Shirika lako limesakinisha mamlaka ya cheti katika wasifu wako wa kazini. Huenda shughuli kwenye mtandao wako salama zikafuatiliwa au kubadilishwa."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Mamlaka ya cheti imesakinishwa kwenye kifaa hiki. Huenda shughuli kwenye mtandao wako salama zikafuatiliwa au kubadilishwa."</string>
@@ -920,6 +920,7 @@
<string name="pip_pause" msgid="1139598607050555845">"Sitisha"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"Ruka ufikie inayofuata"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"Ruka ufikie iliyotangulia"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"Badilisha ukubwa"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"Simu ilizima kutokana na joto"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"Simu yako sasa inafanya kazi ipasavyo"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Simu yako ilikuwa moto sana, kwa hivyo ilijizima ili ipoe. Simu yako sasa inafanya kazi ipasavyo.\n\nSimu yako inaweza kuwa moto sana ikiwa:\n • Unatumia programu zinazotumia vipengee vingi (kama vile michezo ya video, video au programu za uelekezaji)\n • Unapakua au upakie faili kubwa\n • Unatumia simu yako katika maeneo yenye halijoto ya juu"</string>
@@ -1015,8 +1016,8 @@
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Hali tuli"</string>
<string name="priority_onboarding_title" msgid="2893070698479227616">"Mazungumzo yamepewa kipaumbele"</string>
<string name="priority_onboarding_behavior" msgid="5342816047020432929">"Mazungumzo yaliyopewa kipaumbele:"</string>
- <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Onyesha kwenye sehemu ya juu ya mazungumzo"</string>
- <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Onyesha picha ya wasifu kwenye skrini iliyofungwa"</string>
+ <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Huonyeshwa kwenye sehemu ya juu ya mazungumzo"</string>
+ <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Huonyesha picha ya wasifu kwenye skrini iliyofungwa"</string>
<string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Yataonekana kama kiputo kinachoelea juu ya programu"</string>
<string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Katiza kipengele cha Usinisumbue"</string>
<string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Nimeelewa"</string>
@@ -1045,7 +1046,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Shikilia na uburute ili upange vidhibiti upya"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"Umeondoa vidhibiti vyote"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Mabadiliko hayajahifadhiwa"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"Imeshindwa kupakia orodha ya vidhibiti vyote."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"Imeshindwa kupakia vidhibiti. Angalia programu ya <xliff:g id="APP">%s</xliff:g> ili uhakikishe kuwa mipangilio ya programu haijabadilika."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"Vidhibiti vinavyooana havipatikani"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Nyingine"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"Weka kwenye vidhibiti vya vifaa"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"Weka"</string>
@@ -1061,8 +1063,11 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"Thibitisha mabadiliko kwenye <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Telezesha kidole ili uone zaidi"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Inapakia mapendekezo"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"Funga kipindi hiki cha maudhui"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"Maudhui"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"Ficha kipindi cha sasa."</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ficha"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Endelea"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"Mipangilio"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Haitumiki, angalia programu"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Hitilafu, inajaribu tena…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Hakipatikani"</string>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index 29a186f481cc..b3f42f28a1d0 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -454,8 +454,10 @@
<string name="notification_tap_again" msgid="4477318164947497249">"திறக்க, மீண்டும் தட்டவும்"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"திறப்பதற்கு மேல் நோக்கி ஸ்வைப் செய்யவும்"</string>
<string name="keyguard_retry" msgid="886802522584053523">"மீண்டும் முயல மேல்நோக்கி ஸ்வைப் செய்யவும்"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"இந்தச் சாதனத்தை உங்கள் நிறுவனம் நிர்வகிக்கிறது"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"இந்தச் சாதனத்தை நிர்வகிப்பது: <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for do_disclosure_generic (4896482821974707167) -->
+ <skip />
+ <!-- no translation found for do_disclosure_with_name (2091641464065004091) -->
+ <skip />
<string name="phone_hint" msgid="6682125338461375925">"ஃபோனிற்கு ஐகானிலிருந்து ஸ்வைப் செய்யவும்"</string>
<string name="voice_hint" msgid="7476017460191291417">"குரல் உதவிக்கு ஐகானிலிருந்து ஸ்வைப் செய்யவும்"</string>
<string name="camera_hint" msgid="4519495795000658637">"கேமராவிற்கு ஐகானிலிருந்து ஸ்வைப் செய்யவும்"</string>
@@ -521,21 +523,33 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"சுயவிவரம் கண்காணிக்கப்படலாம்"</string>
<string name="vpn_footer" msgid="3457155078010607471">"நெட்வொர்க் கண்காணிக்கப்படலாம்"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"நெட்வொர்க் கண்காணிக்கப்படலாம்"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"உங்கள் நிறுவனம் இந்தச் சாதனத்தை நிர்வகிக்கும், அத்துடன் அது நெட்வொர்க் ட்ராஃபிக்கைக் கண்காணிக்கலாம்"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> இந்தச் சாதனத்தை நிர்வகிக்கும், அத்துடன் அது நெட்வொர்க் ட்ராஃபிக்கைக் கண்காணிக்கலாம்"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"சாதனத்தை உங்கள் நிறுவனம் நிர்வகிக்கிறது, மேலும் அது <xliff:g id="VPN_APP">%1$s</xliff:g> உடன் இணைக்கப்பட்டுள்ளது"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"சாதனத்தை <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> நிர்வகிக்கிறது, மேலும் அது <xliff:g id="VPN_APP">%2$s</xliff:g> உடன் இணைக்கப்பட்டுள்ளது"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"சாதனத்தை உங்கள் நிறுவனம் நிர்வகிக்கிறது"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"சாதனத்தை <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> நிர்வகிக்கிறது"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"சாதனத்தை உங்கள் நிறுவனம் நிர்வகிக்கிறது, மேலும் அது VPNகளுடன் இணைக்கப்பட்டுள்ளது"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"சாதனத்தை <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> நிர்வகிக்கிறது, மேலும் அது VPNகளுடன் இணைக்கப்பட்டுள்ளது"</string>
+ <!-- no translation found for quick_settings_disclosure_management_monitoring (8231336875820702180) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_monitoring (2831423806103479812) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_named_vpn (6096715329056415588) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (5302786161534380104) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management (5515296598440684962) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management (3476472755775165827) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_vpns (371835422690053154) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_vpns (4046375645500668555) -->
+ <skip />
<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_monitoring" msgid="8548019955631378680">"நெட்வொர்க் கண்காணிக்கப்படலாம்"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"சாதனம் VPNகளுடன் இணைக்கப்பட்டுள்ளது"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"<xliff:g id="VPN_APP">%1$s</xliff:g> உடன் பணிவிவரம் இணைக்கப்பட்டுள்ளது"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"தனிப்பட்ட சுயவிவரம் <xliff:g id="VPN_APP">%1$s</xliff:g> உடன் இணைக்கப்பட்டுள்ளது"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"சாதனம் <xliff:g id="VPN_APP">%1$s</xliff:g> உடன் இணைக்கப்பட்டுள்ளது"</string>
+ <!-- no translation found for quick_settings_disclosure_vpns (7213546797022280246) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (8117568745060010789) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (5481763430080807797) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_vpn (2350838218824492465) -->
+ <skip />
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"சாதன நிர்வாகம்"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"சுயவிவரத்தைக் கண்காணித்தல்"</string>
<string name="monitoring_title" msgid="4063890083735924568">"நெட்வொர்க்கைக் கண்காணித்தல்"</string>
@@ -545,8 +559,10 @@
<string name="disable_vpn" msgid="482685974985502922">"VPNஐ முடக்கு"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"VPNஐத் துண்டி"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"கொள்கைகளைக் காட்டு"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"சாதனத்தை <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> நிர்வகிக்கிறது.\n\nஉங்கள் நிர்வாகியால் அமைப்புகள், நிறுவன அணுகல், ஆப்ஸ், உங்கள் சாதனத்துடன் தொடர்புடைய டேட்டா, சாதனங்களின் இருப்பிடத் தகவல் ஆகியவற்றைக் கண்காணிக்கவும் நிர்வகிக்கவும் முடியும்.\n\nமேலும் தகவலுக்கு, உங்கள் நிர்வாகியைத் தொடர்புகொள்ளவும்."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"சாதனத்தை உங்கள் நிறுவனம் நிர்வகிக்கிறது.\n\nஉங்கள் நிர்வாகியால் அமைப்புகள், நிறுவன அணுகல், ஆப்ஸ், உங்கள் சாதனத்துடன் தொடர்புடைய டேட்டா, சாதனங்களின் இருப்பிடத் தகவல் ஆகியவற்றைக் கண்காணிக்கவும் நிர்வகிக்கவும் முடியும்.\n\nமேலும் தகவலுக்கு, உங்கள் நிர்வாகியைத் தொடர்புகொள்ளவும்."</string>
+ <!-- no translation found for monitoring_description_named_management (505833016545056036) -->
+ <skip />
+ <!-- no translation found for monitoring_description_management (4308879039175729014) -->
+ <skip />
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"உங்கள் நிறுவனம் இந்தச் சாதனத்தில் சான்றிதழ் அங்கீகாரத்தை நிறுவியுள்ளது. உங்களின் பாதுகாப்பான நெட்வொர்க் ட்ராஃபிக் கண்காணிக்கப்படலாம் அல்லது மாற்றப்படலாம்."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"உங்கள் நிறுவனம், பணிக் கணக்கில் சான்றிதழ் அங்கீகாரத்தை நிறுவியுள்ளது. உங்களின் பாதுகாப்பான நெட்வொர்க் ட்ராஃபிக் கண்காணிக்கப்படலாம் அல்லது மாற்றப்படலாம்."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"இந்தச் சாதனத்தில் சான்றிதழ் அங்கீகாரம் நிறுவப்பட்டுள்ளது. உங்களின் பாதுகாப்பான நெட்வொர்க் ட்ராஃபிக் கண்காணிக்கப்படலாம் அல்லது மாற்றப்படலாம்."</string>
@@ -920,6 +936,7 @@
<string name="pip_pause" msgid="1139598607050555845">"இடைநிறுத்து"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"அடுத்ததற்குச் செல்"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"முந்தையதற்குச் செல்"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"அளவு மாற்று"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"வெப்பத்தினால் ஃபோன் ஆஃப் செய்யப்பட்டது"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"இப்போது உங்கள் ஃபோன் இயல்புநிலையில் இயங்குகிறது"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"உங்கள் ஃபோன் அதிகமாகச் சூடானதால், அதன் சூட்டைக் குறைக்க, ஆஃப் செய்யப்பட்டது. இப்போது உங்கள் ஃபோன் இயல்புநிலையில் இயங்குகிறது.\n\nபின்வருவனவற்றைச் செய்தால், ஃபோன் சூடாகலாம்:\n • அதிகளவு தரவைப் பயன்படுத்தும் ஆப்ஸை (எ.கா: கேமிங், வீடியோ (அ) வழிகாட்டுதல் ஆப்ஸ்) பயன்படுத்துவது\n • பெரிய கோப்புகளைப் பதிவிறக்குவது/பதிவேற்றுவது\n • அதிக வெப்பநிலையில் ஃபோனைப் பயன்படுத்துவது"</string>
@@ -1045,7 +1062,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"கட்டுப்பாடுகளை மறுவரிசைப்படுத்த அவற்றைப் பிடித்து இழுக்கவும்"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"கட்டுப்பாடுகள் அனைத்தும் அகற்றப்பட்டன"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"மாற்றங்கள் சேமிக்கப்படவில்லை"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"எல்லா கட்டுப்பாடுகளின் பட்டியலை ஏற்ற முடியவில்லை."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"கட்டுப்பாடுகளை ஏற்ற முடியவில்லை. ஆப்ஸ் அமைப்புகள் மாறவில்லை என்பதை உறுதிப்படுத்த <xliff:g id="APP">%s</xliff:g> ஆப்ஸைப் பார்க்கவும்."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"இணக்கமான கட்டுப்பாடுகள் இல்லை"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"பிற"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"சாதனக் கட்டுப்பாடுகளில் சேர்த்தல்"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"சேர்"</string>
@@ -1061,8 +1079,11 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"<xliff:g id="DEVICE">%s</xliff:g> ஐ மாற்றுவதை உறுதிப்படுத்தவும்"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"மேலும் பார்க்க ஸ்வைப் செய்யவும்"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"பரிந்துரைகளை ஏற்றுகிறது"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"இந்த மீடியா அமர்வை மூடுக"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"மீடியா"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"இந்த அமர்வை மறையுங்கள்."</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"மறை"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"தொடர்க"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"அமைப்புகள்"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"செயலில் இல்லை , சரிபார்க்கவும்"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"பிழை, மீண்டும் முயல்கிறது…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"இல்லை"</string>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 4b56e157b34f..ab8953dc8c31 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -454,8 +454,10 @@
<string name="notification_tap_again" msgid="4477318164947497249">"తెరవడానికి మళ్లీ నొక్కండి"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"తెరవడానికి, పైకి స్వైప్ చేయండి"</string>
<string name="keyguard_retry" msgid="886802522584053523">"మళ్ళీ ప్రయత్నించడానికి పైకి స్వైప్ చేయండి"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"ఈ పరికరాన్ని మీ సంస్థ నిర్వహిస్తోంది"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"ఈ పరికరం <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> నిర్వహణలో ఉంది"</string>
+ <!-- no translation found for do_disclosure_generic (4896482821974707167) -->
+ <skip />
+ <!-- no translation found for do_disclosure_with_name (2091641464065004091) -->
+ <skip />
<string name="phone_hint" msgid="6682125338461375925">"ఫోన్ కోసం చిహ్నాన్ని స్వైప్ చేయండి"</string>
<string name="voice_hint" msgid="7476017460191291417">"వాయిస్ అసిస్టెంట్ చిహ్నం నుండి స్వైప్"</string>
<string name="camera_hint" msgid="4519495795000658637">"కెమెరా కోసం చిహ్నాన్ని స్వైప్ చేయండి"</string>
@@ -521,21 +523,33 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"ప్రొఫైల్‌ని పర్యవేక్షించవచ్చు"</string>
<string name="vpn_footer" msgid="3457155078010607471">"నెట్‌వర్క్ పర్యవేక్షించబడవచ్చు"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"నెట్‌వర్క్ పర్యవేక్షించబడవచ్చు"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"మీ సంస్థ ఈ పరికరాన్ని నిర్వహిస్తుంది మరియు నెట్‌వర్క్ ట్రాఫిక్‌ని పర్యవేక్షించవచ్చు"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ఈ పరికరాన్ని నిర్వహిస్తుంది మరియు నెట్‌వర్క్ ట్రాఫిక్‌ని పర్యవేక్షించవచ్చు"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"పరికరం మీ సంస్థ నిర్వహణలో ఉంది మరియు <xliff:g id="VPN_APP">%1$s</xliff:g>కి కనెక్ట్ చేయబడింది"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"పరికరం <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> నిర్వహణలో ఉంది మరియు <xliff:g id="VPN_APP">%2$s</xliff:g>కి కనెక్ట్ చేయబడింది"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"పరికరం మీ సంస్థ నిర్వహణలో ఉంది"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"పరికరం <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> నిర్వహణలో ఉంది"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"పరికరం మీ సంస్థ నిర్వహణలో ఉంది మరియు VPNలకు కనెక్ట్ చేయబడింది"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"పరికరం <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> నిర్వహణలో ఉంది మరియు VPNలకు కనెక్ట్ చేయబడింది"</string>
+ <!-- no translation found for quick_settings_disclosure_management_monitoring (8231336875820702180) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_monitoring (2831423806103479812) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_named_vpn (6096715329056415588) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (5302786161534380104) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management (5515296598440684962) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management (3476472755775165827) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_vpns (371835422690053154) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_vpns (4046375645500668555) -->
+ <skip />
<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_monitoring" msgid="8548019955631378680">"నెట్‌వర్క్ పర్యవేక్షించబడవచ్చు"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"పరికరం VPNలకు కనెక్ట్ చేయబడింది"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"<xliff:g id="VPN_APP">%1$s</xliff:g>కి కార్యాలయ ప్రొఫైల్ కనెక్ట్ చేయబడింది"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"వ్యక్తిగత ప్రొఫైల్ <xliff:g id="VPN_APP">%1$s</xliff:g>కి కనెక్ట్ చేయబడింది"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"పరికరం <xliff:g id="VPN_APP">%1$s</xliff:g>కి కనెక్ట్ చేయబడింది"</string>
+ <!-- no translation found for quick_settings_disclosure_vpns (7213546797022280246) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (8117568745060010789) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (5481763430080807797) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_vpn (2350838218824492465) -->
+ <skip />
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"పరికర నిర్వహణ"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"ప్రొఫైల్ పర్యవేక్షణ"</string>
<string name="monitoring_title" msgid="4063890083735924568">"నెట్‌వర్క్ పర్యవేక్షణ"</string>
@@ -545,8 +559,10 @@
<string name="disable_vpn" msgid="482685974985502922">"VPNని నిలిపివేయి"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"VPNను డిస్‌కనెక్ట్ చేయి"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"విధానాలను వీక్షించండి"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"మీ పరికరం <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> నిర్వహణలో ఉంది.\n\nమీ నిర్వాహకులు మీ పరికరం అనుబంధిత సెట్టింగ్‌లు, కార్పొరేట్ యాక్సెస్, యాప్‌లు, డేటా మరియు మీ పరికర స్థాన సమాచారం పర్యవేక్షించగలరు మరియు నిర్వహించగలరు.\n\nమరింత సమాచారం కోసం, మీ నిర్వాహకులను సంప్రదించండి."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"మీ పరికరం మీ సంస్థ నిర్వహణలో ఉంది.\n\nమీ నిర్వాహకులు మీ పరికరం అనుబంధిత సెట్టింగ్‌లు, కార్పొరేట్ యాక్సెస్, యాప్‌లు, డేటాను మరియు మీ పరికర స్థాన సమాచారాన్ని పర్యవేక్షించగలరు మరియు నిర్వహించగలరు.\n\nమరింత సమాచారం కోసం, మీ నిర్వాహకులను సంప్రదించండి."</string>
+ <!-- no translation found for monitoring_description_named_management (505833016545056036) -->
+ <skip />
+ <!-- no translation found for monitoring_description_management (4308879039175729014) -->
+ <skip />
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"ఈ పరికరంలో మీ సంస్థ ఒక ప్రమాణపత్ర అధికారాన్ని ఇన్‌స్టాల్ చేసింది. మీ సురక్షిత నెట్‌వర్క్ ట్రాఫిక్ పర్యవేక్షించబడవచ్చు లేదా సవరించబడవచ్చు."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"మీ కార్యాలయ ప్రొఫైల్‌లో మీ సంస్థ ఒక ప్రమాణపత్ర అధికారాన్ని ఇన్‌స్టాల్ చేసింది. మీ సురక్షిత నెట్‌వర్క్ ట్రాఫిక్ పర్యవేక్షించబడవచ్చు లేదా సవరించబడవచ్చు."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"ఈ పరికరంలో ప్రమాణపత్ర అధికారం ఇన్‌స్టాల్ చేయబడింది. మీ సురక్షిత నెట్‌వర్క్ ట్రాఫిక్ పర్యవేక్షించబడవచ్చు లేదా సవరించబడవచ్చు."</string>
@@ -920,6 +936,7 @@
<string name="pip_pause" msgid="1139598607050555845">"పాజ్ చేయి"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"దాటవేసి తర్వాత దానికి వెళ్లు"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"దాటవేసి మునుపటి దానికి వెళ్లు"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"పరిమాణం మార్చు"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"వేడెక్కినందుకు ఫోన్ ఆఫ్ చేయబడింది"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"మీ ఫోన్ ఇప్పుడు సాధారణంగా పని చేస్తుంది"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"మీ ఫోన్ చాలా వేడిగా ఉంది, కనుక చల్లబర్చడానికి ఆఫ్ చేయబడింది. మీ ఫోన్ ఇప్పుడు సాధారణంగా పని చేస్తుంది.\n\nమీరు ఇలా చేస్తే మీ ఫోన్ చాలా వేడెక్కవచ్చు:\n • వనరు-ఆధారిత అనువర్తనాలు (గేమింగ్, వీడియో లేదా నావిగేషన్ వంటి అనువర్తనాలు) ఉపయోగించడం\n • పెద్ద ఫైల్‌లను డౌన్‌లోడ్ లేదా అప్‌లోడ్ చేయడం\n • అధిక ఉష్ణోగ్రతలలో మీ ఫోన్‌ని ఉపయోగించడం"</string>
@@ -1045,7 +1062,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"నియంత్రణల క్రమం మార్చడానికి దేనినైనా పట్టుకుని, లాగి వదిలేయండి"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"అన్ని నియంత్రణలు తీసివేయబడ్డాయి"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"మార్పులు సేవ్ చేయబడలేదు"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"అన్ని నియంత్రణలు గల జాబితాను లోడ్ చేయలేకపోయాము."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"కంట్రోల్‌లను లోడ్ చేయడం సాధ్యపడలేదు. యాప్ సెట్టింగ్‌లు మారలేదని నిర్ధారించడానికి <xliff:g id="APP">%s</xliff:g> యాప్‌ను చెక్ చేయండి."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"అనుకూల కంట్రోల్‌లు అందుబాటులో లేవు"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"ఇతరం"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"పరికరం నియంత్రణలకు జోడించడం"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"జోడించండి"</string>
@@ -1061,8 +1079,11 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"<xliff:g id="DEVICE">%s</xliff:g>కి సంబంధించి మార్పును నిర్ధారించండి"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"మరిన్నింటిని చూడటం కోసం స్వైప్ చేయండి"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"సిఫార్సులు లోడ్ అవుతున్నాయి"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"ఈ మీడియా సెషన్‌ని మూసివేయండి"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"మీడియా"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"ప్రస్తుత సెషన్‌ను దాచు."</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"దాచు"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"కొనసాగించండి"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"సెట్టింగ్‌లు"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"ఇన్‌యాక్టివ్, యాప్ చెక్ చేయండి"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"లోపం, మళ్లీ ప్రయత్నిస్తోంది..."</string>
<string name="controls_error_removed" msgid="6675638069846014366">"కనుగొనబడలేదు"</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index ba16febe18c3..8530da24077b 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -454,8 +454,10 @@
<string name="notification_tap_again" msgid="4477318164947497249">"แตะอีกครั้งเพื่อเปิด"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"เลื่อนขึ้นเพื่อเปิด"</string>
<string name="keyguard_retry" msgid="886802522584053523">"เลื่อนขึ้นเพื่อลองอีกครั้ง"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"อุปกรณ์นี้จัดการโดยองค์กรของคุณ"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"อุปกรณ์เครื่องนี้จัดการโดย <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for do_disclosure_generic (4896482821974707167) -->
+ <skip />
+ <!-- no translation found for do_disclosure_with_name (2091641464065004091) -->
+ <skip />
<string name="phone_hint" msgid="6682125338461375925">"เลื่อนไอคอนโทรศัพท์"</string>
<string name="voice_hint" msgid="7476017460191291417">"เลื่อนไอคอนตัวช่วยเสียง"</string>
<string name="camera_hint" msgid="4519495795000658637">"เลื่อนไอคอนกล้อง"</string>
@@ -521,21 +523,33 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"อาจมีการตรวจสอบโปรไฟล์"</string>
<string name="vpn_footer" msgid="3457155078010607471">"เครือข่ายอาจได้รับการตรวจสอบ"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"เครือข่ายอาจถูกตรวจสอบ"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"องค์กรของคุณจัดการอุปกรณ์นี้และอาจตรวจสอบการจราจรของข้อมูลในเครือข่าย"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> จัดการอุปกรณ์นี้และอาจตรวจสอบการจราจรของข้อมูลในเครือข่าย"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"องค์กรของคุณเป็นผู้จัดการอุปกรณ์นี้ ซึ่งเชื่อมต่ออยู่กับ <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> เป็นผู้จัดการอุปกรณ์นี้ ซึ่งเชื่อมต่ออยู่กับ <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"องค์กรของคุณเป็นผู้จัดการอุปกรณ์นี้"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> เป็นผู้จัดการอุปกรณ์นี้"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"องค์กรของคุณเป็นผู้จัดการอุปกรณ์นี้ ซึ่งเชื่อมต่ออยู่กับ VPN"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> เป็นผู้จัดการอุปกรณ์นี้ ซึ่งเชื่อมต่ออยู่กับ VPN"</string>
+ <!-- no translation found for quick_settings_disclosure_management_monitoring (8231336875820702180) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_monitoring (2831423806103479812) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_named_vpn (6096715329056415588) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (5302786161534380104) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management (5515296598440684962) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management (3476472755775165827) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_vpns (371835422690053154) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_vpns (4046375645500668555) -->
+ <skip />
<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_monitoring" msgid="8548019955631378680">"อาจมีการตรวจสอบเครือข่าย"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"อุปกรณ์เชื่อมต่ออยู่กับ VPN"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"โปรไฟล์งานเชื่อมต่ออยู่กับ <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"โปรไฟล์ส่วนตัวเชื่อมต่ออยู่กับ <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"อุปกรณ์เชื่อมต่ออยู่กับ <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <!-- no translation found for quick_settings_disclosure_vpns (7213546797022280246) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (8117568745060010789) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (5481763430080807797) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_vpn (2350838218824492465) -->
+ <skip />
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"การจัดการอุปกรณ์"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"การตรวจสอบโปรไฟล์"</string>
<string name="monitoring_title" msgid="4063890083735924568">"การตรวจสอบเครือข่าย"</string>
@@ -545,8 +559,10 @@
<string name="disable_vpn" msgid="482685974985502922">"ปิดใช้ VPN"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"ยกเลิกการเชื่อมต่อ VPN"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"ดูนโยบาย"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"อุปกรณ์นี้จัดการโดย <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>\n\nผู้ดูแลระบบสามารถตรวจสอบและจัดการการตั้งค่า การเข้าถึงของบริษัท แอป ข้อมูลที่เชื่อมโยงกับอุปกรณ์ และข้อมูลตำแหน่งของอุปกรณ์\n\nสำหรับข้อมูลเพิ่มเติม โปรดติดต่อผู้แลระบบ"</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"อุปกรณ์นี้จัดการโดยองค์กรของคุณ\n\nผู้ดูแลระบบสามารถตรวจสอบและจัดการการตั้งค่า การเข้าถึงของบริษัท แอป ข้อมูลที่เชื่อมโยงกับอุปกรณ์ และข้อมูลตำแหน่งของอุปกรณ์\n\nสำหรับข้อมูลเพิ่มเติม โปรดติดต่อผู้แลระบบ"</string>
+ <!-- no translation found for monitoring_description_named_management (505833016545056036) -->
+ <skip />
+ <!-- no translation found for monitoring_description_management (4308879039175729014) -->
+ <skip />
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"องค์กรของคุณติดตั้งผู้ออกใบรับรองในอุปกรณ์นี้ อาจมีการตรวจสอบหรือแก้ไขการจราจรของข้อมูลในเครือข่ายที่ปลอดภัยของคุณ"</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"องค์กรของคุณติดตั้งผู้ออกใบรับรองในโปรไฟล์งาน อาจมีการตรวจสอบหรือแก้ไขการจราจรของข้อมูลในเครือข่ายที่ปลอดภัยของคุณ"</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"มีการติดตั้งผู้ออกใบรับรองในอุปกรณ์นี้ อาจมีการตรวจสอบหรือแก้ไขการจราจรของข้อมูลในเครือข่ายที่ปลอดภัยของคุณ"</string>
@@ -920,6 +936,7 @@
<string name="pip_pause" msgid="1139598607050555845">"หยุดชั่วคราว"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"ข้ามไปรายการถัดไป"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"ข้ามไปรายการก่อนหน้า"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"ปรับขนาด"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"โทรศัพท์ปิดไปเพราะร้อนมาก"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"ขณะนี้โทรศัพท์ทำงานเป็นปกติ"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"โทรศัพท์ร้อนเกินไปจึงปิดเครื่องเพื่อให้เย็นลง ขณะนี้โทรศัพท์ทำงานเป็นปกติ\n\nโทรศัพท์อาจร้อนเกินไปหากคุณ\n • ใช้แอปที่ใช้ทรัพยากรมาก (เช่น เกม วิดีโอ หรือแอปการนำทาง)\n • ดาวน์โหลดหรืออัปโหลดไฟล์ขนาดใหญ่\n • ใช้โทรศัพท์ในอุณหภูมิที่สูง"</string>
@@ -1045,7 +1062,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"แตะตัวควบคุมค้างไว้แล้วลากเพื่อจัดเรียงใหม่"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"นำตัวควบคุมทั้งหมดออกแล้ว"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"ยังไม่ได้บันทึกการเปลี่ยนแปลง"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"โหลดรายการตัวควบคุมทั้งหมดไม่ได้"</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"โหลดตัวควบคุมไม่ได้ ตรวจสอบแอป <xliff:g id="APP">%s</xliff:g> ให้แน่ใจว่าการตั้งค่าของแอปไม่เปลี่ยนแปลง"</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"ตัวควบคุมความเข้ากันได้ไม่พร้อมใช้งาน"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"อื่นๆ"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"เพิ่มไปยังระบบควบคุมอุปกรณ์"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"เพิ่ม"</string>
@@ -1061,8 +1079,11 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"ยืนยันการเปลี่ยนแปลงสำหรับ<xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"เลื่อนเพื่อดูเพิ่มเติม"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"กำลังโหลดคำแนะนำ"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"ปิดเซสชันสื่อนี้"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"สื่อ"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"ซ่อนเซสชันปัจจุบัน"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"ซ่อน"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"เล่นต่อ"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"การตั้งค่า"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"ไม่มีการใช้งาน โปรดตรวจสอบแอป"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"มีข้อผิดพลาด กำลังลองอีกครั้ง…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"ไม่พบ"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index e25e52bdf4ab..bfae370511bb 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -454,8 +454,8 @@
<string name="notification_tap_again" msgid="4477318164947497249">"I-tap ulit upang buksan"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Mag-swipe pataas para buksan"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Mag-swipe pataas para subukan ulit"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"Ang device na ito ay pinamamahalaan ng iyong organisasyon"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"Pinamamahalaan ng <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ang device na ito"</string>
+ <string name="do_disclosure_generic" msgid="4896482821974707167">"Pagmamay-ari ng iyong organisasyon ang device na ito"</string>
+ <string name="do_disclosure_with_name" msgid="2091641464065004091">"Pagmamay-ari ng <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ang device na ito"</string>
<string name="phone_hint" msgid="6682125338461375925">"Mag-swipe mula sa icon para sa telepono"</string>
<string name="voice_hint" msgid="7476017460191291417">"Mag-swipe mula sa icon para sa voice assist"</string>
<string name="camera_hint" msgid="4519495795000658637">"Mag-swipe mula sa icon para sa camera"</string>
@@ -521,21 +521,21 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"Maaaring subaybayan ang profile"</string>
<string name="vpn_footer" msgid="3457155078010607471">"Maaaring sinusubaybayan ang network"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"Maaaring sinusubaybayan ang network"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"Pinamamahalaan ng iyong organisasyon ang device na ito at maaaring sumubaybay ng trapiko sa network"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"Pinamamahalaan ng <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ang device na ito at maaari itong sumubaybay ng trapiko sa network"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"Pinamamahalaan ng iyong organisasyon ang device at nakakonekta ito sa <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"Pinamamahalaan ng <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ang device at nakakonekta ito sa <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"Pinamamahalaan ng iyong organisasyon ang device"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"Pinamamahalaan ng <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ang device"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"Pinamamahalaan ng iyong organisasyon ang device at nakakonekta ito sa mga VPN"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"Pinamamahalaan ng <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ang device at nakakonekta ito sa mga VPN"</string>
+ <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Pagmamay-ari ng organisasyon mo ang device na ito at puwede nitong subaybayan ang trapiko sa network"</string>
+ <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Pagmamay-ari ng <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ang device na ito at puwede nitong subaybayan ang trapiko sa network"</string>
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Pagmamay-ari ng iyong organisasyon ang device na ito at nakakonekta ito sa <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Pagmamay-ari ng <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ang device na ito at nakakonekta ito sa <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Pagmamay-ari ng iyong organisasyon ang device na ito"</string>
+ <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Pagmamay-ari ng <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ang device na ito"</string>
+ <string name="quick_settings_disclosure_management_vpns" msgid="371835422690053154">"Pagmamay-ari ng iyong organisasyon ang device na ito nakakonekta ito sa mga VPN"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="4046375645500668555">"Pagmamay-ari ng <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ang device na ito at nakakonekta ito sa mga VPN"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Maaaring sumubaybay ang iyong organisasyon ng trapiko sa network sa profile sa trabaho mo"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"Maaaring subaybayan ng <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ang trapiko sa network sa iyong profile sa trabaho"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Maaaring sinusubaybayan ang network"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"Nakakonekta ang device sa mga VPN"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"Nakakonekta sa <xliff:g id="VPN_APP">%1$s</xliff:g> ang profile sa trabaho"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"Nakakonekta ang personal na profile sa <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"Nakakonekta ang device sa <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_vpns" msgid="7213546797022280246">"Nakakonekta sa mga VPN ang device na ito"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Nakakonekta sa <xliff:g id="VPN_APP">%1$s</xliff:g> ang iyong profile sa trabaho"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Nakakonekta sa <xliff:g id="VPN_APP">%1$s</xliff:g> ang iyong personal na profile"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Nakakonekta sa <xliff:g id="VPN_APP">%1$s</xliff:g> ang device na ito"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Pamamahala ng device"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Pagsubaybay sa Profile"</string>
<string name="monitoring_title" msgid="4063890083735924568">"Pagsubaybay sa network"</string>
@@ -545,8 +545,8 @@
<string name="disable_vpn" msgid="482685974985502922">"I-disable ang VPN"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"Idiskonekta ang VPN"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"Tingnan ang Mga Patakaran"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"Pinamamahalaan ng <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ang iyong device.\n\nMaaaring subaybayan at pamahalaan ng admin mo ang mga setting, pangkumpanyang access, app, data na nauugnay sa iyong device, at ang impormasyon ng lokasyon ng device mo.\n\nPara sa higit pang impormasyon, makipag-ugnayan sa iyong admin."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"Pinamamahalaan ng iyong organisasyon ang device mo.\n\nMaaaring subaybayan at pamahalaan ng iyong admin ang mga setting, pangkumpanyang access, app, data na nauugnay sa device mo, at ang impormasyon ng lokasyon ng iyong device.\n\nPara sa higit pang impormasyon, makipag-ugnayan sa admin mo."</string>
+ <string name="monitoring_description_named_management" msgid="505833016545056036">"Pagmamay-ari ng <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ang device na ito.\n\nMagagawa ng iyong IT admin na subaybayan at pamahalaan ang mga setting, pangkorporasyong access, mga app, data na nauugnay sa device mo, at ang impormasyon ng lokasyon ng iyong device.\n\nPara sa higit pang impormasyon, makipag-ugnayan sa iyong IT admin."</string>
+ <string name="monitoring_description_management" msgid="4308879039175729014">"Pagmamay-ari ng iyong organisasyon ang device na ito.\n\nMagagawa ng iyong IT admin na subaybayan at pamahalaan ang mga setting, pangkorporasyong access, mga app, data na nauugnay sa device mo, at ang impormasyon ng lokasyon ng iyong device.\n\nPara sa higit pang impormasyon, makipag-ugnayan sa iyong IT admin."</string>
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Nag-install ang iyong organisasyon ng awtoridad sa certificate sa device na ito. Maaaring subaybayan o baguhin ang iyong ligtas na trapiko sa network."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Nag-install ang iyong organisasyon ng awtoridad sa certificate sa iyong profile sa trabaho. Maaaring subaybayan o baguhin ang iyong ligtas na trapiko sa network."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"May naka-install sa device na ito na isang awtoridad sa certificate. Maaaring subaybayan o baguhin ang iyong ligtas na trapiko sa network."</string>
@@ -920,6 +920,7 @@
<string name="pip_pause" msgid="1139598607050555845">"I-pause"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"Lumaktaw sa susunod"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"Lumaktaw sa nakaraan"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"I-resize"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"Na-off ang telepono dahil sa init"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"Maayos na ngayong gumagana ang iyong telepono"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Napakainit ng telepono, kaya nag-off ito para lumamig. Maayos na itong gumagana.\n\nMaaaring lubos na uminit ang telepono kapag:\n • Gumamit ka ng resource-intensive na app (gaya ng app para sa gaming, video, o navigation)\n • Nag-download o nag-upload ka ng malaking file\n • Ginamit mo ito sa mainit na lugar"</string>
@@ -1015,8 +1016,8 @@
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Naka-standby"</string>
<string name="priority_onboarding_title" msgid="2893070698479227616">"Ginawang priyoridad ang pag-uusap"</string>
<string name="priority_onboarding_behavior" msgid="5342816047020432929">"Ang mga priyoridad na pag-uusap ay:"</string>
- <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Ipakita sa itaas ng seksyon ng pag-uusap"</string>
- <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Ipakita ang larawan sa profile sa lock screen"</string>
+ <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Lalabas sa itaas ng seksyon ng pag-uusap"</string>
+ <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Magpapakita ng larawan sa profile sa lock screen"</string>
<string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Ipakitang floating bubble sa ibabaw ng mga app"</string>
<string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Ihinto ang Huwag Istorbohin"</string>
<string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"OK"</string>
@@ -1025,7 +1026,7 @@
<string name="magnification_window_title" msgid="4863914360847258333">"Window ng Pag-magnify"</string>
<string name="magnification_controls_title" msgid="8421106606708891519">"Mga Kontrol sa Pag-magnify ng Window"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"Mga kontrol ng device"</string>
- <string name="quick_controls_subtitle" msgid="1667408093326318053">"Magdagdag ng mga kontrol para sa iyong mga nakakonektang device"</string>
+ <string name="quick_controls_subtitle" msgid="1667408093326318053">"Magdagdag ng kontrol para sa mga nakakonektang device"</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"I-set up ang mga kontrol ng device"</string>
<string name="quick_controls_setup_subtitle" msgid="1681506617879773824">"Pindutin nang matagal ang Power button para ma-access ang iyong mga kontrol"</string>
<string name="controls_providers_title" msgid="6879775889857085056">"Pumili ng app para magdagdag ng mga kontrol"</string>
@@ -1045,7 +1046,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"I-hold at i-drag para baguhin ang pagkakaayos ng mga kontrol"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"Inalis ang lahat ng kontrol"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Hindi na-save ang mga pagbabago"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"Hindi ma-load ang listahan ng lahat ng control."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"Hindi ma-load ang mga kontrol. Tingnan ang app na <xliff:g id="APP">%s</xliff:g> para matiyak na hindi nabago ang mga setting ng app."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"Hindi available ang mga compatible na kontrol"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Iba pa"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"Idagdag sa mga kontrol ng device"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"Idagdag"</string>
@@ -1061,8 +1063,11 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"Kumpirmahin ang pagbabago para sa <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Mag-swipe para tumingin ng higit pa"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Nilo-load ang rekomendasyon"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"Isara ang session ng media na ito"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"Media"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"Itago ang kasalukuyang session."</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Itago"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Ituloy"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"Mga Setting"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Hindi aktibo, tingnan ang app"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Nagka-error, sinusubukan ulit…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Hindi nahanap"</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 6c6b5bf47b3b..4d7970601491 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -454,8 +454,8 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Açmak için tekrar dokunun"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Açmak için yukarı kaydırın"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Tekrar denemek için yukarı kaydırın"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"Bu cihaz kuruluşunuz tarafından yönetiliyor"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"Bu cihaz <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> tarafından yönetilmektedir."</string>
+ <string name="do_disclosure_generic" msgid="4896482821974707167">"Bu cihaz, kuruluşunuza ait"</string>
+ <string name="do_disclosure_with_name" msgid="2091641464065004091">"Bu cihaz <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> adlı kuruluşa ait"</string>
<string name="phone_hint" msgid="6682125338461375925">"Telefon için, simgeden hızlıca kaydırın"</string>
<string name="voice_hint" msgid="7476017460191291417">"Sesli yardım için, simgeden hızlıca kaydırın"</string>
<string name="camera_hint" msgid="4519495795000658637">"Kamera için, simgeden hızlıca kaydırın"</string>
@@ -521,21 +521,21 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"Profil izlenebilir"</string>
<string name="vpn_footer" msgid="3457155078010607471">"Ağ etkinliği izlenebilir"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"Ağ etkinliği izlenebilir"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"Bu cihazı kuruluşunuz yönetiyor ve ağ trafiğini izleyebilir"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>, bu cihazı yönetiyor ve ağ trafiğini izleyebilir"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"Cihaz, kuruluşunuz tarafından yönetiliyor ve <xliff:g id="VPN_APP">%1$s</xliff:g> uygulamasına bağlı"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"Cihaz, <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> tarafından yönetiliyor ve <xliff:g id="VPN_APP">%2$s</xliff:g> uygulamasına bağlı"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"Cihaz, kuruluşunuz tarafından yönetiliyor"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"Cihaz, <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> tarafından yönetiliyor"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"Cihaz, kuruluşunuz tarafından yönetiliyor ve VPN\'lere bağlı"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"Cihaz, <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> tarafından yönetiliyor ve VPN\'lere bağlı"</string>
+ <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Bu cihaz, kuruluşunuza ait olup ağ trafiği kuruluşunuz tarafından izlenebilir"</string>
+ <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Bu cihaz, <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> adlı kuruluşa ait olup ağ trafiği bu kuruluş tarafından izlenebilir"</string>
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Bu cihaz, kuruluşunuza ait olup <xliff:g id="VPN_APP">%1$s</xliff:g> uygulamasına bağlı"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Bu cihaz, <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> kuruluşuna ait olup <xliff:g id="VPN_APP">%2$s</xliff:g> uygulamasına bağlı"</string>
+ <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Bu cihaz, kuruluşunuza ait"</string>
+ <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Bu cihaz <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> adlı kuruluşa ait"</string>
+ <string name="quick_settings_disclosure_management_vpns" msgid="371835422690053154">"Bu cihaz, kuruluşunuza ait olup VPN\'lere bağlı."</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="4046375645500668555">"Bu cihaz <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> kuruluşuna ait olup VPN\'lere bağlı"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Kuruluşunuz, iş profilinizdeki ağ trafiğini izleyebilir"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>, iş profilinizdeki ağ trafiğini izleyebilir"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Ağ trafiği izlenebilir"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"Cihaz VPN\'lere bağlı"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"İş profiliniz <xliff:g id="VPN_APP">%1$s</xliff:g> uygulamasına bağlı"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"Kişisel profil <xliff:g id="VPN_APP">%1$s</xliff:g> uygulamasına bağlı"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"Cihaz <xliff:g id="VPN_APP">%1$s</xliff:g> uygulamasına bağlı"</string>
+ <string name="quick_settings_disclosure_vpns" msgid="7213546797022280246">"Bu cihaz VPN\'lere bağlı"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"İş profiliniz <xliff:g id="VPN_APP">%1$s</xliff:g> uygulamasına bağlı"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Kişisel profiliniz <xliff:g id="VPN_APP">%1$s</xliff:g> uygulamasına bağlı"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Bu cihaz <xliff:g id="VPN_APP">%1$s</xliff:g> uygulamasına bağlı"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Cihaz yönetimi"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Profil izleme"</string>
<string name="monitoring_title" msgid="4063890083735924568">"Ağ izleme"</string>
@@ -545,8 +545,8 @@
<string name="disable_vpn" msgid="482685974985502922">"VPN\'yi devre dışı bırak"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"VPN bağlantısını kes"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"Politikaları Göster"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"Cihazınız <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> tarafından yönetiliyor.\n\nYöneticiniz ayarları, şirket erişimini, uygulamaları, cihazınızla ilişkili verileri ve cihazınızın konum bilgilerini izleyebilir ve yönetebilir.\n\nDaha fazla bilgi için yöneticinize başvurun."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"Cihazınız kuruluşunuz tarafından yönetiliyor.\n\nYöneticiniz ayarları, şirket erişimini, uygulamaları, cihazınızla ilişkili verileri ve cihazınızın konum bilgilerini izleyebilir ve yönetebilir.\n\nDaha fazla bilgi için yöneticinize başvurun."</string>
+ <string name="monitoring_description_named_management" msgid="505833016545056036">"Bu cihaz <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> adlı kuruluşa ait.\n\nBT yöneticiniz cihazınızın ayarlarını, şirket erişimini, uygulamaları, cihazınızla ilişkilendirilen verileri, cihazınızın konum bilgilerini izleyip yönetebilir.\n\nDaha fazla bilgi için BT yöneticinize başvurun."</string>
+ <string name="monitoring_description_management" msgid="4308879039175729014">"Bu cihaz kuruluşunuza ait.\n\nBT yöneticiniz cihazın ayarlarını, şirket erişimini, uygulamaları, cihazınızla ilişkilendirilen verileri, cihazınızın konum bilgilerini izleyip yönetebilir.\n\nDaha fazla bilgi için BT yöneticinize başvurun."</string>
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Kuruluşunuz bu cihaza bir sertifika yetkilisi yükledi. Güvenli ağ trafiğiniz izlenebilir veya değiştirilebilir."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Kuruluşunuz iş profilinize bir sertifika yetkilisi yükledi. Güvenli ağ trafiğiniz izlenebilir veya değiştirilebilir."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Bu cihazda bir sertifika yetkilisi yüklü. Güvenli ağ trafiğiniz izlenebilir veya değiştirilebilir."</string>
@@ -920,6 +920,7 @@
<string name="pip_pause" msgid="1139598607050555845">"Duraklat"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"Sonrakine atla"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"Öncekine atla"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"Yeniden boyutlandır"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"Telefon ısındığından kapatıldı"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"Telefonunuz şu anda normal bir şekilde çalışıyor"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Telefonunuz çok ısındığından soğuması için kapatıldı ve şu anda normal bir şekilde çalışıyor.\n\nTelefon şu koşullarda çok ısınabilir:\n • Yoğun kaynak gerektiren uygulamalar (oyun, video veya gezinme uygulamaları gibi) kullanma\n • Büyük dosyalar indirme veya yükleme\n • Telefonu sıcak yerlerde kullanma"</string>
@@ -1045,7 +1046,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Kontrolleri yeniden düzenlemek için basılı tutup sürükleyin"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"Tüm kontroller kaldırıldı"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Değişiklikler kaydedilmedi"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"Tüm kontrollerin listesi yüklenemedi."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"Kontroller yüklenemedi. Uygulama ayarlarının değişmediğinden emin olmak için <xliff:g id="APP">%s</xliff:g> uygulamasını kontrol edin."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"Uyumlu kontrol bulunamadı"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Diğer"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"Cihaz denetimlerine ekle"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"Ekle"</string>
@@ -1061,13 +1063,16 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"<xliff:g id="DEVICE">%s</xliff:g> için değişikliği onaylayın"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Diğer öğeleri görmek için hızlıca kaydırın"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Öneriler yükleniyor"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"Bu medya oturumunu kapat"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"Medya"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"Mevcut oturumu gizle."</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Gizle"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Devam ettir"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"Ayarlar"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Devre dışı, uygulamaya bakın"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Hata, yeniden deneniyor…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Bulunamadı"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"Kontrol kullanılamıyor"</string>
- <string name="controls_error_removed_message" msgid="2885911717034750542">"<xliff:g id="DEVICE">%1$s</xliff:g> cihazına erişilemedi Kontrolün hâlâ kullanılabilir olduğundan ve uygulama ayarlarının değişmediğinden emin olmak için <xliff:g id="APPLICATION">%2$s</xliff:g> uygulamasını kontrol edin."</string>
+ <string name="controls_error_removed_message" msgid="2885911717034750542">"<xliff:g id="DEVICE">%1$s</xliff:g> cihazına erişilemedi. Kontrolün kullanılabilir olduğundan ve uygulama ayarlarının değişmediğinden emin olmak için <xliff:g id="APPLICATION">%2$s</xliff:g> uygulamasını kontrol edin."</string>
<string name="controls_open_app" msgid="483650971094300141">"Uygulama aç"</string>
<string name="controls_error_generic" msgid="352500456918362905">"Durum yüklenemiyor"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Hata, yeniden deneyin"</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index e192c120922f..7ccd4620857b 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -458,8 +458,10 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Торкніться знову, щоб відкрити"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Проведіть пальцем угору, щоб відкрити"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Проведіть пальцем угору, щоб повторити спробу"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"Цим пристроєм керує адміністратор вашої організації"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"Цим пристроєм керує організація <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
+ <!-- no translation found for do_disclosure_generic (4896482821974707167) -->
+ <skip />
+ <!-- no translation found for do_disclosure_with_name (2091641464065004091) -->
+ <skip />
<string name="phone_hint" msgid="6682125338461375925">"Телефон: проведіть пальцем від значка"</string>
<string name="voice_hint" msgid="7476017460191291417">"Голосові підказки: проведіть пальцем від значка"</string>
<string name="camera_hint" msgid="4519495795000658637">"Камера: проведіть пальцем від значка"</string>
@@ -527,21 +529,33 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"Профіль може відстежуватись"</string>
<string name="vpn_footer" msgid="3457155078010607471">"Дії в мережі можуть відстежуватися"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"Мережа може відстежуватися"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"Адміністратор вашої організації керує цим пристроєм і може відстежувати мережевий трафік"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"Адміністратор організації <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> керує цим пристроєм і може відстежувати мережевий трафік"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"Цим пристроєм керує адміністратор вашої організації. Пристрій під’єднано до додатка <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"Пристроєм керує адміністратор організації <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>. Пристрій під’єднано до додатка <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"Пристроєм керує адміністратор вашої організації"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"Цим пристроєм керує адміністратор організації <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"Пристроєм керує адміністратор вашої організації. Пристрій під’єднано до мереж VPN"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"Цим пристроєм керує адміністратор організації <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>. Пристрій під’єднано до мереж VPN"</string>
+ <!-- no translation found for quick_settings_disclosure_management_monitoring (8231336875820702180) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_monitoring (2831423806103479812) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_named_vpn (6096715329056415588) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (5302786161534380104) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management (5515296598440684962) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management (3476472755775165827) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_vpns (371835422690053154) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_vpns (4046375645500668555) -->
+ <skip />
<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_monitoring" msgid="8548019955631378680">"Мережевий трафік може відстежуватися"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"Пристрої, під’єднані до мереж VPN"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"Робочий профіль під’єднано до додатка <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"Особистий профіль під’єднано до додатка <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"Пристрій під’єднано до додатка <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <!-- no translation found for quick_settings_disclosure_vpns (7213546797022280246) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (8117568745060010789) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (5481763430080807797) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_vpn (2350838218824492465) -->
+ <skip />
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Керування пристроями"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Відстеження профілю"</string>
<string name="monitoring_title" msgid="4063890083735924568">"Відстеження дій у мережі"</string>
@@ -551,8 +565,10 @@
<string name="disable_vpn" msgid="482685974985502922">"Вимкнути VPN"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"Від’єднатися від мережі VPN"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"Переглянути правила"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"Вашим пристроєм керує адміністратор організації \"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>\".\n\nВін може відстежувати та контролювати налаштування, корпоративний доступ, додатки, дані пристрою й інформацію про його місцезнаходження.\n\nЩоб дізнатися більше, зв’яжіться з адміністратором."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"Вашим пристроєм керує адміністратор організації.\n\nВін може відстежувати та контролювати налаштування, корпоративний доступ, додатки, дані пристрою й інформацію про його місцезнаходження.\n\nЩоб дізнатися більше, зв’яжіться з адміністратором."</string>
+ <!-- no translation found for monitoring_description_named_management (505833016545056036) -->
+ <skip />
+ <!-- no translation found for monitoring_description_management (4308879039175729014) -->
+ <skip />
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Адміністратор організації встановив центр сертифікації на цьому пристрої. Захищений мережевий трафік може відстежуватися або змінюватися."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Адміністратор організації встановив центр сертифікації у вашому робочому профілі. Захищений мережевий трафік може відстежуватися або змінюватися."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"На цьому пристрої встановлено центр сертифікації. Захищений мережевий трафік може відстежуватися або змінюватися."</string>
@@ -930,6 +946,7 @@
<string name="pip_pause" msgid="1139598607050555845">"Призупинити"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"Перейти далі"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"Перейти назад"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"Змінити розмір"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"Телефон перегрівся й вимкнувся"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"Зараз телефон працює, як зазвичай"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Телефон перегрівся, тому вимкнувся, щоб охолонути. Зараз він працює, як зазвичай.\n\nТелефон перегрівається, якщо ви:\n • використовуєте ресурсомісткі додатки (ігри, відео, навігація)\n • завантажуєте великі файли на телефон або з нього\n • використовуєте телефон за високої температури"</string>
@@ -1016,7 +1033,7 @@
<string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Не показувати спливаючі чати для розмов"</string>
<string name="bubbles_user_education_title" msgid="5547017089271445797">"Спливаючий чат"</string>
<string name="bubbles_user_education_description" msgid="1160281719576715211">"Нові повідомлення чату з\'являються у вигляді спливаючих значків. Щоб відкрити чат, натисніть його, а щоб перемістити – перетягніть."</string>
- <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Налаштовуйте спливаючі чати будь-коли"</string>
+ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Контроль спливаючих чатів"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"Натисніть \"Налаштувати\", щоб вимкнути спливаючі чати від цього додатка"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string>
<string name="bubbles_app_settings" msgid="5779443644062348657">"Налаштування параметра \"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>\""</string>
@@ -1057,7 +1074,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Щоб змінити порядок елементів керування, перетягуйте їх"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"Усі елементи керування вилучено"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Зміни не збережено"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"Не вдалося завантажити список усіх елементів керування."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"Не вдалося завантажити елементи керування. Перевірте в додатку <xliff:g id="APP">%s</xliff:g>, чи його налаштування не змінились."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"Сумісні елементи керування недоступні"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Інше"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"Додати до елементів керування пристроями"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"Додати"</string>
@@ -1073,8 +1091,15 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"<xliff:g id="DEVICE">%s</xliff:g>: підтвердьте зміну"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Гортайте, щоб переглянути інші"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Завантаження рекомендацій"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"Закрити цей сеанс медіа"</string>
+ <!-- no translation found for controls_media_title (1746947284862928133) -->
+ <skip />
+ <!-- no translation found for controls_media_close_session (3957093425905475065) -->
+ <skip />
+ <!-- no translation found for controls_media_dismiss_button (4485675693008031646) -->
+ <skip />
<string name="controls_media_resume" msgid="1933520684481586053">"Відновити"</string>
+ <!-- no translation found for controls_media_settings_button (5815790345117172504) -->
+ <skip />
<string name="controls_error_timeout" msgid="794197289772728958">"Неактивно, перейдіть у додаток"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Помилка. Повторна спроба…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Не знайдено"</string>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index d382f4237c47..e8857c89d6c3 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -454,8 +454,10 @@
<string name="notification_tap_again" msgid="4477318164947497249">"کھولنے کیلئے دوبارہ تھپتھپائیں"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"کھولنے کے لیے اوپر سوائپ کريں"</string>
<string name="keyguard_retry" msgid="886802522584053523">"دوبارہ کوشش کرنے کے لیے اوپر سوائپ کريں"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"یہ آلہ آپ کی تنظیم کے زیر انتظام ہے"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"یہ آلہ <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> کے زیر انتظام ہے"</string>
+ <!-- no translation found for do_disclosure_generic (4896482821974707167) -->
+ <skip />
+ <!-- no translation found for do_disclosure_with_name (2091641464065004091) -->
+ <skip />
<string name="phone_hint" msgid="6682125338461375925">"فون کیلئے آئیکن سے سوائپ کریں"</string>
<string name="voice_hint" msgid="7476017460191291417">"صوتی معاون کیلئے آئیکن سے سوائپ کریں"</string>
<string name="camera_hint" msgid="4519495795000658637">"کیمرہ کیلئے آئیکن سے سوائپ کریں"</string>
@@ -521,21 +523,33 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"پروفائل کو مانیٹر کیا جا سکتا ہے"</string>
<string name="vpn_footer" msgid="3457155078010607471">"نیٹ ورک کو مانیٹر کیا جا سکتا ہے"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"نیٹ ورک کو شاید مانیٹر کیا جائے"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"آپ کی تنظیم اس آلے کا نظم کرتی ہے اور نیٹ ورک ٹریفک مانیٹر کر سکتی ہے"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> اس آلے کا نظم کرتی ہے اور وہ نیٹ ورک ٹریفک مانیٹر کر سکتی ہے"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"آلہ آپ کی تنظیم کے زیر انتظام ہے اور <xliff:g id="VPN_APP">%1$s</xliff:g> سے منسلک ہے"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"آلہ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> کے زیر انتظام ہے اور <xliff:g id="VPN_APP">%2$s</xliff:g> سے منسلک ہے"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"آلہ آپ کی تنظیم کے زیر انتظام ہے"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"آلہ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> کے زیر انتظام ہے"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"‏آلہ آپ کی تنظیم کے زیر انتظام ہے اور VPNs سے منسلک ہے"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"‏آلہ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> کے زیر انتظام ہے اور VPNs سے منسلک ہے"</string>
+ <!-- no translation found for quick_settings_disclosure_management_monitoring (8231336875820702180) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_monitoring (2831423806103479812) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_named_vpn (6096715329056415588) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (5302786161534380104) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management (5515296598440684962) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management (3476472755775165827) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_vpns (371835422690053154) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_vpns (4046375645500668555) -->
+ <skip />
<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_monitoring" msgid="8548019955631378680">"نیٹ ورک کو مانیٹر کیا جا سکتا ہے"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"‏آلہ VPNs سے منسلک ہے"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"دفتری پروفائل <xliff:g id="VPN_APP">%1$s</xliff:g> سے منسلک ہے"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"ذاتی پروفائل <xliff:g id="VPN_APP">%1$s</xliff:g> سے منسلک ہے"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"آلہ <xliff:g id="VPN_APP">%1$s</xliff:g> سے منسلک ہے"</string>
+ <!-- no translation found for quick_settings_disclosure_vpns (7213546797022280246) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (8117568745060010789) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (5481763430080807797) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_vpn (2350838218824492465) -->
+ <skip />
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"آلے کا نظم و نسق"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"پروفائل کو مانیٹر کرنا"</string>
<string name="monitoring_title" msgid="4063890083735924568">"نیٹ ورک کو مانیٹر کرنا"</string>
@@ -545,8 +559,10 @@
<string name="disable_vpn" msgid="482685974985502922">"‏VPN کو غیر فعال کریں"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"‏VPN کو غیر منسلک کریں"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"پالیسیاں دیکھیں"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"آپ کا آلہ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> کے زیر انتظام ہے۔\n\nآپ کا منتظم ترتیبات، کارپوریٹ رسائی، ایپس، آپ کے آلہ سے وابستہ ڈیٹا اور آپ کے آلہ کے مقام کی معلومات کو مانیٹر اور ان کا نظم کر سکتا ہے۔\n\nمزید معلومات کیلئے اپنے منتظم سے رابطہ کریں۔"</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"آپ کا آلہ آپ کی تنظیم کے زیر انتظام ہے۔\n\nآپ کا منتظم ترتیبات، کارپوریٹ رسائی، ایپس، آپ کے آلہ سے وابستہ ڈیٹا اور آپ کے آلہ کے مقام کی معلومات کو مانیٹر اور ان کا نظم کر سکتا ہے۔\n\nمزید معلومات کیلئے اپنے منتظم سے رابطہ کریں۔"</string>
+ <!-- no translation found for monitoring_description_named_management (505833016545056036) -->
+ <skip />
+ <!-- no translation found for monitoring_description_management (4308879039175729014) -->
+ <skip />
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"آپ کی تنظیم نے اس آلے پر ایک سرٹیفکیٹ کی اتھارٹی کو انسٹال کیا ہے۔ آپ کا محفوظ نیٹ ورک ٹریفک مانیٹر ہو سکتا ہے یا اس میں ترمیم کی جا سکتی ہے۔"</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"آپ کی تنظیم نے آپ کے دفتری پروفائل میں ایک سرٹیفکیٹ کی اتھارٹی کو انسٹال کیا ہے۔ آپ کا محفوظ نیٹ ورک ٹریفک مانیٹر ہو سکتا ہے یا اس میں ترمیم کی جا سکتی ہے۔"</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"ایک سرٹیفکیٹ کی اتھارٹی اس آلہ پر انسٹال ہے۔ آپ کا محفوظ نیٹ ورک ٹریفک مانیٹر ہو سکتا ہے یا اس میں ترمیم کی جا سکتی ہے۔"</string>
@@ -920,6 +936,7 @@
<string name="pip_pause" msgid="1139598607050555845">"موقوف کریں"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"نظرانداز کرکے اگلے پر جائیں"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"نظرانداز کرکے پچھلے پر جائیں"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"سائز تبدیل کریں"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"حرارت کی وجہ سے فون آف ہو گیا"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"آپ کا فون اب حسب معمول کام کر رہا ہے"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"آپ کا فون کافی گرم ہو گيا تھا، اس لئے سرد ہونے کیلئے یہ آف ہو گیا۔ اب آپ کا فون حسب معمول کام کر رہا ہے۔\n\nمندرجہ ذیل چیزیں کرنے پر آپ کا فون کافی گرم ہو سکتا ہے:\n • ماخذ کا زیادہ استعمال کرنے والی ایپس (جیسے کہ گیمنگ، ویڈیو، یا نیویگیشن ایپس) کا استعمال کرنا\n • بڑی فائلز ڈاؤن لوڈ یا اپ لوڈ کرنا\n • اعلی درجہ حرارت میں فون کا استعمال کرنا"</string>
@@ -1003,7 +1020,7 @@
<string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"نیچے بائیں جانب لے جائیں"</string>
<string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"نیچے دائیں جانب لے جائیں"</string>
<string name="bubble_dismiss_text" msgid="1314082410868930066">"بلبلہ برخاست کریں"</string>
- <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"بلبلہ گفتگو نہ کریں"</string>
+ <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"گفتگو بلبلہ نہ کریں"</string>
<string name="bubbles_user_education_title" msgid="5547017089271445797">"بلبلے کے ذریعے چیٹ کریں"</string>
<string name="bubbles_user_education_description" msgid="1160281719576715211">"نئی گفتگوئیں فلوٹنگ آئیکن یا بلبلے کے طور پر ظاہر ہوں گی۔ بلبلہ کھولنے کے لیے تھپتھپائیں۔ اسے منتقل کرنے کے لیے گھسیٹیں۔"</string>
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"کسی بھی وقت بلبلے کو کنٹرول کریں"</string>
@@ -1014,9 +1031,9 @@
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"سسٹم نیویگیشن اپ ڈیٹ کرنے کے لیے ترتیبات پر جائیں"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"اسٹینڈ بائی"</string>
<string name="priority_onboarding_title" msgid="2893070698479227616">"گفتگو کو ترجیح پر سیٹ کیا گیا"</string>
- <string name="priority_onboarding_behavior" msgid="5342816047020432929">"ترجیحی گفتگوئیں یہ ہوگی:"</string>
- <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"گفتگو کے سیکشن میں سب سے اوپر دکھائیں"</string>
- <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"مقفل سکرین پر پروفائل کی تصویر دکھائیں"</string>
+ <string name="priority_onboarding_behavior" msgid="5342816047020432929">"ترجیحی گفتگوئیں:"</string>
+ <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"گفتگو سیکشن میں سب سے اوپر نظر آئیں گی"</string>
+ <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"مقفل سکرین پر پروفائل کی تصویر دکھائیں گی"</string>
<string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"ایپس کے سب سے اوپر فلوٹنگ بلبلہ کے طور پر ظاہر ہوں"</string>
<string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"ڈسٹرب نہ کریں میں مداخلت کریں"</string>
<string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"سمجھ آ گئی"</string>
@@ -1045,7 +1062,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"کنٹرولز کو دوبارہ ترتیب دینے کے ليے پکڑیں اور گھسیٹیں"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"سبھی کنٹرولز ہٹا دیے گئے"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"تبدیلیاں محفوظ نہیں ہوئیں"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"تمام کنٹرولز کی فہرست لوڈ نہیں کی جا سکی۔"</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"کنٹرولز کو لوڈ نہیں کیا جا سکا۔ یہ یقینی بنانے کے لیے <xliff:g id="APP">%s</xliff:g> ایپ کو چیک کریں کہ ایپ کی ترتیبات تبدیل نہیں ہوئی ہیں۔"</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"موافق کنٹرولز دستیاب نہیں ہیں"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"دیگر"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"آلہ کے کنٹرولز میں شامل کریں"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"شامل کریں"</string>
@@ -1061,13 +1079,16 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"<xliff:g id="DEVICE">%s</xliff:g> کی تبدیلی کی توثیق کریں"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"مزید دیکھنے کیلئے سوائپ کریں"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"تجاویز لوڈ ہو رہی ہیں"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"اس میڈیا سیشن کو بند کریں"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"میڈیا"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"موجودہ سیشن چھپائیں۔"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"چھپائیں"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"دوبارہ شروع کریں"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"ترتیبات"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"غیر فعال، ایپ چیک کریں"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"خرابی، دوبارہ کوشش کی جا رہی ہے…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"نہیں ملا"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"کنٹرول دستیاب نہیں ہے"</string>
- <string name="controls_error_removed_message" msgid="2885911717034750542">"<xliff:g id="DEVICE">%1$s</xliff:g> تک رسائی حاصل نہیں ہو سکی۔ اس بات کو یقینی بنانے کے لیے کہ کنٹرول ابھی بھی دستیاب ہے اور ایپ کی ترتیبات تبدیل نہیں ہوئی، تو <xliff:g id="APPLICATION">%2$s</xliff:g> ایپ چیک کریں۔"</string>
+ <string name="controls_error_removed_message" msgid="2885911717034750542">"‫<xliff:g id="DEVICE">%1$s</xliff:g> تک رسائی حاصل نہیں ہو سکی۔ اس بات کو یقینی بنانے کے لیے کہ کنٹرول ابھی بھی دستیاب ہے اور ایپ کی ترتیبات تبدیل نہیں ہوئی، تو <xliff:g id="APPLICATION">%2$s</xliff:g> ایپ چیک کریں۔"</string>
<string name="controls_open_app" msgid="483650971094300141">"ایپ کھولیں"</string>
<string name="controls_error_generic" msgid="352500456918362905">"صورتحال لوڈ نہیں ہو سکتی"</string>
<string name="controls_error_failed" msgid="960228639198558525">"خرابی، دوبارہ کوشش کریں"</string>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 3099270c0d80..bd7fb7d18f5e 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -454,8 +454,8 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Ochish uchun yana bosing"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Ochish uchun tepaga suring"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Qayta urinish uchun tepaga suring"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"Bu – tashkilotingiz tomonidan boshqariladigan qurilma"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"Bu – <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> tomonidan boshqariladigan qurilma"</string>
+ <string name="do_disclosure_generic" msgid="4896482821974707167">"Bu qurilma tashkilotingizga tegishli"</string>
+ <string name="do_disclosure_with_name" msgid="2091641464065004091">"Bu qurilma <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> tashkilotiga tegishli"</string>
<string name="phone_hint" msgid="6682125338461375925">"Telefonni ochish uchun suring"</string>
<string name="voice_hint" msgid="7476017460191291417">"Ovozli yordam: belgidan boshlab suring"</string>
<string name="camera_hint" msgid="4519495795000658637">"Kamerani ochish uchun suring"</string>
@@ -521,21 +521,21 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"Profil kuzatilishi mumkin"</string>
<string name="vpn_footer" msgid="3457155078010607471">"Tarmoqni kuzatish mumkin"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"Tarmoq kuzatilishi mumkin"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"Tashkilotingiz bu qurilmani boshqaradi va tarmoq trafigini nazorat qilishi mumkin"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> bu qurilmani boshqaradi va tarmoq trafigini nazorat qilishi mumkin"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"Qurilma tashkilotingiz tomonidan boshqariladi va unda <xliff:g id="VPN_APP">%1$s</xliff:g> ilovasi ishga tushirilgan"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"Qurilma <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> tomonidan boshqariladi va unda <xliff:g id="VPN_APP">%2$s</xliff:g> ilovasi ishga tushirilgan"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"Qurilma tashkilotingiz tomonidan boshqariladi"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"Qurilma <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> tomonidan boshqariladi"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"Qurilma tashkilotingiz tomonidan boshqariladi va u VPN tarmoqlarga ulangan"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"Qurilma <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> tomonidan boshqariladi va VPN tarmoqlarga ulangan"</string>
+ <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Bu qurilma tashkilotingizga tegishli va tarmoq trafigi tashkilotingiz tomonidan kuzatilishi mumkin"</string>
+ <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Bu qurilma <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> tashkilotiga tegishli va tarmoq trafigi tashkilot tomonidan kuzatilishi mumkin"</string>
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Bu qurilma tashkilotingizga tegishli va <xliff:g id="VPN_APP">%1$s</xliff:g> tarmogʻiga ulangan"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Bu qurilma <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> tashkilotiga tegishli va <xliff:g id="VPN_APP">%2$s</xliff:g> tarmogʻiga ulangan"</string>
+ <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Bu qurilma tashkilotingizga tegishli"</string>
+ <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Bu qurilma <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> tashkilotiga tegishli"</string>
+ <string name="quick_settings_disclosure_management_vpns" msgid="371835422690053154">"Bu qurilma tashkilotingizga tegishli va VPN tarmoqlarga ulangan"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="4046375645500668555">"Bu qurilma <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> tashkilotiga tegishli va VPN tarmoqlarga ulangan"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Tashkilotingiz ishchi profilingizda tarmoq trafigini nazorat qilishi mumkin"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ishchi profilingizda tarmoq trafigini nazorat qilishi mumkin"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Tarmoq kuzatilishi mumkin"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"Qurilma VPN tarmoqlarga ulangan"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"Ishchi profilda <xliff:g id="VPN_APP">%1$s</xliff:g> ilovasi ishga tushirilgan"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"Shaxsiy profilda <xliff:g id="VPN_APP">%1$s</xliff:g> ilovasi ishga tushirilgan"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"Qurilmada <xliff:g id="VPN_APP">%1$s</xliff:g> ilovasi ishga tushirilgan"</string>
+ <string name="quick_settings_disclosure_vpns" msgid="7213546797022280246">"Bu qurilma VPN tarmoqlarga ulangan"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Ish profilingiz <xliff:g id="VPN_APP">%1$s</xliff:g> tarmogʻiga ulangan"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Shaxsiy profilingiz <xliff:g id="VPN_APP">%1$s</xliff:g> tarmogʻiga ulangan"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Bu qurilma <xliff:g id="VPN_APP">%1$s</xliff:g> tarmogʻiga ulangan"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Qurilmalar boshqaruvi"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Profilni kuzatish"</string>
<string name="monitoring_title" msgid="4063890083735924568">"Tarmoqlarni kuzatish"</string>
@@ -545,8 +545,8 @@
<string name="disable_vpn" msgid="482685974985502922">"VPN tarmog‘ini o‘chirish"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"VPN ulanishini uzish"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"Siyosatlarni ko‘rish"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"Qurilmangiz <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> tomonidan boshqariladi.\n\nAdministrator sozlamalar, korporativ kirish huquqi, ilovalar, qurilmangizdagi ma’lumotlar, jumladan, joylashuv ma’lumotlari hamda unga bog‘liq boshqa ma’lumotlarni boshqarishi mumkin.\n\nBatafsil axborot olish uchun administratoringiz bilan bog‘laning."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"Qurilmangiz tashkilot tomonidan boshqariladi.\n\nAdministrator sozlamalar, korporativ kirish huquqi, ilovalar, qurilmangizdagi ma’lumotlar, jumladan, joylashuv ma’lumotlari hamda unga bog‘liq boshqa ma’lumotlarni boshqarishi mumkin.\n\nBatafsil axborot olish uchun administratoringiz bilan bog‘laning."</string>
+ <string name="monitoring_description_named_management" msgid="505833016545056036">"Bu qurilma <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> tashkilotiga tegishli.\n\nAT administratori sozlamalar, korporativ ruxsat, ilovalar, qurilmaning geolokatsiyasi va unga aloqador axborotlarni kuzatishi va boshqarishi mumkin.\n\nBatafsil axborot uchun AT administratoriga murojaat qiling."</string>
+ <string name="monitoring_description_management" msgid="4308879039175729014">"Bu qurilma tashkilotingizga tegishli.\n\nAT administratori sozlamalar, korporativ ruxsat, ilovalar, qurilmaning geolokatsiyasi va unga aloqador axborotlarni kuzatishi va boshqarishi mumkin.\n\nBatafsil axborot uchun AT administratoriga murojaat qiling."</string>
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Tashkilotingiz bu qurilmada CA sertifikatini o‘rnatdi. U himoyalangan tarmoq trafigini nazorat qilishi va o‘zgartirishi mumkin."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Tashkilotingiz ishchi profilingizga CA sertifikatini o‘rnatdi. U himoyalangan tarmoq trafigini nazorat qilishi va o‘zgartirishi mumkin."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Qurilmada CA sertifikati o‘rnatilgan. U himoyalangan tarmoq trafigini nazorat qilishi va o‘zgartirishi mumkin."</string>
@@ -920,6 +920,7 @@
<string name="pip_pause" msgid="1139598607050555845">"Pauza"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"Keyingisiga o‘tish"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"Avvalgisiga qaytish"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"Oʻlchamini oʻzgartirish"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"Qizigani uchun o‘chirildi"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"Telefoningiz hozir normal holatda ishlayapti"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Telefon qizib ketganligi sababli sovitish uchun o‘chirib qo‘yilgan. Endi telefoningiz normal holatda ishlayapti.\n\nTelefon bu hollarda qizib ketishi mumkin:\n • Resurstalab ilovalar ishlatilganda (masalan, o‘yin, video yoki navigatsiya ilovalari)\n • Katta faylni yuklab olishda yoki yuklashda\n • Telefondan yuqori haroratda foydalanganda"</string>
@@ -1002,11 +1003,11 @@
<string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Yuqori oʻngga surish"</string>
<string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Quyi chapga surish"</string>
<string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Quyi oʻngga surish"</string>
- <string name="bubble_dismiss_text" msgid="1314082410868930066">"Pufakni yopish"</string>
+ <string name="bubble_dismiss_text" msgid="1314082410868930066">"Bulutchani yopish"</string>
<string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Suhbatlar bulutchalar shaklida chiqmasin"</string>
<string name="bubbles_user_education_title" msgid="5547017089271445797">"Bulutchalar yordamida subhatlashish"</string>
<string name="bubbles_user_education_description" msgid="1160281719576715211">"Yangi xabarlar qalqib chiquvchi belgilar yoki bulutchalar kabi chiqadi. Xabarni ochish uchun bildirishnoma ustiga bosing. Xabarni qayta joylash uchun bildirishnomani suring."</string>
- <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Bulutcha shaklidagi bildirishnomalarni sozlash"</string>
+ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Bulutchalardagi bildirishnomalar"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"Bu ilova bulutchalarini faolsizlantirish uchun Boshqarish tugmasini bosing"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string>
<string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> sozlamalari"</string>
@@ -1045,7 +1046,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Boshqaruv elementlarini qayta tartiblash uchun ushlab torting"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"Barcha boshqaruv elementlari olib tashlandi"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Oʻzgarishlar saqlanmadi"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"Boshqaruv elementlarining barchasi yuklanmadi."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"Boshqaruvlar yuklanmadi. <xliff:g id="APP">%s</xliff:g> ilovasining sozlamalari oʻzgarmaganini tekshiring."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"Mos boshqaruvlar mavjud emas"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Boshqa"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"Qurilma boshqaruv elementlariga kiritish"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"Kiritish"</string>
@@ -1061,8 +1063,11 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"<xliff:g id="DEVICE">%s</xliff:g> uchun oʻzgarishlarni tasdiqlang"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Batafsil axborot olish uchun suring"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Tavsiyalar yuklanmoqda"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"Bu media seansni yopish"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"Media"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"Joriy seans berkitilsin."</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Berkitish"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Davom etish"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"Sozlamalar"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Nofaol. Ilovani tekshiring"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Xato, qayta urinilmoqda…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Topilmadi"</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index cc6a8fd25826..a3c643e41263 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -454,8 +454,10 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Nhấn lại để mở"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Vuốt lên để mở"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Vuốt lên để thử lại"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"Thiết bị này do tổ chức của bạn quản lý"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"Thiết bị này được <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> quản lý"</string>
+ <!-- no translation found for do_disclosure_generic (4896482821974707167) -->
+ <skip />
+ <!-- no translation found for do_disclosure_with_name (2091641464065004091) -->
+ <skip />
<string name="phone_hint" msgid="6682125338461375925">"Vuốt từ biểu tượng để mở điện thoại"</string>
<string name="voice_hint" msgid="7476017460191291417">"Vuốt từ biểu tượng để mở trợ lý thoại"</string>
<string name="camera_hint" msgid="4519495795000658637">"Vuốt từ biểu tượng để mở máy ảnh"</string>
@@ -521,21 +523,33 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"Hồ sơ có thể được giám sát"</string>
<string name="vpn_footer" msgid="3457155078010607471">"Mạng có thể được giám sát"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"Mạng có thể được giám sát"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"Tổ chức của bạn quản lý thiết bị này và có thể giám sát lưu lượng truy cập mạng"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> quản lý thiết bị này và có thể giám sát lưu lượng truy cập mạng"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"Thiết bị này do tổ chức của bạn quản lý và được kết nối với <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"Thiết bị do <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> quản lý và được kết nối với <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"Thiết bị do tổ chức của bạn quản lý"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"Thiết bị này do <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> quản lý"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"Thiết bị này do tổ chức của bạn quản lý và được kết nối với VPN"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"Thiết bị do <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> quản lý và được kết nối với VPN"</string>
+ <!-- no translation found for quick_settings_disclosure_management_monitoring (8231336875820702180) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_monitoring (2831423806103479812) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_named_vpn (6096715329056415588) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (5302786161534380104) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management (5515296598440684962) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management (3476472755775165827) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_vpns (371835422690053154) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_vpns (4046375645500668555) -->
+ <skip />
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Tổ chức của bạn có thể giám sát lưu lượng truy cập mạng trong hồ sơ công việc của bạn"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> có thể giám sát lưu lượng truy cập mạng trong hồ sơ công việc của bạn"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Mạng có thể được giám sát"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"Thiết bị được kết nối với VPN"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"Hồ sơ công việc được kết nối với <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"Hồ sơ cá nhân được kết nối với <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"Thiết bị được kết nối với <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <!-- no translation found for quick_settings_disclosure_vpns (7213546797022280246) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (8117568745060010789) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (5481763430080807797) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_vpn (2350838218824492465) -->
+ <skip />
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Quản lý thiết bị"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Giám sát hồ sơ"</string>
<string name="monitoring_title" msgid="4063890083735924568">"Giám sát mạng"</string>
@@ -545,8 +559,10 @@
<string name="disable_vpn" msgid="482685974985502922">"Tắt VPN"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"Ngắt kết nối VPN"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"Xem chính sách"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"Thiết bị của bạn do <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> quản lý.\n\nQuản trị viên của bạn có thể giám sát và quản lý cài đặt, quyền truy cập vào dữ liệu công ty, ứng dụng, dữ liệu được liên kết với thiết bị và thông tin vị trí thiết bị của bạn.\n\nĐể biết thêm thông tin, hãy liên hệ với quản trị viên của bạn."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"Thiết bị của bạn do tổ chức của bạn quản lý.\n\nQuản trị viên có thể giám sát và quản lý cài đặt, quyền truy cập vào dữ liệu công ty, ứng dụng, dữ liệu được liên kết với thiết bị và thông tin vị trí thiết bị của bạn.\n\nĐể biết thêm thông tin, hãy liên hệ với quản trị viên của bạn."</string>
+ <!-- no translation found for monitoring_description_named_management (505833016545056036) -->
+ <skip />
+ <!-- no translation found for monitoring_description_management (4308879039175729014) -->
+ <skip />
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Tổ chức của bạn đã cài đặt một tổ chức phát hành chứng chỉ trên thiết bị này. Lưu lượng truy cập mạng bảo mật của bạn có thể được giám sát hoặc sửa đổi."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Tổ chức của bạn đã cài đặt một tổ chức phát hành chứng chỉ trong hồ cơ công việc của bạn. Lưu lượng truy cập mạng bảo mật của bạn có thể được giám sát hoặc sửa đổi."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Một tổ chức phát hành chứng chỉ được cài đặt trên thiết bị này. Lưu lượng truy cập mạng bảo mật của bạn có thể được giám sát hoặc sửa đổi."</string>
@@ -686,7 +702,7 @@
<string name="do_not_silence_block" msgid="4361847809775811849">"Không im lặng hoặc chặn"</string>
<string name="tuner_full_importance_settings" msgid="1388025816553459059">"Điều khiển thông báo nguồn"</string>
<string name="tuner_full_importance_settings_on" msgid="917981436602311547">"Bật"</string>
- <string name="tuner_full_importance_settings_off" msgid="5580102038749680829">"Tắt"</string>
+ <string name="tuner_full_importance_settings_off" msgid="5580102038749680829">"Đang tắt"</string>
<string name="power_notification_controls_description" msgid="1334963837572708952">"Với các kiểm soát thông báo nguồn, bạn có thể đặt cấp độ quan trọng từ 0 đến 5 cho các thông báo của ứng dụng. \n\n"<b>"Cấp 5"</b>" \n- Hiển thị ở đầu danh sách thông báo \n- Cho phép gián đoạn ở chế độ toàn màn hình \n- Luôn xem nhanh \n\n"<b>"Cấp 4"</b>" \n- Ngăn gián đoạn ở chế độ toàn màn hình \n- Luôn xem nhanh \n\n"<b>"Cấp 3"</b>" \n- Ngăn gián đoạn ở chế độ toàn màn hình \n- Không bao giờ xem nhanh \n\n"<b>"Cấp 2"</b>" \n- Ngăn gián đoạn ở chế độ toàn màn hình \n- Không bao giờ xem nhanh \n- Không bao giờ có âm báo và rung \n\n"<b>"Cấp 1"</b>" \n- Ngăn gián đoạn ở chế độ toàn màn hình \n- Không bao giờ xem nhanh \n- Không bao giờ có âm báo và rung \n- Ẩn khỏi màn hình khóa và thanh trạng thái \n- Hiển thị ở cuối danh sách thông báo \n\n"<b>"Cấp 0"</b>" \n- Chặn tất cả các thông báo từ ứng dụng"</string>
<string name="notification_header_default_channel" msgid="225454696914642444">"Thông báo"</string>
<string name="notification_channel_disabled" msgid="928065923928416337">"Bạn sẽ không thấy các thông báo này nữa"</string>
@@ -920,6 +936,7 @@
<string name="pip_pause" msgid="1139598607050555845">"Tạm dừng"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"Chuyển tới mục tiếp theo"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"Chuyển về mục trước"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"Đổi kích thước"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"Điện thoại đã tắt do nhiệt"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"Điện thoại của bạn hiện đang chạy bình thường"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Do quá nóng nên điện thoại đã tắt để hạ nhiệt. Hiện điện thoại của bạn đang chạy bình thường.\n\nĐiện thoại có thể bị quá nóng nếu bạn:\n • Dùng các ứng dụng tốn nhiều tài nguyên (như ứng dụng trò chơi, video hoặc điều hướng)\n • Tải xuống hoặc tải lên tệp có dung lượng lớn\n • Dùng điện thoại ở nhiệt độ cao"</string>
@@ -1006,7 +1023,7 @@
<string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Dừng trò chuyện bằng bong bóng"</string>
<string name="bubbles_user_education_title" msgid="5547017089271445797">"Trò chuyện bằng bong bóng trò chuyện"</string>
<string name="bubbles_user_education_description" msgid="1160281719576715211">"Các cuộc trò chuyện mới sẽ xuất hiện dưới dạng biểu tượng nổi hoặc bong bóng trò chuyện. Nhấn để mở bong bóng trò chuyện. Kéo để di chuyển bong bóng trò chuyện."</string>
- <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Kiểm soát tùy chọn cài đặt bong bóng trò chuyện bất mọi lúc"</string>
+ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Kiểm soát bong bóng bất cứ lúc nào"</string>
<string name="bubbles_user_education_manage" msgid="1391639189507036423">"Nhấn vào nút Quản lý để tắt bong bóng trò chuyện từ ứng dụng này"</string>
<string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string>
<string name="bubbles_app_settings" msgid="5779443644062348657">"Cài đặt <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
@@ -1045,7 +1062,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Giữ và kéo để sắp xếp lại các tùy chọn điều khiển"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"Đã xóa tất cả tùy chọn điều khiển"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Chưa lưu các thay đổi"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"Không thể tải danh sách tất cả tùy chọn điều khiển."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"Không tải được các chức năng điều khiển. Hãy kiểm tra ứng dụng <xliff:g id="APP">%s</xliff:g> để đảm bảo rằng thông tin cài đặt của ứng dụng chưa thay đổi."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"Không có các chức năng điều khiển tương thích"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Khác"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"Thêm vào mục điều khiển thiết bị"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"Thêm"</string>
@@ -1061,8 +1079,11 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"Xác nhận thay đổi <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Vuốt để xem thêm"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Đang tải các đề xuất"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"Đóng phiên đa phương tiện này"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"Nội dung nghe nhìn"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"Ẩn phiên hiện tại."</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ẩn"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Tiếp tục"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"Cài đặt"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Không hoạt động, hãy kiểm tra ứng dụng"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Lỗi, đang thử lại…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Không tìm thấy"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 73fac041f446..24c052312fb7 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -454,8 +454,10 @@
<string name="notification_tap_again" msgid="4477318164947497249">"再次点按即可打开"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"向上滑动即可打开"</string>
<string name="keyguard_retry" msgid="886802522584053523">"向上滑动即可重试"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"此设备由您所属单位管理"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"此设备是由<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>托管"</string>
+ <!-- no translation found for do_disclosure_generic (4896482821974707167) -->
+ <skip />
+ <!-- no translation found for do_disclosure_with_name (2091641464065004091) -->
+ <skip />
<string name="phone_hint" msgid="6682125338461375925">"滑动图标即可拨打电话"</string>
<string name="voice_hint" msgid="7476017460191291417">"滑动图标即可打开语音助理"</string>
<string name="camera_hint" msgid="4519495795000658637">"滑动图标即可打开相机"</string>
@@ -521,21 +523,33 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"资料可能会受到监控"</string>
<string name="vpn_footer" msgid="3457155078010607471">"网络可能会受到监控"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"网络可能会受到监控"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"您所在的单位会管理此设备,且可能会监控网络流量"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"“<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>”会管理此设备,且可能会监控网络流量"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"设备由您所在的单位负责管理,且已连接到“<xliff:g id="VPN_APP">%1$s</xliff:g>”"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"设备由“<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>”负责管理,且已连接到“<xliff:g id="VPN_APP">%2$s</xliff:g>”"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"设备由您所在的单位负责管理"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"设备由“<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>”负责管理"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"设备由您所在的单位负责管理,且已连接到两个 VPN"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"设备由“<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>”负责管理,且已连接到两个 VPN"</string>
+ <!-- no translation found for quick_settings_disclosure_management_monitoring (8231336875820702180) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_monitoring (2831423806103479812) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_named_vpn (6096715329056415588) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (5302786161534380104) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management (5515296598440684962) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management (3476472755775165827) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_vpns (371835422690053154) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_vpns (4046375645500668555) -->
+ <skip />
<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_monitoring" msgid="8548019955631378680">"网络可能会受到监控"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"设备已连接到两个 VPN"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"工作资料已连接到“<xliff:g id="VPN_APP">%1$s</xliff:g>”"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"个人资料已连接到“<xliff:g id="VPN_APP">%1$s</xliff:g>”"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"设备已连接到“<xliff:g id="VPN_APP">%1$s</xliff:g>”"</string>
+ <!-- no translation found for quick_settings_disclosure_vpns (7213546797022280246) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (8117568745060010789) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (5481763430080807797) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_vpn (2350838218824492465) -->
+ <skip />
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"设备管理"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"资料监控"</string>
<string name="monitoring_title" msgid="4063890083735924568">"网络监控"</string>
@@ -545,8 +559,10 @@
<string name="disable_vpn" msgid="482685974985502922">"关闭VPN"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"断开VPN连接"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"查看政策"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"您的设备由“<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>”负责管理。\n\n您的管理员能够监控和管理与您的设备相关的设置、企业权限、应用、数据,以及您设备的位置信息。\n\n要了解详情,请与您的管理员联系。"</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"您的设备由贵单位负责管理。\n\n您的管理员能够监控和管理与您的设备相关的设置、企业权限、应用、数据,以及您设备的位置信息。\n\n要了解详情,请与您的管理员联系。"</string>
+ <!-- no translation found for monitoring_description_named_management (505833016545056036) -->
+ <skip />
+ <!-- no translation found for monitoring_description_management (4308879039175729014) -->
+ <skip />
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"您所在的单位已在此设备上安装证书授权中心。您的安全网络流量可能会受到监控或修改。"</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"您所在的单位已为您的工作资料安装证书授权中心。您的安全网络流量可能会受到监控或修改。"</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"此设备上已安装证书授权中心。您的安全网络流量可能会受到监控或修改。"</string>
@@ -920,6 +936,7 @@
<string name="pip_pause" msgid="1139598607050555845">"暂停"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"跳到下一个"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"跳到上一个"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"调整大小"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"手机因严重发热而自动关机"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"现在,您的手机已恢复正常运行"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"由于发热严重,因此您的手机执行了自动关机以降温。现在,您的手机已恢复正常运行。\n\n以下情况可能会导致您的手机严重发热:\n • 使用占用大量资源的应用(例如游戏、视频或导航应用)\n • 下载或上传大型文件\n • 在高温环境下使用手机"</string>
@@ -1045,7 +1062,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"按住并拖动即可重新排列控件"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"已移除所有控件"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"未保存更改"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"无法加载所有控件的列表。"</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"无法加载控件。请查看<xliff:g id="APP">%s</xliff:g>应用,确保应用设置没有更改。"</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"找不到兼容的控件"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"其他"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"添加到设备控件"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"添加"</string>
@@ -1061,8 +1079,11 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"确认<xliff:g id="DEVICE">%s</xliff:g>的更改"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"滑动可查看更多结构"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"正在加载推荐内容"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"关闭此媒体会话"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"媒体"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"隐藏当前会话。"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"隐藏"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"继续播放"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"设置"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"无效,请检查应用"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"出现错误,正在重试…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"未找到"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 5f5c85fcc8ef..8acba22917c3 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -454,8 +454,10 @@
<string name="notification_tap_again" msgid="4477318164947497249">"再次輕按即可開啟"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"向上滑動即可開啟"</string>
<string name="keyguard_retry" msgid="886802522584053523">"請向上滑動以再試一次"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"此裝置由您的機構管理"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"此裝置由<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>管理"</string>
+ <!-- no translation found for do_disclosure_generic (4896482821974707167) -->
+ <skip />
+ <!-- no translation found for do_disclosure_with_name (2091641464065004091) -->
+ <skip />
<string name="phone_hint" msgid="6682125338461375925">"從圖示滑動即可使用手機功能"</string>
<string name="voice_hint" msgid="7476017460191291417">"從圖示滑動即可使用語音助手"</string>
<string name="camera_hint" msgid="4519495795000658637">"從圖示滑動即可使用相機功能"</string>
@@ -521,21 +523,33 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"個人檔案可能受到監控"</string>
<string name="vpn_footer" msgid="3457155078010607471">"網絡可能會受到監控"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"網絡可能會受到監控"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"您的機構會管理此裝置,並可能會監控網絡流量"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>會管理此裝置,並可能會監控網絡流量"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"裝置由您的機構管理,並已連結至「<xliff:g id="VPN_APP">%1$s</xliff:g>」"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"裝置由<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>管理,並已連結至「<xliff:g id="VPN_APP">%2$s</xliff:g>」"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"裝置由您的機構管理"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"裝置由<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>管理"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"裝置由您的機構管理,並已連結至 VPN"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"裝置由<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>管理,並已連結至 VPN"</string>
+ <!-- no translation found for quick_settings_disclosure_management_monitoring (8231336875820702180) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_monitoring (2831423806103479812) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_named_vpn (6096715329056415588) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (5302786161534380104) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management (5515296598440684962) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management (3476472755775165827) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_vpns (371835422690053154) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_vpns (4046375645500668555) -->
+ <skip />
<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_monitoring" msgid="8548019955631378680">"網絡可能會受到監控"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"裝置已連結至 VPN"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"工作設定檔已連結至「<xliff:g id="VPN_APP">%1$s</xliff:g>」"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"個人設定檔已連結至「<xliff:g id="VPN_APP">%1$s</xliff:g>」"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"裝置已連結至「<xliff:g id="VPN_APP">%1$s</xliff:g>」"</string>
+ <!-- no translation found for quick_settings_disclosure_vpns (7213546797022280246) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (8117568745060010789) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (5481763430080807797) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_vpn (2350838218824492465) -->
+ <skip />
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"裝置管理"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"個人檔案監控"</string>
<string name="monitoring_title" msgid="4063890083735924568">"網絡監控"</string>
@@ -545,8 +559,10 @@
<string name="disable_vpn" msgid="482685974985502922">"停用 VPN"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"中斷 VPN 連線"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"查看政策"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"您的裝置由<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>管理。\n\n您的管理員可以監控和管理與您裝置相關的設定、公司存取權、應用程式、資料和位置。\n\n如需瞭解詳情,請聯絡您的管理員。"</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"您的裝置由您的機構管理。\n\n您的管理員可以監控和管理與您裝置相關的設定、公司存取權、應用程式、資料和位置。\n\n如需瞭解詳情,請聯絡您的管理員。"</string>
+ <!-- no translation found for monitoring_description_named_management (505833016545056036) -->
+ <skip />
+ <!-- no translation found for monitoring_description_management (4308879039175729014) -->
+ <skip />
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"您的機構已在此裝置中安裝憑證授權單位。您的安全網絡流量可能會受監控或修改。"</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"您的機構已在您的工作設定檔中安裝憑證授權單位。您的安全網絡流量可能會受監控或修改。"</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"此裝置已安裝憑證授權單位。您的安全網絡流量可能會受監控或修改。"</string>
@@ -593,12 +609,12 @@
<string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"停用"</string>
<string name="accessibility_output_chooser" msgid="7807898688967194183">"切換輸出裝置"</string>
<string name="screen_pinning_title" msgid="9058007390337841305">"已固定應用程式"</string>
- <string name="screen_pinning_description" msgid="8699395373875667743">"畫面將會繼續顯示,直至您取消固定。按住 [返回] 和 [概覽] 即可取消固定。"</string>
- <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"畫面將會繼續顯示,直至您取消固定為止。按住 [返回] 按鈕和主按鈕即可取消固定。"</string>
- <string name="screen_pinning_description_gestural" msgid="7246323931831232068">"畫面將會繼續顯示,直至您取消固定為止。向上滑動並按住即可取消固定。"</string>
- <string name="screen_pinning_description_accessible" msgid="7386449191953535332">"畫面將會繼續顯示,直至您取消固定。按住 [概覽] 即可取消固定。"</string>
- <string name="screen_pinning_description_recents_invisible_accessible" msgid="2857071808674481986">"畫面將會繼續顯示,直至您取消固定為止。按住主按鈕即可取消固定。"</string>
- <string name="screen_pinning_exposes_personal_data" msgid="8189852022981524789">"該應用程式可存取個人資料 (例如聯絡人和電郵內容)。"</string>
+ <string name="screen_pinning_description" msgid="8699395373875667743">"應用程式將會固定在螢幕上顯示,直至您取消固定為止。按住「返回」和「概覽」按鈕即可取消固定。"</string>
+ <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"應用程式將會固定在螢幕上顯示,直至您取消固定為止。按住「返回」按鈕和主按鈕即可取消固定。"</string>
+ <string name="screen_pinning_description_gestural" msgid="7246323931831232068">"應用程式將會固定在螢幕上顯示,直至您取消固定為止。向上滑動後按住即可取消固定。"</string>
+ <string name="screen_pinning_description_accessible" msgid="7386449191953535332">"應用程式將會固定在螢幕上顯示,直至您取消固定為止。按住「概覽」按鈕即可取消固定。"</string>
+ <string name="screen_pinning_description_recents_invisible_accessible" msgid="2857071808674481986">"應用程式將會固定在螢幕上顯示,直至您取消固定為止。按住主按鈕即可取消固定。"</string>
+ <string name="screen_pinning_exposes_personal_data" msgid="8189852022981524789">"應用程式可能會存取個人資料 (例如通訊錄和電郵內容)。"</string>
<string name="screen_pinning_can_open_other_apps" msgid="7529756813231421455">"固定的應用程式可開啟其他應用程式。"</string>
<string name="screen_pinning_toast" msgid="8177286912533744328">"如要取消固定此應用程式,請按住「返回」按鈕和「概覽」按鈕"</string>
<string name="screen_pinning_toast_recents_invisible" msgid="6850978077443052594">"如要取消固定此應用程式,請按住「返回」按鈕和主按鈕"</string>
@@ -920,6 +936,7 @@
<string name="pip_pause" msgid="1139598607050555845">"暫停"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"跳到下一個"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"跳到上一個"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"調整大小"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"手機因過熱而關上"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"您的手機現已正常運作"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"您的手機之前因過熱而關上降溫。手機現已正常運作。\n\n以下情況可能會導致手機過熱:\n • 使用耗用大量資源的應用程式 (例如遊戲、影片或導航應用程式)\n • 下載或上載大型檔案\n • 在高溫環境下使用手機"</string>
@@ -1002,7 +1019,7 @@
<string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"移去右上角"</string>
<string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"移去左下角"</string>
<string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"移去右下角"</string>
- <string name="bubble_dismiss_text" msgid="1314082410868930066">"關閉對話氣泡"</string>
+ <string name="bubble_dismiss_text" msgid="1314082410868930066">"關閉小視窗氣泡"</string>
<string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"不要透過小視窗顯示對話"</string>
<string name="bubbles_user_education_title" msgid="5547017089271445797">"使用小視窗進行即時通訊"</string>
<string name="bubbles_user_education_description" msgid="1160281719576715211">"新對話會以浮動圖示 (小視窗) 顯示。輕按即可開啟小視窗。拖曳即可移動小視窗。"</string>
@@ -1025,7 +1042,7 @@
<string name="magnification_window_title" msgid="4863914360847258333">"放大視窗"</string>
<string name="magnification_controls_title" msgid="8421106606708891519">"放大視窗控制項"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"裝置控制"</string>
- <string name="quick_controls_subtitle" msgid="1667408093326318053">"為已連接的裝置新增控制項"</string>
+ <string name="quick_controls_subtitle" msgid="1667408093326318053">"為連接的裝置新增控制選項"</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"設定裝置控制"</string>
<string name="quick_controls_setup_subtitle" msgid="1681506617879773824">"按住「開關」按鈕便可存取控制項"</string>
<string name="controls_providers_title" msgid="6879775889857085056">"選擇要新增控制項的應用程式"</string>
@@ -1045,7 +1062,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"按住並拖曳便可重新排列控制項"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"已移除所有控制項"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"未儲存變更"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"無法載入完整控制項清單。"</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"無法載入控制項。請檢查 <xliff:g id="APP">%s</xliff:g> 應用程式,確定應用程式設定並無變更。"</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"沒有可用的兼容控制項"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"其他"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"加到裝置控制"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"新增"</string>
@@ -1061,8 +1079,11 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"確認<xliff:g id="DEVICE">%s</xliff:g>變更"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"滑動以查看更多"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"正在載入建議"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"關閉此媒體版面"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"媒體"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"隱藏目前的工作階段。"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"隱藏"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"繼續播放"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"設定"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"已停用,請檢查應用程式"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"發生錯誤,正在重試…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"找不到"</string>
@@ -1070,7 +1091,7 @@
<string name="controls_error_removed_message" msgid="2885911717034750542">"無法存取 <xliff:g id="DEVICE">%1$s</xliff:g>。請檢查 <xliff:g id="APPLICATION">%2$s</xliff:g> 應用程式,確定控制功能仍可使用,同時應用程式設定並無變更。"</string>
<string name="controls_open_app" msgid="483650971094300141">"開啟應用程式"</string>
<string name="controls_error_generic" msgid="352500456918362905">"無法載入狀態"</string>
- <string name="controls_error_failed" msgid="960228639198558525">"發生錯誤,請再試一次"</string>
+ <string name="controls_error_failed" msgid="960228639198558525">"發生錯誤,請重試"</string>
<string name="controls_in_progress" msgid="4421080500238215939">"進行中"</string>
<string name="controls_added_tooltip" msgid="4842812921719153085">"按住「開關」按鈕以查看新控制項"</string>
<string name="controls_menu_add" msgid="4447246119229920050">"新增控制項"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings_tv.xml b/packages/SystemUI/res/values-zh-rHK/strings_tv.xml
index 3cf2b43ed1ff..1cd63144b904 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings_tv.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings_tv.xml
@@ -24,5 +24,5 @@
<string name="pip_close" msgid="5775212044472849930">"關閉 PIP"</string>
<string name="pip_fullscreen" msgid="3877997489869475181">"全螢幕"</string>
<string name="mic_active" msgid="5766614241012047024">"麥克風已啟用"</string>
- <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s 曾存取您的麥克風"</string>
+ <string name="app_accessed_mic" msgid="2754428675130470196">"「%1$s」已存取您的麥克風"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 9847871c2efc..f74e9de52758 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -454,8 +454,10 @@
<string name="notification_tap_again" msgid="4477318164947497249">"再次輕觸即可開啟"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"向上滑動即可開啟"</string>
<string name="keyguard_retry" msgid="886802522584053523">"向上滑動即可重試"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"這個裝置是由貴機構所管理"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"這個裝置是由 <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> 所管理"</string>
+ <!-- no translation found for do_disclosure_generic (4896482821974707167) -->
+ <skip />
+ <!-- no translation found for do_disclosure_with_name (2091641464065004091) -->
+ <skip />
<string name="phone_hint" msgid="6682125338461375925">"滑動手機圖示即可啟用"</string>
<string name="voice_hint" msgid="7476017460191291417">"滑動語音小幫手圖示即可啟用"</string>
<string name="camera_hint" msgid="4519495795000658637">"滑動相機圖示即可啟用"</string>
@@ -521,21 +523,33 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"設定檔可能會受到監控"</string>
<string name="vpn_footer" msgid="3457155078010607471">"網路可能會受到監控"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"網路可能會受到監控"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"貴機構負責管理這個裝置,且可能會監控網路流量"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"「<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>」負責管理這個裝置,且可能會監控網路流量"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"裝置是由貴機構所管理,並已連結至「<xliff:g id="VPN_APP">%1$s</xliff:g>」"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"裝置是由「<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>」所管理,並已連結至「<xliff:g id="VPN_APP">%2$s</xliff:g>」"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"裝置是由貴機構所管理"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"裝置是由「<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>」所管理"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"裝置是由貴機構所管理,並已連結至兩個 VPN"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"裝置是由「<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>」所管理,並已連結至兩個 VPN"</string>
+ <!-- no translation found for quick_settings_disclosure_management_monitoring (8231336875820702180) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_monitoring (2831423806103479812) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_named_vpn (6096715329056415588) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (5302786161534380104) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management (5515296598440684962) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management (3476472755775165827) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_management_vpns (371835422690053154) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_management_vpns (4046375645500668555) -->
+ <skip />
<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_monitoring" msgid="8548019955631378680">"網路可能會受到監控"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"裝置已連結至兩個 VPN"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"工作資料夾已連結至「<xliff:g id="VPN_APP">%1$s</xliff:g>」"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"個人設定檔已連結至「<xliff:g id="VPN_APP">%1$s</xliff:g>」"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"裝置已連結至「<xliff:g id="VPN_APP">%1$s</xliff:g>」"</string>
+ <!-- no translation found for quick_settings_disclosure_vpns (7213546797022280246) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (8117568745060010789) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (5481763430080807797) -->
+ <skip />
+ <!-- no translation found for quick_settings_disclosure_named_vpn (2350838218824492465) -->
+ <skip />
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"裝置管理"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"設定檔監控"</string>
<string name="monitoring_title" msgid="4063890083735924568">"網路監控"</string>
@@ -545,8 +559,10 @@
<string name="disable_vpn" msgid="482685974985502922">"停用 VPN"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"中斷 VPN 連線"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"查看政策"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"你的裝置是由「<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>」所管理。\n\n你的管理員可以監控及管理與裝置相關聯的設定、公司系統權限、應用程式和資料,以及裝置的位置資訊。\n\n如要瞭解詳情,請與你的管理員聯絡。"</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"你的裝置是由貴機構所管理。\n\n你的管理員可以監控及管理與裝置相關聯的設定、公司系統權限、應用程式和資料,以及裝置的位置資訊。\n\n如要瞭解詳情,請與你的管理員聯絡。"</string>
+ <!-- no translation found for monitoring_description_named_management (505833016545056036) -->
+ <skip />
+ <!-- no translation found for monitoring_description_management (4308879039175729014) -->
+ <skip />
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"貴機構已為這個裝置安裝憑證授權單位憑證。你的安全網路流量可能會受到監控或修改。"</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"貴機構已為你的工作資料夾安裝憑證授權單位憑證。你的安全網路流量可能會受到監控或修改。"</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"這個裝置已安裝憑證授權單位憑證。你的安全網路流量可能會受到監控或修改。"</string>
@@ -920,6 +936,7 @@
<string name="pip_pause" msgid="1139598607050555845">"暫停"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"跳到下一個"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"跳到上一個"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"調整大小"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"手機先前過熱,因此關閉電源"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"手機現在已恢復正常運作"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"手機先前的溫度過高,因此關閉了電源以進行降溫。手機現在已恢復正常運作。\n\n以下情況可能會導致你的手機溫度過高:\n • 使用需要密集處理資料的應用程式 (例如遊戲、影片或導航應用程式)\n • 下載或上傳大型檔案\n • 在高溫環境下使用手機"</string>
@@ -1013,7 +1030,7 @@
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"系統操作機制已更新。如要進行變更,請前往「設定」。"</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"請前往「設定」更新系統操作機制"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"待機"</string>
- <string name="priority_onboarding_title" msgid="2893070698479227616">"將對話設為優先"</string>
+ <string name="priority_onboarding_title" msgid="2893070698479227616">"對話已設為優先"</string>
<string name="priority_onboarding_behavior" msgid="5342816047020432929">"優先對話會:"</string>
<string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"顯示在對話部分的頂端"</string>
<string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"在螢幕鎖定畫面上顯示個人資料相片"</string>
@@ -1045,7 +1062,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"按住並拖曳即可重新排列控制項"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"所有控制項都已移除"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"未儲存變更"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"無法載入完整的控制項清單。"</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"無法載入控制項。請查看「<xliff:g id="APP">%s</xliff:g>」應用程式,確認應用程式設定沒有任何異動。"</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"找不到相容的控制項"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"其他"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"新增至裝置控制"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"新增"</string>
@@ -1061,8 +1079,11 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"確認「<xliff:g id="DEVICE">%s</xliff:g>」的變更"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"滑動即可查看其他結構"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"正在載入建議控制項"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"關閉這個媒體工作階段"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"媒體"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"隱藏目前的工作階段。"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"隱藏"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"繼續播放"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"設定"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"無效,請查看應用程式"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"發生錯誤,正在重試…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"找不到控制項"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 9b76660e6cd3..46b35245221c 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -454,8 +454,8 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Thepha futhi ukuze uvule"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Swayiphela phezulu ukuze uvule"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Swayiphela phezulu ukuze uzame futhi"</string>
- <string name="do_disclosure_generic" msgid="2388094207542706440">"Le divayisi iphethwe inhlangano yakho"</string>
- <string name="do_disclosure_with_name" msgid="9113122674419739611">"Le divayisi iphethwe yi-<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
+ <string name="do_disclosure_generic" msgid="4896482821974707167">"Le divayisi eyenhlangano yakho"</string>
+ <string name="do_disclosure_with_name" msgid="2091641464065004091">"Le divayisi ngeye-<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="6682125338461375925">"Swayiphela ifoni kusukela kusithonjana"</string>
<string name="voice_hint" msgid="7476017460191291417">"Swayiphela isilekeleli sezwi kusukela kusithonjana"</string>
<string name="camera_hint" msgid="4519495795000658637">"Swayiphela ikhamela kusukela kusithonjana"</string>
@@ -521,21 +521,21 @@
<string name="profile_owned_footer" msgid="2756770645766113964">"Iphrofayela ingaqashwa"</string>
<string name="vpn_footer" msgid="3457155078010607471">"Inethiwekhi kungenzeka iqashiwe"</string>
<string name="branded_vpn_footer" msgid="816930186313188514">"Inethiwekhi kungenzeka iqashiwe"</string>
- <string name="quick_settings_disclosure_management_monitoring" msgid="7453097432200441126">"Inhlangano yakho iphethe le divayisi futhi ingaqapha ithrafikhi yenethiwekhi"</string>
- <string name="quick_settings_disclosure_named_management_monitoring" msgid="8460849665162741948">"I-<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> iphethe le divayisi futhi ingahlola ithrafikhi yenethiwekhi"</string>
- <string name="quick_settings_disclosure_management_named_vpn" msgid="218693044433431656">"Idivayisi iphethwe inhlangano yakho futhi ixhumeke ku-<xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5228196397615456474">"Idivayisi iphethwe i-<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> futhi ixhumeke ku-<xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management" msgid="5778936163447003324">"Idivayisi iphethwe inhlangano yakho"</string>
- <string name="quick_settings_disclosure_named_management" msgid="586473803771171610">"Idivayisi iphethwe i-<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="3447553497516286109">"Idivayisi iphethwe inhlangano yakho futhi ixhumeke kuma-VPN"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="4066586579688193212">"Idivayisi iphethwe i-<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> futhi ixhumeke kuma-VPN"</string>
+ <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Inhlangano yakho ingumnikazi wale divayisi futhi ingaqapha ithrafikhi yenethiwekhi"</string>
+ <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"I-<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ingumnikazi wale divayisi futhi ingaqapha ithrafikhi yenethiwekhi"</string>
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Le divayisi ngeyenhlangano yakho futhi ixhunywe ku-<xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="5302786161534380104">"Le divayisi ngeye-<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> futhi ixhunywe ku-<xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Le divayisi eyenhlangano yakho"</string>
+ <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Le divayisi ngeye-<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management_vpns" msgid="371835422690053154">"Le divayisi ngeyenhlangano yakho futhi ixhunywe kuma-VPN"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="4046375645500668555">"Le divayisi ngeye-<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> futhi ixhunywe kuma-VPN"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Inhlangano yakho ingaqapha ithrafikhi yenethiwekhi kuphrofayela yakho yomsebenzi"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"I-<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ingaqaphela ithrafikhi yenethiwekhi kuphrofayela yakho yomsebenzi"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Inethiwekhi kungenzeka iqashiwe"</string>
- <string name="quick_settings_disclosure_vpns" msgid="2890510056934492407">"Idivayisi ixhumeke kuma-VPN"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="5149334449426566152">"Iphrofayela yomsebenzi ixhumeke ku-<xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4201831495800021670">"Iphrofayela yomuntu siqu ixhumeke ku-<xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="5069088739435424666">"Idivayisi ixhumeke ku-<xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_vpns" msgid="7213546797022280246">"Le divayisi ixhunywe kuma-VPN"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Iphrofayela yakho yomsebenzi ixhunywe ku-<xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="5481763430080807797">"Iphrofayela yakho yomuntu ixhunywe ku-<xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="2350838218824492465">"Le divayisi ixhunywe ku-<xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Ukuphathwa kwedivayisi"</string>
<string name="monitoring_title_profile_owned" msgid="6301118649405449568">"Ukuqapha iphrofayela"</string>
<string name="monitoring_title" msgid="4063890083735924568">"Ukuqashwa kwenethiwekhi"</string>
@@ -545,8 +545,8 @@
<string name="disable_vpn" msgid="482685974985502922">"Khubaza i-VPN"</string>
<string name="disconnect_vpn" msgid="26286850045344557">"Nqamula i-VPN"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"Buka izinqubomgomo"</string>
- <string name="monitoring_description_named_management" msgid="7424612629468754552">"Idivayisi yakho iphethwe yi-<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nUmlawuli wakho angaqaphela aphinde aphathe izilungiselelo, ukufinyelela kwezinkampani, izinhlelo zokusebenza, idatha ehlotshaniswa nedivayisi yakho, kanye nolwazi lwendawo yedivayisi yakho.\n\nUkuze uthole olunye ulwazi, xhumana nomlawuli wakho."</string>
- <string name="monitoring_description_management" msgid="8081910434889677718">"Idivayisi yakho iphethwe inhlangano yakho.\n\nUmlawuli wakho angaqapha aphinde aphathe izilungiselelo, ukufinyelela kwezinkampani, izinhlelo zokusebenza, idatha ehlotshaniswa nedivayisi yakho, kanye nolwazi lwendawo yedivayisi yakho.\n\nUkuze uthole olunye ulwazi, xhumana nomlawuli wakho."</string>
+ <string name="monitoring_description_named_management" msgid="505833016545056036">"Le divayisi ngeye-<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nYUmphathi wakho we-IT angakwazi ukugada nokulawula amasethingi, ukufinyelela kwenhlangano, izinhlelo zokusebenza, idatha ehlobene nedivayisi yakho, nolwazi lwendawo yedivayisi yakho.\n\nUkuze uthole ulwazi olwengeziwe, xhumana nomphathi wakho we-IT."</string>
+ <string name="monitoring_description_management" msgid="4308879039175729014">"Le divayisi ngeyenhlangano.\n\nUmphathi wakho we-IT angakwazi ukugada nokulawula amasethingi, ukufinyelela kwenhlangano, izinhlelo zokusebenza, idatha ehlobene nedivayisi yakho, nolwazi lwendawo yedivayisi yakho.\n\nUkuze uthole ulwazi olwengeziwe, xhumana nomphathi wakho we-IT."</string>
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Inhlangano yakho ifake ukugunyazwa kwesitifiketi kule divayisi. Ithrafikhi yenethiwekhi yakho evikelekile kungenzeka iqashelwe noma ilungiswe."</string>
<string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Inhlangano yakho ifake ukugunyaza kwesitifiketi kuphrofayela yakho yomsebenzi. Ithrafikhi yenethiwekhi yakho evikelekile ingaqashwa noma ilungiswe."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Ukugunyaza kwesitifiketi kufakwe kule divayisi. Ithrafikhi yenethiwekhi yakho evikelekile ingaqashelwa noma ilungiswe."</string>
@@ -920,6 +920,7 @@
<string name="pip_pause" msgid="1139598607050555845">"Misa isikhashana"</string>
<string name="pip_skip_to_next" msgid="3864212650579956062">"Yeqela kokulandelayo"</string>
<string name="pip_skip_to_prev" msgid="3742589641443049237">"Yeqela kokwangaphambilini"</string>
+ <string name="accessibility_action_pip_resize" msgid="8237306972921160456">"Shintsha usayizi"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"Ifoni ivaliwe ngenxa yokushisa"</string>
<string name="thermal_shutdown_message" msgid="7432744214105003895">"Ifoni yakho manje isebenza kahle"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Ifoni yakho ibishisa kakhulu, ngakho-ke yacisha ukuze iphole. Ifoni yakho manje isebenza ngokuvamile.\n\nIfoni yakho ingashisa kakhulu uma:\n • Usebenzisa izinhlelo zokusebenza ezinkulu (njegegeyimu, ividiyo, noma izinhlelo zokusebenza zokuzula)\n • Landa noma layisha amafayela amakhulu\n • Sebenzisa ifoni yakho kumathempelesha aphezulu"</string>
@@ -1045,7 +1046,8 @@
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Bamba futhi uhudule ukuze uphinde ulungise izilawuli"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"Zonke izilawuli zisusiwe"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Izinguquko azilondolozwanga"</string>
- <string name="controls_favorite_load_error" msgid="2533215155804455348">"Uhlu lwazo zonke izilawuli alilayishekanga."</string>
+ <string name="controls_favorite_load_error" msgid="5126216176144877419">"Izilawuli azikwazanga ukulayishwa. Hlola uhlelo lokusebenza le-<xliff:g id="APP">%s</xliff:g> ukuqinisekisa ukuthi amasethingi wohlelo lokusebenza awashintshile."</string>
+ <string name="controls_favorite_load_none" msgid="7687593026725357775">"Izilawuli ezihambelanayo azitholakali"</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Okunye"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"Engeza kuzilawuli zezinsiza"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"Engeza"</string>
@@ -1061,8 +1063,11 @@
<string name="controls_confirmation_message" msgid="7744104992609594859">"Qinisekisa ushintsho lwe-<xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Swayipha ukuze ubone okuningi"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Ilayisha izincomo"</string>
- <string name="controls_media_close_session" msgid="9023534788828414585">"Vala leseshini yemidiya"</string>
+ <string name="controls_media_title" msgid="1746947284862928133">"Imidiya"</string>
+ <string name="controls_media_close_session" msgid="3957093425905475065">"Fihla iseshini yamanje."</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Fihla"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Qalisa kabusha"</string>
+ <string name="controls_media_settings_button" msgid="5815790345117172504">"Izilungiselelo"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Akusebenzi, hlola uhlelo lokusebenza"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Iphutha, iyazama futhi…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Ayitholakali"</string>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 40a4b5074413..994a18110260 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -245,8 +245,11 @@
<!-- media -->
<color name="media_primary_text">@android:color/white</color>
+ <color name="media_secondary_text">#99ffffff</color> <!-- 60% -->
<color name="media_seekbar_progress">#c0ffffff</color>
<color name="media_disabled">#80ffffff</color>
+ <color name="media_seamless_border">#26ffffff</color> <!-- 15% -->
+ <color name="media_divider">#1d000000</color>
<!-- controls -->
<color name="control_primary_text">#E6FFFFFF</color>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index d176fed57459..29a2ad4cba9f 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -1058,6 +1058,10 @@
<!-- Shift quick access wallet down in Global Actions when Controls are unavailable -->
<dimen name="global_actions_wallet_top_margin">40dp</dimen>
+ <!-- Shutdown and restart actions are larger in power options dialog -->
+ <dimen name="global_actions_power_dialog_item_height">190dp</dimen>
+ <dimen name="global_actions_power_dialog_item_width">255dp</dimen>
+
<!-- The maximum offset in either direction that elements are moved horizontally to prevent
burn-in on AOD. -->
<dimen name="burn_in_prevention_offset_x">8dp</dimen>
@@ -1112,6 +1116,8 @@
<!-- Biometric Dialog values -->
<dimen name="biometric_dialog_biometric_icon_size">64dp</dimen>
+ <dimen name="biometric_dialog_button_negative_max_width">160dp</dimen>
+ <dimen name="biometric_dialog_button_positive_max_width">136dp</dimen>
<dimen name="biometric_dialog_corner_size">4dp</dimen>
<!-- Y translation when showing/dismissing the dialog-->
<dimen name="biometric_dialog_animation_translation_offset">350dp</dimen>
@@ -1263,8 +1269,13 @@
<dimen name="qs_media_panel_outer_padding">16dp</dimen>
<dimen name="qs_media_album_size">52dp</dimen>
<dimen name="qs_seamless_icon_size">20dp</dimen>
+ <dimen name="qs_seamless_fallback_icon_size">20dp</dimen>
+ <dimen name="qs_seamless_fallback_top_margin">18dp</dimen>
+ <dimen name="qs_seamless_fallback_end_margin">16dp</dimen>
<dimen name="qqs_media_spacing">16dp</dimen>
<dimen name="qs_footer_horizontal_margin">22dp</dimen>
+ <dimen name="qs_media_disabled_seekbar_height">1dp</dimen>
+ <dimen name="qs_media_enabled_seekbar_height">3dp</dimen>
<dimen name="magnification_border_size">5dp</dimen>
<dimen name="magnification_frame_move_short">5dp</dimen>
@@ -1325,8 +1336,8 @@
<dimen name="controls_management_editing_list_margin">48dp</dimen>
<dimen name="controls_management_editing_divider_margin">24dp</dimen>
<dimen name="controls_management_apps_extra_side_margin">8dp</dimen>
- <dimen name="controls_management_apps_top_margin"></dimen>
<dimen name="controls_management_zone_top_margin">32dp</dimen>
+ <dimen name="controls_management_status_side_margin">16dp</dimen>
<dimen name="controls_management_page_indicator_height">24dp</dimen>
<dimen name="controls_management_checkbox_size">25dp</dimen>
<dimen name="controls_title_size">24sp</dimen>
diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml
index d47ad7fcdfbd..8212d6159737 100644
--- a/packages/SystemUI/res/values/ids.xml
+++ b/packages/SystemUI/res/values/ids.xml
@@ -174,5 +174,8 @@
<item type="id" name="accessibility_action_controls_move_before" />
<item type="id" name="accessibility_action_controls_move_after" />
+
+ <!-- Accessibility actions for PIP -->
+ <item type="id" name="action_pip_resize" />
</resources>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index f4141e2f2ee8..0e3fa1e48695 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1091,11 +1091,11 @@
<!-- Message shown when face authentication fails and the pin pad is visible. [CHAR LIMIT=60] -->
<string name="keyguard_retry">Swipe up to try again</string>
- <!-- Text on keyguard screen and in Quick Settings footer indicating that the device is enterprise-managed by a Device Owner [CHAR LIMIT=60] -->
- <string name="do_disclosure_generic">This device is managed by your organization</string>
+ <!-- Text on keyguard screen and in Quick Settings footer indicating that the user's device belongs to their organization. [CHAR LIMIT=60] -->
+ <string name="do_disclosure_generic">This device belongs to your organization</string>
- <!-- Text on keyguard screen and in Quick Settings footer indicating that the device is enterprise-managed by a Device Owner [CHAR LIMIT=40] -->
- <string name="do_disclosure_with_name">This device is managed by <xliff:g id="organization_name" example="Foo, Inc.">%s</xliff:g></string>
+ <!-- Text on keyguard screen and in Quick Settings footer indicating that user's device belongs to their organization. [CHAR LIMIT=40] -->
+ <string name="do_disclosure_with_name">This device belongs to <xliff:g id="organization_name" example="Foo, Inc.">%s</xliff:g></string>
<!-- Shows when people have clicked on the phone icon [CHAR LIMIT=60] -->
<string name="phone_hint">Swipe from icon for phone</string>
@@ -1288,29 +1288,29 @@
<!-- Footer vpn present text [CHAR LIMIT=50] -->
<string name="branded_vpn_footer">Network may be monitored</string>
- <!-- Disclosure at the bottom of Quick Settings that indicates that the device has a device owner that can monitor the network traffic [CHAR LIMIT=100] -->
- <string name="quick_settings_disclosure_management_monitoring">Your organization manages this device and may monitor network traffic</string>
+ <!-- Disclosure at the bottom of Quick Settings that indicates that the user's device belongs to their organization, and the organization can monitor network traffic on that device. [CHAR LIMIT=100] -->
+ <string name="quick_settings_disclosure_management_monitoring">Your organization owns this device and may monitor network traffic</string>
- <!-- Disclosure at the bottom of Quick Settings that indicates that the device has a device owner that can monitor the network traffic [CHAR LIMIT=100] -->
- <string name="quick_settings_disclosure_named_management_monitoring"><xliff:g id="organization_name" example="Foo, Inc.">%1$s</xliff:g> manages this device and may monitor network traffic</string>
+ <!-- Disclosure at the bottom of Quick Settings that indicates that the user's device belongs to their organization, and the organization can monitor network traffic on that device. The placeholder is the organization's name. [CHAR LIMIT=100] -->
+ <string name="quick_settings_disclosure_named_management_monitoring"><xliff:g id="organization_name" example="Foo, Inc.">%1$s</xliff:g> owns this device and may monitor network traffic</string>
- <!-- Disclosure at the bottom of Quick Settings that indicates that the device has a device owner and is connected to a VPN [CHAR LIMIT=100] -->
- <string name="quick_settings_disclosure_management_named_vpn">Device is managed by your organization and connected to <xliff:g id="vpn_app" example="Foo VPN App">%1$s</xliff:g></string>
+ <!-- Disclosure at the bottom of Quick Settings that indicates that the user's device belongs to their organization, and the device is connected to a VPN. The placeholder is the VPN name. [CHAR LIMIT=100] -->
+ <string name="quick_settings_disclosure_management_named_vpn">This device belongs to your organization and is connected to <xliff:g id="vpn_app" example="Foo VPN App">%1$s</xliff:g></string>
- <!-- Disclosure at the bottom of Quick Settings that indicates that the device has a device owner and is connected to a VPN [CHAR LIMIT=100] -->
- <string name="quick_settings_disclosure_named_management_named_vpn">Device is managed by <xliff:g id="organization_name" example="Foo, Inc.">%1$s</xliff:g> and connected to <xliff:g id="vpn_app" example="Foo VPN App">%2$s</xliff:g></string>
+ <!-- Disclosure at the bottom of Quick Settings that indicates that the user's device belongs to their organization, and the device is connected to a VPN. The first placeholder is the organization name, and the second placeholder is the VPN name. [CHAR LIMIT=100] -->
+ <string name="quick_settings_disclosure_named_management_named_vpn">This device belongs to <xliff:g id="organization_name" example="Foo, Inc.">%1$s</xliff:g> and is connected to <xliff:g id="vpn_app" example="Foo VPN App">%2$s</xliff:g></string>
- <!-- Disclosure at the bottom of Quick Settings that indicates that the device has a device owner [CHAR LIMIT=100] -->
- <string name="quick_settings_disclosure_management">Device is managed by your organization</string>
+ <!-- Disclosure at the bottom of Quick Settings that indicates that the user's device belongs to their organization. [CHAR LIMIT=100] -->
+ <string name="quick_settings_disclosure_management">This device belongs to your organization</string>
- <!-- Disclosure at the bottom of Quick Settings that indicates that the device has a device owner [CHAR LIMIT=100] -->
- <string name="quick_settings_disclosure_named_management">Device is managed by <xliff:g id="organization_name" example="Foo, Inc.">%1$s</xliff:g></string>
+ <!-- Disclosure at the bottom of Quick Settings that indicates that the user's device belongs to their organization. The placeholder is the organization's name. [CHAR LIMIT=100] -->
+ <string name="quick_settings_disclosure_named_management">This device belongs to <xliff:g id="organization_name" example="Foo, Inc.">%1$s</xliff:g></string>
- <!-- Disclosure at the bottom of Quick Settings that indicates that the device has a device owner and is connected to two VPNs, one in the current user, one in the managed profile [CHAR LIMIT=100] -->
- <string name="quick_settings_disclosure_management_vpns">Device is managed by your organization and connected to VPNs</string>
+ <!-- Disclosure at the bottom of Quick Settings that indicates that the user's device belongs to their organization, and the device is connected to multiple VPNs. [CHAR LIMIT=100] -->
+ <string name="quick_settings_disclosure_management_vpns">This device belongs to your organization and is connected to VPNs</string>
- <!-- Disclosure at the bottom of Quick Settings that indicates that the device has a device owner and is connected to two VPNs, one in the current user, one in the managed profile [CHAR LIMIT=100] -->
- <string name="quick_settings_disclosure_named_management_vpns">Device is managed by <xliff:g id="organization_name" example="Foo, Inc.">%1$s</xliff:g> and connected to VPNs</string>
+ <!-- Disclosure at the bottom of Quick Settings that indicates that the user's device belongs to their organization, and the device is connected to multiple VPNs. The placeholder is the organization's name. [CHAR LIMIT=100] -->
+ <string name="quick_settings_disclosure_named_management_vpns">This device belongs to <xliff:g id="organization_name" example="Foo, Inc.">%1$s</xliff:g> and is connected to VPNs</string>
<!-- Disclosure at the bottom of Quick Settings that indicates that the device has a managed profile which can be monitored by the profile owner [CHAR LIMIT=100] -->
<string name="quick_settings_disclosure_managed_profile_monitoring">Your organization may monitor network traffic in your work profile</string>
@@ -1321,17 +1321,17 @@
<!-- Disclosure at the bottom of Quick Settings that indicates that a certificate authorithy is installed on this device and the traffic might be monitored [CHAR LIMIT=100] -->
<string name="quick_settings_disclosure_monitoring">Network may be monitored</string>
- <!-- Disclosure at the bottom of Quick Settings that indicates that the device is connected to two VPNs, one in the current user, one in the managed profile [CHAR LIMIT=100] -->
- <string name="quick_settings_disclosure_vpns">Device connected to VPNs</string>
+ <!-- Disclosure at the bottom of Quick Settings that indicates that the device is connected to multiple VPNs. [CHAR LIMIT=100] -->
+ <string name="quick_settings_disclosure_vpns">This device is connected to VPNs</string>
- <!-- Disclosure at the bottom of Quick Settings that indicates that the device is connected to a VPN in the work profile [CHAR LIMIT=100] -->
- <string name="quick_settings_disclosure_managed_profile_named_vpn">Work profile connected to <xliff:g id="vpn_app" example="Foo VPN App">%1$s</xliff:g></string>
+ <!-- Disclosure at the bottom of Quick Settings that indicates that the device is connected to a VPN in the work profile. The placeholder is the VPN name. [CHAR LIMIT=100] -->
+ <string name="quick_settings_disclosure_managed_profile_named_vpn">Your work profile is connected to <xliff:g id="vpn_app" example="Foo VPN App">%1$s</xliff:g></string>
- <!-- Disclosure at the bottom of Quick Settings that indicates that the device is connected to a VPN in the personal profile (as opposed to the work profile) [CHAR LIMIT=100] -->
- <string name="quick_settings_disclosure_personal_profile_named_vpn">Personal profile connected to <xliff:g id="vpn_app" example="Foo VPN App">%1$s</xliff:g></string>
+ <!-- Disclosure at the bottom of Quick Settings that indicates that the device is connected to a VPN in the personal profile (instead of the work profile). The placeholder is the VPN name. [CHAR LIMIT=100] -->
+ <string name="quick_settings_disclosure_personal_profile_named_vpn">Your personal profile is connected to <xliff:g id="vpn_app" example="Foo VPN App">%1$s</xliff:g></string>
- <!-- Disclosure at the bottom of Quick Settings that indicates that the device is connected to a VPN [CHAR LIMIT=100] -->
- <string name="quick_settings_disclosure_named_vpn">Device connected to <xliff:g id="vpn_app" example="Foo VPN App">%1$s</xliff:g></string>
+ <!-- Disclosure at the bottom of Quick Settings that indicates that the device is connected to a VPN. The placeholder is the VPN name. [CHAR LIMIT=100] -->
+ <string name="quick_settings_disclosure_named_vpn">This device is connected to <xliff:g id="vpn_app" example="Foo VPN App">%1$s</xliff:g></string>
<!-- Monitoring dialog title for device owned devices [CHAR LIMIT=35] -->
<string name="monitoring_title_device_owned">Device management</string>
@@ -1361,11 +1361,11 @@
<!-- Monitoring dialog label for button opening a page with more information on the admin's abilities [CHAR LIMIT=30] -->
<string name="monitoring_button_view_policies">View Policies</string>
- <!-- Monitoring dialog: Description of the device owner by name. [CHAR LIMIT=NONE]-->
- <string name="monitoring_description_named_management">Your device is managed by <xliff:g id="organization_name" example="Foo, Inc.">%1$s</xliff:g>.\n\nYour admin can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information.\n\nFor more information, contact your admin.</string>
+ <!-- Dialog that a user can access via Quick Settings. The dialog describes what the IT admin can monitor (and the changes they can make) on the user's device. [CHAR LIMIT=NONE]-->
+ <string name="monitoring_description_named_management">This device belongs to <xliff:g id="organization_name" example="Foo, Inc.">%1$s</xliff:g>.\n\nYour IT admin can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information.\n\nFor more information, contact your IT admin.</string>
- <!-- Monitoring dialog: Description of a device owner. [CHAR LIMIT=NONE]-->
- <string name="monitoring_description_management">Your device is managed by your organization.\n\nYour admin can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information.\n\nFor more information, contact your admin.</string>
+ <!-- Dialog that a user can access via Quick Settings. The dialog describes what the IT admin can monitor (and the changes they can make) on the user's device. [CHAR LIMIT=NONE]-->
+ <string name="monitoring_description_management">This device belongs to your organization.\n\nYour IT admin can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information.\n\nFor more information, contact your IT admin.</string>
<!-- Monitoring dialog: Description of a CA Certificate. [CHAR LIMIT=NONE]-->
<string name="monitoring_description_management_ca_certificate">Your organization installed a certificate authority on this device. Your secure network traffic may be monitored or modified.</string>
@@ -2392,6 +2392,9 @@
<!-- Button to skip to the prev media on picture-in-picture (PIP) [CHAR LIMIT=30] -->
<string name="pip_skip_to_prev">Skip to previous</string>
+ <!-- Accessibility action for resizing PIP [CHAR LIMIT=NONE] -->
+ <string name="accessibility_action_pip_resize">Resize</string>
+
<!-- Tuner string -->
<string name="change_theme_reboot" translatable="false">Changing the theme requires a restart.</string>
<!-- Tuner string -->
@@ -2741,8 +2744,10 @@
<!-- Controls management favorites screen, See other apps with changes made [CHAR LIMIT=NONE] -->
<string name="controls_favorite_toast_no_changes">Changes not saved</string>
- <!-- Controls management controls screen error on load message [CHAR LIMIT=60] -->
- <string name="controls_favorite_load_error">The list of all controls could not be loaded.</string>
+ <!-- Controls management controls screen error on load message [CHAR LIMIT=NONE] -->
+ <string name="controls_favorite_load_error">Controls could not be loaded. Check the <xliff:g id="app" example="System UI">%s</xliff:g> app to make sure that the app settings haven\u2019t changed.</string>
+ <!-- Controls management controls screen no controls found on load message [CHAR LIMIT=NONE] -->
+ <string name="controls_favorite_load_none">Compatible controls unavailable</string>
<!-- Controls management controls screen header for Other zone [CHAR LIMIT=60] -->
<string name="controls_favorite_other_zone_header">Other</string>
@@ -2779,10 +2784,16 @@
recommended controls [CHAR_LIMIT=60] -->
<string name="controls_seeding_in_progress">Loading recommendations</string>
- <!-- Close the controls associated with a specific media session [CHAR_LIMIT=NONE] -->
- <string name="controls_media_close_session">Close this media session</string>
+ <!-- Title for media controls [CHAR_LIMIT=50] -->
+ <string name="controls_media_title">Media</string>
+ <!-- Explanation for closing controls associated with a specific media session [CHAR_LIMIT=NONE] -->
+ <string name="controls_media_close_session">Hide the current session.</string>
+ <!-- Label for a button that will hide media controls [CHAR_LIMIT=30] -->
+ <string name="controls_media_dismiss_button">Hide</string>
<!-- Label for button to resume media playback [CHAR_LIMIT=NONE] -->
<string name="controls_media_resume">Resume</string>
+ <!-- Label for button to go to media control settings screen [CHAR_LIMIT=30] -->
+ <string name="controls_media_settings_button">Settings</string>
<!-- Error message indicating that a control timed out while waiting for an update [CHAR_LIMIT=30] -->
<string name="controls_error_timeout">Inactive, check app</string>
diff --git a/packages/SystemUI/res/xml/media_collapsed.xml b/packages/SystemUI/res/xml/media_collapsed.xml
index 57e6f3635785..811e0e351bd3 100644
--- a/packages/SystemUI/res/xml/media_collapsed.xml
+++ b/packages/SystemUI/res/xml/media_collapsed.xml
@@ -36,7 +36,7 @@
android:layout_marginTop="20dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toEndOf="@id/icon"
- app:layout_constraintEnd_toStartOf="@id/media_seamless"
+ app:layout_constraintEnd_toStartOf="@id/media_seamless_barrier"
app:layout_constraintHorizontal_bias="0"
/>
@@ -52,6 +52,18 @@
/>
<Constraint
+ android:id="@+id/media_seamless_fallback"
+ android:layout_width="@dimen/qs_seamless_fallback_icon_size"
+ android:layout_height="@dimen/qs_seamless_fallback_icon_size"
+ android:layout_marginTop="@dimen/qs_seamless_fallback_top_margin"
+ android:layout_marginEnd="@dimen/qs_seamless_fallback_end_margin"
+ android:alpha="0.5"
+ android:visibility="gone"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintTop_toTopOf="parent"
+ />
+
+ <Constraint
android:id="@+id/album_art"
android:layout_width="@dimen/qs_media_album_size"
android:layout_height="@dimen/qs_media_album_size"
@@ -73,7 +85,7 @@
app:layout_constraintTop_toBottomOf="@id/app_name"
app:layout_constraintBottom_toTopOf="@id/header_artist"
app:layout_constraintStart_toEndOf="@id/album_art"
- app:layout_constraintEnd_toStartOf="@id/action0"
+ app:layout_constraintEnd_toStartOf="@id/media_action_barrier"
app:layout_constraintHorizontal_bias="0"/>
<!-- Artist name -->
@@ -85,7 +97,7 @@
android:layout_marginBottom="24dp"
app:layout_constraintTop_toBottomOf="@id/header_title"
app:layout_constraintStart_toStartOf="@id/header_title"
- app:layout_constraintEnd_toStartOf="@id/action0"
+ app:layout_constraintEnd_toStartOf="@id/media_action_barrier"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_bias="0"/>
@@ -116,15 +128,37 @@
/>
<Constraint
+ android:id="@+id/media_action_barrier"
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:orientation="vertical"
+ app:layout_constraintTop_toTopOf="parent"
+ app:barrierDirection="start"
+ app:constraint_referenced_ids="media_action_guidebox,action0,action1,action2,action3,action4"
+ />
+
+ <Constraint
+ android:id="@+id/media_action_guidebox"
+ android:layout_width="0dp"
+ android:layout_height="48dp"
+ android:layout_marginTop="18dp"
+ android:visibility="invisible"
+ app:layout_constraintTop_toBottomOf="@id/app_name"
+ app:layout_constraintStart_toEndOf="@id/header_title"
+ app:layout_constraintEnd_toEndOf="parent"
+ />
+
+ <Constraint
android:id="@+id/action0"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginStart="4dp"
- android:layout_marginTop="16dp"
+ android:layout_marginEnd="4dp"
+ android:layout_marginTop="18dp"
android:visibility="gone"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintTop_toBottomOf="@id/app_name"
- app:layout_constraintLeft_toRightOf="@id/header_title"
+ app:layout_constraintLeft_toLeftOf="@id/media_action_guidebox"
app:layout_constraintRight_toLeftOf="@id/action1"
>
</Constraint>
@@ -176,9 +210,10 @@
android:layout_marginEnd="4dp"
android:visibility="gone"
android:layout_marginTop="18dp"
+ app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintTop_toBottomOf="@id/app_name"
app:layout_constraintLeft_toRightOf="@id/action3"
- app:layout_constraintRight_toRightOf="parent"
+ app:layout_constraintRight_toRightOf="@id/media_action_guidebox"
>
</Constraint>
</ConstraintSet>
diff --git a/packages/SystemUI/res/xml/media_expanded.xml b/packages/SystemUI/res/xml/media_expanded.xml
index 78973f3207d1..8432abcc16cb 100644
--- a/packages/SystemUI/res/xml/media_expanded.xml
+++ b/packages/SystemUI/res/xml/media_expanded.xml
@@ -36,7 +36,7 @@
android:layout_marginTop="20dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toEndOf="@id/icon"
- app:layout_constraintEnd_toStartOf="@id/media_seamless"
+ app:layout_constraintEnd_toStartOf="@id/media_seamless_barrier"
app:layout_constraintHorizontal_bias="0"
/>
@@ -52,6 +52,18 @@
/>
<Constraint
+ android:id="@+id/media_seamless_fallback"
+ android:layout_width="@dimen/qs_seamless_fallback_icon_size"
+ android:layout_height="@dimen/qs_seamless_fallback_icon_size"
+ android:layout_marginTop="@dimen/qs_seamless_fallback_top_margin"
+ android:layout_marginEnd="@dimen/qs_seamless_fallback_end_margin"
+ android:alpha="0.5"
+ android:visibility="gone"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintTop_toTopOf="parent"
+ />
+
+ <Constraint
android:id="@+id/album_art"
android:layout_width="@dimen/qs_media_album_size"
android:layout_height="@dimen/qs_media_album_size"
@@ -170,6 +182,7 @@
android:layout_marginStart="4dp"
android:layout_marginEnd="4dp"
android:layout_marginBottom="@dimen/qs_media_panel_outer_padding"
+ app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintLeft_toRightOf="@id/action3"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="@id/action0"
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/ThumbnailData.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/ThumbnailData.java
index eca6ebf7f8e5..279a200949a5 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/ThumbnailData.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/ThumbnailData.java
@@ -18,12 +18,17 @@ package com.android.systemui.shared.recents.model;
import static android.app.WindowConfiguration.ROTATION_UNDEFINED;
import static android.content.res.Configuration.ORIENTATION_UNDEFINED;
+import static android.graphics.Bitmap.Config.ARGB_8888;
import static com.android.systemui.shared.system.WindowManagerWrapper.WINDOWING_MODE_UNDEFINED;
import android.app.ActivityManager.TaskSnapshot;
import android.graphics.Bitmap;
+import android.graphics.Color;
+import android.graphics.GraphicBuffer;
import android.graphics.Rect;
+import android.hardware.HardwareBuffer;
+import android.util.Log;
/**
* Data for a single thumbnail.
@@ -57,7 +62,15 @@ public class ThumbnailData {
}
public ThumbnailData(TaskSnapshot snapshot) {
- thumbnail = Bitmap.wrapHardwareBuffer(snapshot.getSnapshot(), snapshot.getColorSpace());
+ final GraphicBuffer buffer = snapshot.getSnapshot();
+ if (buffer != null && (buffer.getUsage() & HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE) == 0) {
+ // TODO(b/157562905): Workaround for a crash when we get a snapshot without this state
+ Log.e("ThumbnailData", "Unexpected snapshot without USAGE_GPU_SAMPLED_IMAGE");
+ thumbnail = Bitmap.createBitmap(buffer.getWidth(), buffer.getHeight(), ARGB_8888);
+ thumbnail.eraseColor(Color.BLACK);
+ } else {
+ thumbnail = Bitmap.wrapHardwareBuffer(buffer, snapshot.getColorSpace());
+ }
insets = new Rect(snapshot.getContentInsets());
orientation = snapshot.getOrientation();
rotation = snapshot.getRotation();
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplierCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplierCompat.java
index 31fe22e57084..82e6251a4484 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplierCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplierCompat.java
@@ -115,7 +115,6 @@ public class SyncRtSurfaceTransactionApplierCompat {
t.deferTransactionUntil(surfaceParams.surface, mBarrierSurfaceControl, frame);
surfaceParams.applyTo(t);
}
- t.setEarlyWakeup();
t.apply();
Trace.traceEnd(Trace.TRACE_TAG_VIEW);
Message.obtain(mApplyHandler, MSG_UPDATE_SEQUENCE_NUMBER, toApplySeqNo, 0)
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TransactionCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TransactionCompat.java
index bdb6c063521f..b966f9356849 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TransactionCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TransactionCompat.java
@@ -99,8 +99,8 @@ public class TransactionCompat {
return this;
}
+ @Deprecated
public TransactionCompat setEarlyWakeup() {
- mTransaction.setEarlyWakeup();
return this;
}
@@ -114,7 +114,7 @@ public class TransactionCompat {
t.deferTransactionUntil(surfaceControl, barrier, frameNumber);
}
+ @Deprecated
public static void setEarlyWakeup(Transaction t) {
- t.setEarlyWakeup();
}
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index 1a4dd1e6dd36..1db2e32b8cdb 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -25,12 +25,16 @@ import static com.android.systemui.DejankUtils.whitelistIpcs;
import static java.lang.Integer.max;
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ValueAnimator;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.content.Intent;
import android.content.res.ColorStateList;
+import android.graphics.Insets;
import android.graphics.Rect;
import android.metrics.LogMaker;
import android.os.Handler;
@@ -48,9 +52,13 @@ import android.view.View;
import android.view.ViewConfiguration;
import android.view.WindowInsets;
import android.view.WindowInsetsAnimation;
+import android.view.WindowInsetsAnimationControlListener;
+import android.view.WindowInsetsAnimationController;
import android.view.WindowManager;
import android.widget.FrameLayout;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import androidx.dynamicanimation.animation.DynamicAnimation;
import androidx.dynamicanimation.animation.SpringAnimation;
@@ -64,6 +72,7 @@ import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
import com.android.settingslib.utils.ThreadUtils;
import com.android.systemui.Dependency;
+import com.android.systemui.Interpolators;
import com.android.systemui.R;
import com.android.systemui.SystemUIFactory;
import com.android.systemui.shared.system.SysUiStatsLog;
@@ -100,6 +109,8 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe
private static final UiEventLogger sUiEventLogger = new UiEventLoggerImpl();
+ private static final long IME_DISAPPEAR_DURATION_MS = 125;
+
private KeyguardSecurityModel mSecurityModel;
private LockPatternUtils mLockPatternUtils;
@@ -125,6 +136,7 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe
private int mActivePointerId = -1;
private boolean mIsDragging;
private float mStartTouchY = -1;
+ private boolean mDisappearAnimRunning;
private final WindowInsetsAnimation.Callback mWindowInsetsAnimationCallback =
new WindowInsetsAnimation.Callback(DISPATCH_MODE_STOP) {
@@ -148,22 +160,29 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe
public WindowInsets onProgress(WindowInsets windowInsets,
List<WindowInsetsAnimation> list) {
int translationY = 0;
- for (WindowInsetsAnimation animation : list) {
- if ((animation.getTypeMask() & WindowInsets.Type.ime()) == 0) {
- continue;
+ if (mDisappearAnimRunning) {
+ mSecurityViewFlipper.setTranslationY(
+ mInitialBounds.bottom - mFinalBounds.bottom);
+ } else {
+ for (WindowInsetsAnimation animation : list) {
+ if ((animation.getTypeMask() & WindowInsets.Type.ime()) == 0) {
+ continue;
+ }
+ final int paddingBottom = (int) MathUtils.lerp(
+ mInitialBounds.bottom - mFinalBounds.bottom, 0,
+ animation.getInterpolatedFraction());
+ translationY += paddingBottom;
}
- final int paddingBottom = (int) MathUtils.lerp(
- mInitialBounds.bottom - mFinalBounds.bottom, 0,
- animation.getInterpolatedFraction());
- translationY += paddingBottom;
+ mSecurityViewFlipper.setTranslationY(translationY);
}
- mSecurityViewFlipper.setTranslationY(translationY);
return windowInsets;
}
@Override
public void onEnd(WindowInsetsAnimation animation) {
- mSecurityViewFlipper.setTranslationY(0);
+ if (!mDisappearAnimRunning) {
+ mSecurityViewFlipper.setTranslationY(0);
+ }
}
};
@@ -376,8 +395,51 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe
}
public boolean startDisappearAnimation(Runnable onFinishRunnable) {
+ mDisappearAnimRunning = true;
if (mCurrentSecuritySelection == SecurityMode.Password) {
- mSecurityViewFlipper.getWindowInsetsController().hide(WindowInsets.Type.ime());
+ mSecurityViewFlipper.getWindowInsetsController().controlWindowInsetsAnimation(ime(),
+ IME_DISAPPEAR_DURATION_MS,
+ Interpolators.LINEAR, null, new WindowInsetsAnimationControlListener() {
+
+
+ @Override
+ public void onReady(@NonNull WindowInsetsAnimationController controller,
+ int types) {
+ ValueAnimator anim = ValueAnimator.ofFloat(1f, 0f);
+ anim.addUpdateListener(animation -> {
+ if (controller.isCancelled()) {
+ return;
+ }
+ Insets shownInsets = controller.getShownStateInsets();
+ Insets insets = Insets.add(shownInsets, Insets.of(0, 0, 0,
+ (int) (-shownInsets.bottom / 4
+ * anim.getAnimatedFraction())));
+ controller.setInsetsAndAlpha(insets,
+ (float) animation.getAnimatedValue(),
+ anim.getAnimatedFraction());
+ });
+ anim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ controller.finish(false);
+ }
+ });
+ anim.setDuration(IME_DISAPPEAR_DURATION_MS);
+ anim.setInterpolator(Interpolators.FAST_OUT_LINEAR_IN);
+ anim.start();
+ }
+
+ @Override
+ public void onFinished(
+ @NonNull WindowInsetsAnimationController controller) {
+ mDisappearAnimRunning = false;
+ }
+
+ @Override
+ public void onCancelled(
+ @Nullable WindowInsetsAnimationController controller) {
+ }
+ });
}
if (mCurrentSecuritySelection != SecurityMode.None) {
return getSecurityView(mCurrentSecuritySelection).startDisappearAnimation(
@@ -887,6 +949,7 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe
@Override
public void reset() {
mSecurityViewFlipper.reset();
+ mDisappearAnimRunning = false;
}
@Override
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 7914d864da0f..ee31706c0b94 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -79,7 +79,6 @@ import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
import android.telephony.TelephonyManager;
-import android.util.EventLog;
import android.util.Log;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
@@ -1075,17 +1074,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
!= LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED;
}
- private boolean isUserEncryptedOrLockdown(int userId) {
- // Biometrics should not be started in this case. Think carefully before modifying this
- // method, see b/79776455
- final int strongAuth = mStrongAuthTracker.getStrongAuthForUser(userId);
- final boolean isLockDown =
- containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW)
- || containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN);
- final boolean isEncrypted = containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_BOOT);
- return isLockDown || isEncrypted;
- }
-
private boolean containsFlag(int haystack, int needle) {
return (haystack & needle) != 0;
}
@@ -1915,7 +1903,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
private boolean shouldListenForFingerprint() {
final boolean allowedOnBouncer =
!(mFingerprintLockedOut && mBouncer && mCredentialAttempted);
- final int user = getCurrentUser();
// Only listen if this KeyguardUpdateMonitor belongs to the primary user. There is an
// instance of KeyguardUpdateMonitor for each user but KeyguardUpdateMonitor is user-aware.
@@ -1924,7 +1911,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
shouldListenForFingerprintAssistant() || (mKeyguardOccluded && mIsDreaming))
&& !mSwitchingUser && !isFingerprintDisabled(getCurrentUser())
&& (!mKeyguardGoingAway || !mDeviceInteractive) && mIsPrimaryUser
- && allowedOnBouncer && !isUserEncryptedOrLockdown(user);
+ && allowedOnBouncer;
return shouldListen;
}
@@ -1938,8 +1925,12 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
&& !statusBarShadeLocked;
final int user = getCurrentUser();
final int strongAuth = mStrongAuthTracker.getStrongAuthForUser(user);
- final boolean isTimedOut =
- containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_TIMEOUT);
+ final boolean isLockDown =
+ containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW)
+ || containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN);
+ final boolean isEncryptedOrTimedOut =
+ containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_BOOT)
+ || containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_TIMEOUT);
boolean canBypass = mKeyguardBypassController != null
&& mKeyguardBypassController.canBypass();
@@ -1948,9 +1939,10 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
// TrustAgents or biometrics are keeping the device unlocked.
boolean becauseCannotSkipBouncer = !getUserCanSkipBouncer(user) || canBypass;
- // Scan even when timeout to show a preemptive bouncer when bypassing.
+ // Scan even when encrypted or timeout to show a preemptive bouncer when bypassing.
// Lock-down mode shouldn't scan, since it is more explicit.
- boolean strongAuthAllowsScanning = (!isTimedOut || canBypass && !mBouncer);
+ boolean strongAuthAllowsScanning = (!isEncryptedOrTimedOut || canBypass && !mBouncer)
+ && !isLockDown;
// Only listen if this KeyguardUpdateMonitor belongs to the primary user. There is an
// instance of KeyguardUpdateMonitor for each user but KeyguardUpdateMonitor is user-aware.
@@ -1960,7 +1952,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
&& !mSwitchingUser && !isFaceDisabled(user) && becauseCannotSkipBouncer
&& !mKeyguardGoingAway && mFaceSettingEnabledForUser.get(user) && !mLockIconPressed
&& strongAuthAllowsScanning && mIsPrimaryUser
- && !mSecureCameraLaunched && !isUserEncryptedOrLockdown(user);
+ && !mSecureCameraLaunched;
// Aggregate relevant fields for debug logging.
if (DEBUG_FACE || DEBUG_SPEW) {
@@ -2033,11 +2025,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
if (mFingerprintCancelSignal != null) {
mFingerprintCancelSignal.cancel();
}
-
- if (isUserEncryptedOrLockdown(userId)) {
- // If this happens, shouldListenForFingerprint() is wrong. SafetyNet for b/79776455
- EventLog.writeEvent(0x534e4554, "79776455", "startListeningForFingerprint");
- }
mFingerprintCancelSignal = new CancellationSignal();
mFpm.authenticate(null, mFingerprintCancelSignal, 0, mFingerprintAuthenticationCallback,
null, userId);
@@ -2056,11 +2043,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
if (mFaceCancelSignal != null) {
mFaceCancelSignal.cancel();
}
-
- if (isUserEncryptedOrLockdown(userId)) {
- // If this happens, shouldListenForFace() is wrong. SafetyNet for b/79776455
- EventLog.writeEvent(0x534e4554, "79776455", "startListeningForFace");
- }
mFaceCancelSignal = new CancellationSignal();
mFaceManager.authenticate(null, mFaceCancelSignal, 0,
mFaceAuthenticationCallback, null, userId);
diff --git a/packages/SystemUI/src/com/android/systemui/ForegroundServiceController.java b/packages/SystemUI/src/com/android/systemui/ForegroundServiceController.java
index 82e665bdf5ac..2deeb1230f09 100644
--- a/packages/SystemUI/src/com/android/systemui/ForegroundServiceController.java
+++ b/packages/SystemUI/src/com/android/systemui/ForegroundServiceController.java
@@ -29,6 +29,8 @@ import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.util.Assert;
+import java.util.Set;
+
import javax.inject.Inject;
import javax.inject.Singleton;
@@ -62,7 +64,7 @@ public class ForegroundServiceController {
/**
* @return true if this user has services missing notifications and therefore needs a
- * disclosure notification.
+ * disclosure notification for running a foreground service.
*/
public boolean isDisclosureNeededForUser(int userId) {
synchronized (mMutex) {
@@ -74,26 +76,26 @@ public class ForegroundServiceController {
/**
* @return true if this user/pkg has a missing or custom layout notification and therefore needs
- * a disclosure notification for system alert windows.
+ * a disclosure notification showing the user which appsOps the app is using.
*/
public boolean isSystemAlertWarningNeeded(int userId, String pkg) {
synchronized (mMutex) {
final ForegroundServicesUserState services = mUserServices.get(userId);
if (services == null) return false;
- return services.getStandardLayoutKey(pkg) == null;
+ return services.getStandardLayoutKeys(pkg) == null;
}
}
/**
- * Returns the key of the foreground service from this package using the standard template,
- * if one exists.
+ * Returns the keys for notifications from this package using the standard template,
+ * if they exist.
*/
@Nullable
- public String getStandardLayoutKey(int userId, String pkg) {
+ public ArraySet<String> getStandardLayoutKeys(int userId, String pkg) {
synchronized (mMutex) {
final ForegroundServicesUserState services = mUserServices.get(userId);
if (services == null) return null;
- return services.getStandardLayoutKey(pkg);
+ return services.getStandardLayoutKeys(pkg);
}
}
@@ -140,25 +142,27 @@ public class ForegroundServiceController {
}
// TODO: (b/145659174) remove when moving to NewNotifPipeline. Replaced by
- // ForegroundCoordinator
- // Update appOp if there's an associated pending or visible notification:
- final String foregroundKey = getStandardLayoutKey(userId, packageName);
- if (foregroundKey != null) {
- final NotificationEntry entry = mEntryManager.getPendingOrActiveNotif(foregroundKey);
- if (entry != null
- && uid == entry.getSbn().getUid()
- && packageName.equals(entry.getSbn().getPackageName())) {
- boolean changed;
- synchronized (entry.mActiveAppOps) {
- if (active) {
- changed = entry.mActiveAppOps.add(appOpCode);
- } else {
- changed = entry.mActiveAppOps.remove(appOpCode);
+ // AppOpsCoordinator
+ // Update appOps if there are associated pending or visible notifications
+ final Set<String> notificationKeys = getStandardLayoutKeys(userId, packageName);
+ if (notificationKeys != null) {
+ boolean changed = false;
+ for (String key : notificationKeys) {
+ final NotificationEntry entry = mEntryManager.getPendingOrActiveNotif(key);
+ if (entry != null
+ && uid == entry.getSbn().getUid()
+ && packageName.equals(entry.getSbn().getPackageName())) {
+ synchronized (entry.mActiveAppOps) {
+ if (active) {
+ changed |= entry.mActiveAppOps.add(appOpCode);
+ } else {
+ changed |= entry.mActiveAppOps.remove(appOpCode);
+ }
}
}
- if (changed) {
- mEntryManager.updateNotifications("appOpChanged pkg=" + packageName);
- }
+ }
+ if (changed) {
+ mEntryManager.updateNotifications("appOpChanged pkg=" + packageName);
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/ForegroundServiceNotificationListener.java b/packages/SystemUI/src/com/android/systemui/ForegroundServiceNotificationListener.java
index 650b9a7f9c0c..bb445832da93 100644
--- a/packages/SystemUI/src/com/android/systemui/ForegroundServiceNotificationListener.java
+++ b/packages/SystemUI/src/com/android/systemui/ForegroundServiceNotificationListener.java
@@ -163,31 +163,31 @@ public class ForegroundServiceNotificationListener {
userState.addImportantNotification(sbn.getPackageName(),
sbn.getKey());
}
- final Notification.Builder builder =
- Notification.Builder.recoverBuilder(
- mContext, sbn.getNotification());
- if (builder.usesStandardHeader()) {
- userState.addStandardLayoutNotification(
- sbn.getPackageName(), sbn.getKey());
- }
+ }
+ final Notification.Builder builder =
+ Notification.Builder.recoverBuilder(
+ mContext, sbn.getNotification());
+ if (builder.usesStandardHeader()) {
+ userState.addStandardLayoutNotification(
+ sbn.getPackageName(), sbn.getKey());
}
}
- tagForeground(entry);
+ tagAppOps(entry);
return true;
},
true /* create if not found */);
}
// TODO: (b/145659174) remove when moving to NewNotifPipeline. Replaced by
- // ForegroundCoordinator
- private void tagForeground(NotificationEntry entry) {
+ // AppOpsCoordinator
+ private void tagAppOps(NotificationEntry entry) {
final StatusBarNotification sbn = entry.getSbn();
ArraySet<Integer> activeOps = mForegroundServiceController.getAppOps(
sbn.getUserId(),
sbn.getPackageName());
- if (activeOps != null) {
- synchronized (entry.mActiveAppOps) {
- entry.mActiveAppOps.clear();
+ synchronized (entry.mActiveAppOps) {
+ entry.mActiveAppOps.clear();
+ if (activeOps != null) {
entry.mActiveAppOps.addAll(activeOps);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/ForegroundServicesUserState.java b/packages/SystemUI/src/com/android/systemui/ForegroundServicesUserState.java
index 2ef46dca317a..5c2950f1365d 100644
--- a/packages/SystemUI/src/com/android/systemui/ForegroundServicesUserState.java
+++ b/packages/SystemUI/src/com/android/systemui/ForegroundServicesUserState.java
@@ -30,9 +30,11 @@ public class ForegroundServicesUserState {
private String[] mRunning = null;
private long mServiceStartTime = 0;
- // package -> sufficiently important posted notification keys
+
+ // package -> sufficiently important posted notification keys that signal an app is
+ // running a foreground service
private ArrayMap<String, ArraySet<String>> mImportantNotifications = new ArrayMap<>(1);
- // package -> standard layout posted notification keys
+ // package -> standard layout posted notification keys that can display appOps
private ArrayMap<String, ArraySet<String>> mStandardLayoutNotifications = new ArrayMap<>(1);
// package -> app ops
@@ -110,6 +112,11 @@ public class ForegroundServicesUserState {
return found;
}
+ /**
+ * System disclosures for foreground services are required if an app has a foreground service
+ * running AND the app hasn't posted its own notification signalling it is running a
+ * foreground service
+ */
public boolean isDisclosureNeeded() {
if (mRunning != null
&& System.currentTimeMillis() - mServiceStartTime
@@ -129,12 +136,15 @@ public class ForegroundServicesUserState {
return mAppOps.get(pkg);
}
- public String getStandardLayoutKey(String pkg) {
+ /**
+ * Gets the notifications with standard layouts associated with this package
+ */
+ public ArraySet<String> getStandardLayoutKeys(String pkg) {
final ArraySet<String> set = mStandardLayoutNotifications.get(pkg);
if (set == null || set.size() == 0) {
return null;
}
- return set.valueAt(0);
+ return set;
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistHandleBehaviorController.java b/packages/SystemUI/src/com/android/systemui/assist/AssistHandleBehaviorController.java
index 525e98971266..7ae3e73caa23 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistHandleBehaviorController.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistHandleBehaviorController.java
@@ -164,7 +164,7 @@ public final class AssistHandleBehaviorController implements AssistHandleCallbac
return Long.max(mShowAndGoEndsAt - SystemClock.elapsedRealtime(), 0);
}
- boolean areHandlesShowing() {
+ public boolean areHandlesShowing() {
return mHandlesShowing;
}
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistLogger.kt b/packages/SystemUI/src/com/android/systemui/assist/AssistLogger.kt
new file mode 100644
index 000000000000..08edad3a7f7f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistLogger.kt
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.assist
+
+import android.content.ComponentName
+import android.content.Context
+import android.content.pm.PackageManager
+import android.util.Log
+import com.android.internal.app.AssistUtils
+import com.android.internal.logging.InstanceId
+import com.android.internal.logging.InstanceIdSequence
+import com.android.internal.logging.UiEventLogger
+import com.android.internal.util.FrameworkStatsLog
+import com.android.keyguard.KeyguardUpdateMonitor
+import com.android.systemui.assist.AssistantInvocationEvent.Companion.deviceStateFromLegacyDeviceState
+import com.android.systemui.assist.AssistantInvocationEvent.Companion.eventFromLegacyInvocationType
+import javax.inject.Inject
+import javax.inject.Singleton
+
+/** Class for reporting events related to Assistant sessions. */
+@Singleton
+open class AssistLogger @Inject constructor(
+ protected val context: Context,
+ protected val uiEventLogger: UiEventLogger,
+ private val assistUtils: AssistUtils,
+ private val phoneStateMonitor: PhoneStateMonitor,
+ private val assistHandleBehaviorController: AssistHandleBehaviorController
+) {
+
+ private val instanceIdSequence = InstanceIdSequence(INSTANCE_ID_MAX)
+
+ private var currentInstanceId: InstanceId? = null
+
+ fun reportAssistantInvocationEventFromLegacy(
+ legacyInvocationType: Int,
+ isInvocationComplete: Boolean,
+ assistantComponent: ComponentName? = null,
+ legacyDeviceState: Int? = null
+ ) {
+ val deviceState = if (legacyDeviceState == null) {
+ null
+ } else {
+ deviceStateFromLegacyDeviceState(legacyDeviceState)
+ }
+ reportAssistantInvocationEvent(
+ eventFromLegacyInvocationType(legacyInvocationType, isInvocationComplete),
+ assistantComponent,
+ deviceState)
+ }
+
+ fun reportAssistantInvocationEvent(
+ invocationEvent: UiEventLogger.UiEventEnum,
+ assistantComponent: ComponentName? = null,
+ deviceState: Int? = null
+ ) {
+
+ val assistComponentFinal = assistantComponent ?: getAssistantComponentForCurrentUser()
+
+ val assistantUid = getAssistantUid(assistComponentFinal)
+
+ val deviceStateFinal = deviceState
+ ?: deviceStateFromLegacyDeviceState(phoneStateMonitor.phoneState)
+
+ FrameworkStatsLog.write(
+ FrameworkStatsLog.ASSISTANT_INVOCATION_REPORTED,
+ invocationEvent.id,
+ assistantUid,
+ assistComponentFinal.flattenToString(),
+ getOrCreateInstanceId().id,
+ deviceStateFinal,
+ assistHandleBehaviorController.areHandlesShowing())
+ reportAssistantInvocationExtraData()
+ }
+
+ fun reportAssistantSessionEvent(sessionEvent: UiEventLogger.UiEventEnum) {
+ val assistantComponent = getAssistantComponentForCurrentUser()
+ val assistantUid = getAssistantUid(assistantComponent)
+ uiEventLogger.logWithInstanceId(
+ sessionEvent,
+ assistantUid,
+ assistantComponent.flattenToString(),
+ getOrCreateInstanceId())
+
+ if (SESSION_END_EVENTS.contains(sessionEvent)) {
+ clearInstanceId()
+ }
+ }
+
+ protected open fun reportAssistantInvocationExtraData() {
+ }
+
+ protected fun getOrCreateInstanceId(): InstanceId {
+ val instanceId = currentInstanceId ?: instanceIdSequence.newInstanceId()
+ currentInstanceId = instanceId
+ return instanceId
+ }
+
+ protected fun clearInstanceId() {
+ currentInstanceId = null
+ }
+
+ protected fun getAssistantComponentForCurrentUser(): ComponentName {
+ return assistUtils.getAssistComponentForUser(KeyguardUpdateMonitor.getCurrentUser())
+ }
+
+ protected fun getAssistantUid(assistantComponent: ComponentName): Int {
+ var assistantUid = 0
+ try {
+ assistantUid = context.packageManager.getApplicationInfo(
+ assistantComponent.packageName, /* flags = */
+ 0).uid
+ } catch (e: PackageManager.NameNotFoundException) {
+ Log.e(TAG, "Unable to find Assistant UID", e)
+ }
+ return assistantUid
+ }
+
+ companion object {
+ protected const val TAG = "AssistLogger"
+
+ private const val INSTANCE_ID_MAX = 1 shl 20
+
+ private val SESSION_END_EVENTS =
+ setOf(
+ AssistantSessionEvent.ASSISTANT_SESSION_INVOCATION_CANCELLED,
+ AssistantSessionEvent.ASSISTANT_SESSION_CLOSE)
+ }
+} \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
index a7533adc795e..6d179f27f4fb 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
@@ -40,11 +40,8 @@ import android.widget.ImageView;
import com.android.internal.app.AssistUtils;
import com.android.internal.app.IVoiceInteractionSessionListener;
import com.android.internal.app.IVoiceInteractionSessionShowCallback;
-import com.android.internal.logging.InstanceId;
-import com.android.internal.logging.InstanceIdSequence;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.internal.util.FrameworkStatsLog;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.settingslib.applications.InterestingConfigChanges;
import com.android.systemui.R;
@@ -124,7 +121,6 @@ public class AssistManager {
private static final long TIMEOUT_SERVICE = 2500;
private static final long TIMEOUT_ACTIVITY = 1000;
- private static final int INSTANCE_ID_MAX = 1 << 20;
protected final Context mContext;
private final WindowManager mWindowManager;
@@ -134,8 +130,7 @@ public class AssistManager {
private final AssistHandleBehaviorController mHandleController;
private final UiController mUiController;
protected final Lazy<SysUiState> mSysUiState;
- protected final InstanceIdSequence mInstanceIdSequence =
- new InstanceIdSequence(INSTANCE_ID_MAX);
+ protected final AssistLogger mAssistLogger;
private AssistOrbContainer mView;
private final DeviceProvisionedController mDeviceProvisionedController;
@@ -202,7 +197,9 @@ public class AssistManager {
PhoneStateMonitor phoneStateMonitor,
OverviewProxyService overviewProxyService,
ConfigurationController configurationController,
- Lazy<SysUiState> sysUiState) {
+ Lazy<SysUiState> sysUiState,
+ DefaultUiController defaultUiController,
+ AssistLogger assistLogger) {
mContext = context;
mDeviceProvisionedController = controller;
mCommandQueue = commandQueue;
@@ -211,6 +208,7 @@ public class AssistManager {
mAssistDisclosure = new AssistDisclosure(context, new Handler());
mPhoneStateMonitor = phoneStateMonitor;
mHandleController = handleController;
+ mAssistLogger = assistLogger;
configurationController.addCallback(mConfigurationListener);
@@ -221,7 +219,7 @@ public class AssistManager {
mConfigurationListener.onConfigChanged(context.getResources().getConfiguration());
mShouldEnableOrb = !ActivityManager.isLowRamDeviceStatic();
- mUiController = new DefaultUiController(mContext);
+ mUiController = defaultUiController;
mSysUiState = sysUiState;
@@ -248,6 +246,8 @@ public class AssistManager {
if (VERBOSE) {
Log.v(TAG, "Voice open");
}
+ mAssistLogger.reportAssistantSessionEvent(
+ AssistantSessionEvent.ASSISTANT_SESSION_UPDATE);
}
@Override
@@ -255,6 +255,8 @@ public class AssistManager {
if (VERBOSE) {
Log.v(TAG, "Voice closed");
}
+ mAssistLogger.reportAssistantSessionEvent(
+ AssistantSessionEvent.ASSISTANT_SESSION_CLOSE);
}
@Override
@@ -298,15 +300,19 @@ public class AssistManager {
if (args == null) {
args = new Bundle();
}
- int invocationType = args.getInt(INVOCATION_TYPE_KEY, 0);
- if (invocationType == INVOCATION_TYPE_GESTURE) {
+ int legacyInvocationType = args.getInt(INVOCATION_TYPE_KEY, 0);
+ if (legacyInvocationType == INVOCATION_TYPE_GESTURE) {
mHandleController.onAssistantGesturePerformed();
}
- int phoneState = mPhoneStateMonitor.getPhoneState();
- args.putInt(INVOCATION_PHONE_STATE_KEY, phoneState);
+ int legacyDeviceState = mPhoneStateMonitor.getPhoneState();
+ args.putInt(INVOCATION_PHONE_STATE_KEY, legacyDeviceState);
args.putLong(INVOCATION_TIME_MS_KEY, SystemClock.elapsedRealtime());
- logStartAssist(/* instanceId = */ null, invocationType, phoneState);
- logStartAssistLegacy(invocationType, phoneState);
+ mAssistLogger.reportAssistantInvocationEventFromLegacy(
+ legacyInvocationType,
+ /* isInvocationComplete = */ true,
+ assistComponent,
+ legacyDeviceState);
+ logStartAssistLegacy(legacyInvocationType, legacyDeviceState);
startAssistInternal(args, assistComponent, isService);
}
@@ -506,34 +512,6 @@ public class AssistManager {
return toLoggingSubType(invocationType, mPhoneStateMonitor.getPhoneState());
}
- protected void logStartAssist(
- @Nullable InstanceId instanceId, int invocationType, int deviceState) {
- InstanceId currentInstanceId =
- instanceId == null ? mInstanceIdSequence.newInstanceId() : instanceId;
- ComponentName assistantComponent =
- mAssistUtils.getAssistComponentForUser(UserHandle.USER_CURRENT);
- int assistantUid = 0;
- try {
- assistantUid =
- mContext.getPackageManager()
- .getApplicationInfo(
- assistantComponent.getPackageName(),
- /* flags = */ 0)
- .uid;
- } catch (PackageManager.NameNotFoundException e) {
- Log.e(TAG, "Unable to find Assistant UID", e);
- }
-
- FrameworkStatsLog.write(
- FrameworkStatsLog.ASSISTANT_INVOCATION_REPORTED,
- AssistantInvocationEvent.Companion.eventIdFromLegacyInvocationType(invocationType),
- assistantUid,
- assistantComponent.flattenToString(),
- currentInstanceId.getId(),
- AssistantInvocationEvent.Companion.deviceStateFromLegacyDeviceState(deviceState),
- mHandleController.areHandlesShowing());
- }
-
protected void logStartAssistLegacy(int invocationType, int phoneState) {
MetricsLogger.action(
new LogMaker(MetricsEvent.ASSISTANT)
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistantInvocationEvent.kt b/packages/SystemUI/src/com/android/systemui/assist/AssistantInvocationEvent.kt
index 1de7b8423617..fb5f1d1f725f 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistantInvocationEvent.kt
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistantInvocationEvent.kt
@@ -50,33 +50,55 @@ enum class AssistantInvocationEvent(private val id: Int) : UiEventLogger.UiEvent
ASSISTANT_INVOCATION_HOME_LONG_PRESS(447),
@UiEvent(doc = "Assistant invoked by physical gesture")
- ASSISTANT_INVOCATION_PHYSICAL_GESTURE(448);
+ ASSISTANT_INVOCATION_PHYSICAL_GESTURE(448),
+
+ @UiEvent(doc = "Assistant invocation started by unknown method")
+ ASSISTANT_INVOCATION_START_UNKNOWN(530),
+
+ @UiEvent(doc = "Assistant invocation started by touch gesture")
+ ASSISTANT_INVOCATION_START_TOUCH_GESTURE(531),
+
+ @UiEvent(doc = "Assistant invocation started by physical gesture")
+ ASSISTANT_INVOCATION_START_PHYSICAL_GESTURE(532);
override fun getId(): Int {
return id
}
companion object {
- fun eventIdFromLegacyInvocationType(legacyInvocationType: Int): Int {
- return when (legacyInvocationType) {
- AssistManager.INVOCATION_TYPE_GESTURE ->
- ASSISTANT_INVOCATION_TOUCH_GESTURE
-
- AssistManager.INVOCATION_TYPE_OTHER ->
- ASSISTANT_INVOCATION_PHYSICAL_GESTURE
-
- AssistManager.INVOCATION_TYPE_VOICE ->
- ASSISTANT_INVOCATION_HOTWORD
-
- AssistManager.INVOCATION_TYPE_QUICK_SEARCH_BAR ->
- ASSISTANT_INVOCATION_QUICK_SEARCH_BAR
-
- AssistManager.INVOCATION_HOME_BUTTON_LONG_PRESS ->
- ASSISTANT_INVOCATION_HOME_LONG_PRESS
-
- else ->
- ASSISTANT_INVOCATION_UNKNOWN
- }.id
+ fun eventFromLegacyInvocationType(legacyInvocationType: Int, isInvocationComplete: Boolean)
+ : AssistantInvocationEvent {
+ return if (isInvocationComplete) {
+ when (legacyInvocationType) {
+ AssistManager.INVOCATION_TYPE_GESTURE ->
+ ASSISTANT_INVOCATION_TOUCH_GESTURE
+
+ AssistManager.INVOCATION_TYPE_OTHER ->
+ ASSISTANT_INVOCATION_PHYSICAL_GESTURE
+
+ AssistManager.INVOCATION_TYPE_VOICE ->
+ ASSISTANT_INVOCATION_HOTWORD
+
+ AssistManager.INVOCATION_TYPE_QUICK_SEARCH_BAR ->
+ ASSISTANT_INVOCATION_QUICK_SEARCH_BAR
+
+ AssistManager.INVOCATION_HOME_BUTTON_LONG_PRESS ->
+ ASSISTANT_INVOCATION_HOME_LONG_PRESS
+
+ else ->
+ ASSISTANT_INVOCATION_UNKNOWN
+ }
+ } else {
+ when (legacyInvocationType) {
+ AssistManager.INVOCATION_TYPE_GESTURE ->
+ ASSISTANT_INVOCATION_START_TOUCH_GESTURE
+
+ AssistManager.INVOCATION_TYPE_OTHER ->
+ ASSISTANT_INVOCATION_START_PHYSICAL_GESTURE
+
+ else -> ASSISTANT_INVOCATION_START_UNKNOWN
+ }
+ }
}
fun deviceStateFromLegacyDeviceState(legacyDeviceState: Int): Int {
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistantSessionEvent.kt b/packages/SystemUI/src/com/android/systemui/assist/AssistantSessionEvent.kt
new file mode 100644
index 000000000000..8b953fa46441
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistantSessionEvent.kt
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.assist
+
+import com.android.internal.logging.UiEvent
+import com.android.internal.logging.UiEventLogger
+
+enum class AssistantSessionEvent(private val id: Int) : UiEventLogger.UiEventEnum {
+ @UiEvent(doc = "Unknown assistant session event")
+ ASSISTANT_SESSION_UNKNOWN(523),
+
+ @UiEvent(doc = "Assistant session dismissed due to timeout")
+ ASSISTANT_SESSION_TIMEOUT_DISMISS(524),
+
+ @UiEvent(doc = "User began a gesture for invoking the Assistant")
+ ASSISTANT_SESSION_INVOCATION_START(525),
+
+ @UiEvent(doc =
+ "User stopped a gesture for invoking the Assistant before the gesture was completed")
+ ASSISTANT_SESSION_INVOCATION_CANCELLED(526),
+
+ @UiEvent(doc = "User manually dismissed the Assistant session")
+ ASSISTANT_SESSION_USER_DISMISS(527),
+
+ @UiEvent(doc = "The Assistant session has changed modes")
+ ASSISTANT_SESSION_UPDATE(528),
+
+ @UiEvent(doc = "The Assistant session completed")
+ ASSISTANT_SESSION_CLOSE(529);
+
+ override fun getId(): Int {
+ return id
+ }
+} \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/assist/PhoneStateMonitor.java b/packages/SystemUI/src/com/android/systemui/assist/PhoneStateMonitor.java
index 652ce6f04db0..257ad50eff61 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/PhoneStateMonitor.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/PhoneStateMonitor.java
@@ -104,7 +104,7 @@ public final class PhoneStateMonitor {
});
}
- int getPhoneState() {
+ public int getPhoneState() {
int phoneState;
if (isShadeFullscreen()) {
phoneState = getPhoneLockscreenState();
diff --git a/packages/SystemUI/src/com/android/systemui/assist/ui/DefaultUiController.java b/packages/SystemUI/src/com/android/systemui/assist/ui/DefaultUiController.java
index 68242f0a0ac2..05f3617dd1d6 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/ui/DefaultUiController.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/ui/DefaultUiController.java
@@ -38,15 +38,21 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.assist.AssistHandleViewController;
+import com.android.systemui.assist.AssistLogger;
import com.android.systemui.assist.AssistManager;
+import com.android.systemui.assist.AssistantSessionEvent;
import com.android.systemui.statusbar.NavigationBarController;
import java.util.Locale;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
/**
* Default UiController implementation. Shows white edge lights along the bottom of the phone,
* expanding from the corners to meet in the center.
*/
+@Singleton
public class DefaultUiController implements AssistManager.UiController {
private static final String TAG = "DefaultUiController";
@@ -58,6 +64,7 @@ public class DefaultUiController implements AssistManager.UiController {
protected final FrameLayout mRoot;
protected InvocationLightsView mInvocationLightsView;
+ protected final AssistLogger mAssistLogger;
private final WindowManager mWindowManager;
private final WindowManager.LayoutParams mLayoutParams;
@@ -69,7 +76,9 @@ public class DefaultUiController implements AssistManager.UiController {
private ValueAnimator mInvocationAnimator = new ValueAnimator();
- public DefaultUiController(Context context) {
+ @Inject
+ public DefaultUiController(Context context, AssistLogger assistLogger) {
+ mAssistLogger = assistLogger;
mRoot = new FrameLayout(context);
mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
@@ -142,6 +151,11 @@ public class DefaultUiController implements AssistManager.UiController {
if (VERBOSE) {
Log.v(TAG, "Invocation started: type=" + type);
}
+ mAssistLogger.reportAssistantInvocationEventFromLegacy(
+ type,
+ /* isInvocationComplete = */ false,
+ /* assistantComponent = */ null,
+ /* legacyDeviceState = */ null);
MetricsLogger.action(new LogMaker(MetricsEvent.ASSISTANT)
.setType(MetricsEvent.TYPE_ACTION)
.setSubtype(Dependency.get(AssistManager.class).toLoggingSubType(type)));
@@ -152,6 +166,8 @@ public class DefaultUiController implements AssistManager.UiController {
if (VERBOSE) {
Log.v(TAG, "Invocation cancelled: type=" + type);
}
+ mAssistLogger.reportAssistantSessionEvent(
+ AssistantSessionEvent.ASSISTANT_SESSION_INVOCATION_CANCELLED);
MetricsLogger.action(new LogMaker(MetricsEvent.ASSISTANT)
.setType(MetricsEvent.TYPE_DISMISS)
.setSubtype(DISMISS_REASON_INVOCATION_CANCELLED));
diff --git a/packages/SystemUI/src/com/android/systemui/broadcast/ActionReceiver.kt b/packages/SystemUI/src/com/android/systemui/broadcast/ActionReceiver.kt
new file mode 100644
index 000000000000..434b03d404dc
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/broadcast/ActionReceiver.kt
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.broadcast
+
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import android.content.IntentFilter
+import android.util.ArraySet
+import com.android.systemui.Dumpable
+import com.android.systemui.broadcast.logging.BroadcastDispatcherLogger
+import com.android.systemui.util.indentIfPossible
+import java.io.FileDescriptor
+import java.io.PrintWriter
+import java.util.concurrent.Executor
+import java.util.concurrent.atomic.AtomicInteger
+
+/**
+ * Receiver for a given action-userId pair to be used by [UserBroadcastDispatcher].
+ *
+ * Each object of this class will take care of a single Action. It will register if it has at least
+ * one [BroadcastReceiver] added to it, and unregister when none are left.
+ *
+ * It will also re-register if filters with new categories are added. But this should not happen
+ * often.
+ *
+ * This class has no sync controls, so make sure to only make modifications from the background
+ * thread.
+ */
+class ActionReceiver(
+ private val action: String,
+ private val userId: Int,
+ private val registerAction: BroadcastReceiver.(IntentFilter) -> Unit,
+ private val unregisterAction: BroadcastReceiver.() -> Unit,
+ private val bgExecutor: Executor,
+ private val logger: BroadcastDispatcherLogger
+) : BroadcastReceiver(), Dumpable {
+
+ companion object {
+ val index = AtomicInteger(0)
+ }
+
+ var registered = false
+ private set
+ private val receiverDatas = ArraySet<ReceiverData>()
+ private val activeCategories = ArraySet<String>()
+
+ @Throws(IllegalArgumentException::class)
+ fun addReceiverData(receiverData: ReceiverData) {
+ if (!receiverData.filter.hasAction(action)) {
+ throw(IllegalArgumentException("Trying to attach to $action without correct action," +
+ "receiver: ${receiverData.receiver}"))
+ }
+ val addedCategories = activeCategories
+ .addAll(receiverData.filter.categoriesIterator()?.asSequence() ?: emptySequence())
+
+ if (receiverDatas.add(receiverData) && receiverDatas.size == 1) {
+ registerAction(createFilter())
+ registered = true
+ } else if (addedCategories) {
+ unregisterAction()
+ registerAction(createFilter())
+ }
+ }
+
+ fun hasReceiver(receiver: BroadcastReceiver): Boolean {
+ return receiverDatas.any { it.receiver == receiver }
+ }
+
+ private fun createFilter(): IntentFilter {
+ val filter = IntentFilter(action)
+ activeCategories.forEach(filter::addCategory)
+ return filter
+ }
+
+ fun removeReceiver(receiver: BroadcastReceiver) {
+ if (receiverDatas.removeAll { it.receiver == receiver } &&
+ receiverDatas.isEmpty() && registered) {
+ unregisterAction()
+ registered = false
+ activeCategories.clear()
+ }
+ }
+
+ @Throws(IllegalStateException::class)
+ override fun onReceive(context: Context, intent: Intent) {
+ if (intent.action != action) {
+ throw(IllegalStateException("Received intent for ${intent.action} " +
+ "in receiver for $action}"))
+ }
+ val id = index.getAndIncrement()
+ logger.logBroadcastReceived(id, userId, intent)
+ // Immediately return control to ActivityManager
+ bgExecutor.execute {
+ receiverDatas.forEach {
+ if (it.filter.matchCategories(intent.categories) == null) {
+ it.executor.execute {
+ it.receiver.pendingResult = pendingResult
+ it.receiver.onReceive(context, intent)
+ logger.logBroadcastDispatched(id, action, it.receiver)
+ }
+ }
+ }
+ }
+ }
+
+ override fun dump(fd: FileDescriptor, pw: PrintWriter, args: Array<out String>) {
+ pw.indentIfPossible {
+ println("Registered: $registered")
+ println("Receivers:")
+ pw.indentIfPossible {
+ receiverDatas.forEach {
+ println(it.receiver)
+ }
+ }
+ println("Categories: ${activeCategories.joinToString(", ")}")
+ }
+ }
+} \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/broadcast/BroadcastDispatcher.kt b/packages/SystemUI/src/com/android/systemui/broadcast/BroadcastDispatcher.kt
index 67c0c620f136..b9b849b8488e 100644
--- a/packages/SystemUI/src/com/android/systemui/broadcast/BroadcastDispatcher.kt
+++ b/packages/SystemUI/src/com/android/systemui/broadcast/BroadcastDispatcher.kt
@@ -29,6 +29,7 @@ import android.os.UserHandle
import android.text.TextUtils
import android.util.SparseArray
import com.android.internal.annotations.VisibleForTesting
+import com.android.internal.util.IndentingPrintWriter
import com.android.systemui.Dumpable
import com.android.systemui.broadcast.logging.BroadcastDispatcherLogger
import com.android.systemui.dump.DumpManager
@@ -65,6 +66,7 @@ private const val DEBUG = true
open class BroadcastDispatcher constructor (
private val context: Context,
private val bgLooper: Looper,
+ private val bgExecutor: Executor,
private val dumpManager: DumpManager,
private val logger: BroadcastDispatcherLogger
) : Dumpable, BroadcastReceiver() {
@@ -173,15 +175,18 @@ open class BroadcastDispatcher constructor (
@VisibleForTesting
protected open fun createUBRForUser(userId: Int) =
- UserBroadcastDispatcher(context, userId, bgLooper, logger)
+ UserBroadcastDispatcher(context, userId, bgLooper, bgExecutor, logger)
override fun dump(fd: FileDescriptor, pw: PrintWriter, args: Array<out String>) {
pw.println("Broadcast dispatcher:")
- pw.println(" Current user: ${handler.currentUser}")
+ val ipw = IndentingPrintWriter(pw, " ")
+ ipw.increaseIndent()
+ ipw.println("Current user: ${handler.currentUser}")
for (index in 0 until receiversByUser.size()) {
- pw.println(" User ${receiversByUser.keyAt(index)}")
- receiversByUser.valueAt(index).dump(fd, pw, args)
+ ipw.println("User ${receiversByUser.keyAt(index)}")
+ receiversByUser.valueAt(index).dump(fd, ipw, args)
}
+ ipw.decreaseIndent()
}
private val handler = object : Handler(bgLooper) {
diff --git a/packages/SystemUI/src/com/android/systemui/broadcast/UserBroadcastDispatcher.kt b/packages/SystemUI/src/com/android/systemui/broadcast/UserBroadcastDispatcher.kt
index 96f5a1f6fbe8..11da920d69ed 100644
--- a/packages/SystemUI/src/com/android/systemui/broadcast/UserBroadcastDispatcher.kt
+++ b/packages/SystemUI/src/com/android/systemui/broadcast/UserBroadcastDispatcher.kt
@@ -18,8 +18,6 @@ package com.android.systemui.broadcast
import android.content.BroadcastReceiver
import android.content.Context
-import android.content.Intent
-import android.content.IntentFilter
import android.os.Handler
import android.os.Looper
import android.os.Message
@@ -31,11 +29,10 @@ import androidx.annotation.VisibleForTesting
import com.android.internal.util.Preconditions
import com.android.systemui.Dumpable
import com.android.systemui.broadcast.logging.BroadcastDispatcherLogger
+import com.android.systemui.util.indentIfPossible
import java.io.FileDescriptor
import java.io.PrintWriter
-import java.lang.IllegalArgumentException
-import java.lang.IllegalStateException
-import java.util.concurrent.atomic.AtomicBoolean
+import java.util.concurrent.Executor
import java.util.concurrent.atomic.AtomicInteger
private const val MSG_REGISTER_RECEIVER = 0
@@ -48,16 +45,14 @@ private const val DEBUG = false
*
* Created by [BroadcastDispatcher] as needed by users. The value of [userId] can be
* [UserHandle.USER_ALL].
- *
- * Each instance of this class will register itself exactly once with [Context]. Updates to the
- * [IntentFilter] will be done in the background thread.
*/
-class UserBroadcastDispatcher(
+open class UserBroadcastDispatcher(
private val context: Context,
private val userId: Int,
private val bgLooper: Looper,
+ private val bgExecutor: Executor,
private val logger: BroadcastDispatcherLogger
-) : BroadcastReceiver(), Dumpable {
+) : Dumpable {
companion object {
// Used only for debugging. If not debugging, this variable will not be accessed and all
@@ -76,47 +71,16 @@ class UserBroadcastDispatcher(
}
}
- private val registered = AtomicBoolean(false)
-
- internal fun isRegistered() = registered.get()
-
// Only modify in BG thread
- private val actionsToReceivers = ArrayMap<String, MutableSet<ReceiverData>>()
- private val receiverToReceiverData = ArrayMap<BroadcastReceiver, MutableSet<ReceiverData>>()
+ @VisibleForTesting
+ internal val actionsToActionsReceivers = ArrayMap<String, ActionReceiver>()
+ private val receiverToActions = ArrayMap<BroadcastReceiver, MutableSet<String>>()
@VisibleForTesting
internal fun isReceiverReferenceHeld(receiver: BroadcastReceiver): Boolean {
- return receiverToReceiverData.contains(receiver) ||
- actionsToReceivers.any {
- it.value.any { it.receiver == receiver }
- }
- }
-
- // Only call on BG thread as it reads from the maps
- private fun createFilter(): IntentFilter {
- Preconditions.checkState(bgHandler.looper.isCurrentThread,
- "This method should only be called from BG thread")
- val categories = mutableSetOf<String>()
- receiverToReceiverData.values.flatten().forEach {
- it.filter.categoriesIterator()?.asSequence()?.let {
- categories.addAll(it)
- }
- }
- val intentFilter = IntentFilter().apply {
- // The keys of the arrayMap are of type String! so null check is needed
- actionsToReceivers.keys.forEach { if (it != null) addAction(it) else Unit }
- categories.forEach { addCategory(it) }
- }
- return intentFilter
- }
-
- override fun onReceive(context: Context, intent: Intent) {
- val id = index.getAndIncrement()
- if (DEBUG) Log.w(TAG, "[$id] Received $intent")
- logger.logBroadcastReceived(id, userId, intent)
- bgHandler.post(
- HandleBroadcastRunnable(
- actionsToReceivers, context, intent, pendingResult, id, logger))
+ return actionsToActionsReceivers.values.any {
+ it.hasReceiver(receiver)
+ } || (receiver in receiverToActions)
}
/**
@@ -137,109 +101,57 @@ class UserBroadcastDispatcher(
Preconditions.checkState(bgHandler.looper.isCurrentThread,
"This method should only be called from BG thread")
if (DEBUG) Log.w(TAG, "Register receiver: ${receiverData.receiver}")
- receiverToReceiverData.getOrPut(receiverData.receiver, { ArraySet() }).add(receiverData)
- var changed = false
- // Index the BroadcastReceiver by all its actions, that way it's easier to dispatch given
- // a received intent.
+ receiverToActions
+ .getOrPut(receiverData.receiver, { ArraySet() })
+ .addAll(receiverData.filter.actionsIterator()?.asSequence() ?: emptySequence())
receiverData.filter.actionsIterator().forEach {
- actionsToReceivers.getOrPut(it) {
- changed = true
- ArraySet()
- }.add(receiverData)
+ actionsToActionsReceivers
+ .getOrPut(it, { createActionReceiver(it) })
+ .addReceiverData(receiverData)
}
logger.logReceiverRegistered(userId, receiverData.receiver)
- if (changed) {
- createFilterAndRegisterReceiverBG()
- }
+ }
+
+ @VisibleForTesting
+ internal open fun createActionReceiver(action: String): ActionReceiver {
+ return ActionReceiver(
+ action,
+ userId,
+ {
+ context.registerReceiverAsUser(this, UserHandle.of(userId), it, null, bgHandler)
+ logger.logContextReceiverRegistered(userId, it)
+ },
+ {
+ try {
+ context.unregisterReceiver(this)
+ logger.logContextReceiverUnregistered(userId, action)
+ } catch (e: IllegalArgumentException) {
+ Log.e(TAG, "Trying to unregister unregistered receiver for user $userId, " +
+ "action $action",
+ IllegalStateException(e))
+ }
+ },
+ bgExecutor,
+ logger
+ )
}
private fun handleUnregisterReceiver(receiver: BroadcastReceiver) {
Preconditions.checkState(bgHandler.looper.isCurrentThread,
"This method should only be called from BG thread")
if (DEBUG) Log.w(TAG, "Unregister receiver: $receiver")
- val actions = receiverToReceiverData.getOrElse(receiver) { return }
- .flatMap { it.filter.actionsIterator().asSequence().asIterable() }.toSet()
- receiverToReceiverData.remove(receiver)?.clear()
- var changed = false
- actions.forEach { action ->
- actionsToReceivers.get(action)?.removeIf { it.receiver == receiver }
- if (actionsToReceivers.get(action)?.isEmpty() ?: false) {
- changed = true
- actionsToReceivers.remove(action)
- }
+ receiverToActions.getOrDefault(receiver, mutableSetOf()).forEach {
+ actionsToActionsReceivers.get(it)?.removeReceiver(receiver)
}
+ receiverToActions.remove(receiver)
logger.logReceiverUnregistered(userId, receiver)
- if (changed) {
- createFilterAndRegisterReceiverBG()
- }
- }
-
- // Only call this from a BG thread
- private fun createFilterAndRegisterReceiverBG() {
- val intentFilter = createFilter()
- bgHandler.post(RegisterReceiverRunnable(intentFilter))
}
override fun dump(fd: FileDescriptor, pw: PrintWriter, args: Array<out String>) {
- pw.println(" Registered=${registered.get()}")
- actionsToReceivers.forEach { (action, list) ->
- pw.println(" $action:")
- list.forEach { pw.println(" ${it.receiver}") }
- }
- }
-
- private class HandleBroadcastRunnable(
- val actionsToReceivers: Map<String, Set<ReceiverData>>,
- val context: Context,
- val intent: Intent,
- val pendingResult: PendingResult,
- val index: Int,
- val logger: BroadcastDispatcherLogger
- ) : Runnable {
- override fun run() {
- if (DEBUG) Log.w(TAG, "[$index] Dispatching $intent")
- actionsToReceivers.get(intent.action)
- ?.filter {
- it.filter.hasAction(intent.action) &&
- it.filter.matchCategories(intent.categories) == null }
- ?.forEach {
- it.executor.execute {
- if (DEBUG) Log.w(TAG,
- "[$index] Dispatching ${intent.action} to ${it.receiver}")
- logger.logBroadcastDispatched(index, intent.action, it.receiver)
- it.receiver.pendingResult = pendingResult
- it.receiver.onReceive(context, intent)
- }
- }
- }
- }
-
- private inner class RegisterReceiverRunnable(val intentFilter: IntentFilter) : Runnable {
-
- /*
- * Registers and unregisters the BroadcastReceiver
- */
- override fun run() {
- if (registered.get()) {
- try {
- context.unregisterReceiver(this@UserBroadcastDispatcher)
- logger.logContextReceiverUnregistered(userId)
- } catch (e: IllegalArgumentException) {
- Log.e(TAG, "Trying to unregister unregistered receiver for user $userId",
- IllegalStateException(e))
- }
- registered.set(false)
- }
- // Short interval without receiver, this can be problematic
- if (intentFilter.countActions() > 0 && !registered.get()) {
- context.registerReceiverAsUser(
- this@UserBroadcastDispatcher,
- UserHandle.of(userId),
- intentFilter,
- null,
- bgHandler)
- registered.set(true)
- logger.logContextReceiverRegistered(userId, intentFilter)
+ pw.indentIfPossible {
+ actionsToActionsReceivers.forEach { (action, actionReceiver) ->
+ println("$action:")
+ actionReceiver.dump(fd, pw, args)
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/broadcast/logging/BroadcastDispatcherLogger.kt b/packages/SystemUI/src/com/android/systemui/broadcast/logging/BroadcastDispatcherLogger.kt
index 123a8ae6307d..6ba88f4e69d7 100644
--- a/packages/SystemUI/src/com/android/systemui/broadcast/logging/BroadcastDispatcherLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/broadcast/logging/BroadcastDispatcherLogger.kt
@@ -99,11 +99,12 @@ class BroadcastDispatcherLogger @Inject constructor(
})
}
- fun logContextReceiverUnregistered(user: Int) {
+ fun logContextReceiverUnregistered(user: Int, action: String) {
log(INFO, {
int1 = user
+ str1 = action
}, {
- "Receiver unregistered with Context for user $int1."
+ "Receiver unregistered with Context for user $int1, action $str1"
})
}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BadgedImageView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BadgedImageView.java
index 55be77ca3be5..a86a46960bcb 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BadgedImageView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BadgedImageView.java
@@ -100,6 +100,7 @@ public class BadgedImageView extends ImageView {
mDotRenderer = new DotRenderer(mBubbleBitmapSize, iconPath, DEFAULT_PATH_SIZE);
setFocusable(true);
+ setClickable(true);
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java b/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java
index 6da7bc8a2ade..b615885596ee 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java
@@ -71,12 +71,14 @@ class Bubble implements BubbleViewProvider {
// Items that are typically loaded later
private String mAppName;
private ShortcutInfo mShortcutInfo;
+ private String mMetadataShortcutId;
private BadgedImageView mIconView;
private BubbleExpandedView mExpandedView;
private BubbleViewInfoTask mInflationTask;
private boolean mInflateSynchronously;
private boolean mPendingIntentCanceled;
+ private boolean mIsImportantConversation;
/**
* Presentational info about the flyout.
@@ -144,6 +146,7 @@ class Bubble implements BubbleViewProvider {
mDesiredHeight = desiredHeight;
mDesiredHeightResId = desiredHeightResId;
mTitle = title;
+ mShowBubbleUpdateDot = false;
}
/** Used in tests when no UI is required. */
@@ -216,6 +219,14 @@ class Bubble implements BubbleViewProvider {
return mTitle;
}
+ String getMetadataShortcutId() {
+ return mMetadataShortcutId;
+ }
+
+ boolean hasMetadataShortcutId() {
+ return (mMetadataShortcutId != null && !mMetadataShortcutId.isEmpty());
+ }
+
/**
* Call when the views should be removed, ensure this is called to clean up ActivityView
* content.
@@ -348,9 +359,10 @@ class Bubble implements BubbleViewProvider {
mAppUid = entry.getSbn().getUid();
mInstanceId = entry.getSbn().getInstanceId();
mFlyoutMessage = BubbleViewInfoTask.extractFlyoutMessage(entry);
+ mShortcutInfo = (entry.getRanking() != null ? entry.getRanking().getShortcutInfo() : null);
+ mMetadataShortcutId = (entry.getBubbleMetadata() != null
+ ? entry.getBubbleMetadata().getShortcutId() : null);
if (entry.getRanking() != null) {
- mShortcutInfo = entry.getRanking().getShortcutInfo() != null
- ? entry.getRanking().getShortcutInfo() : mShortcutInfo;
mIsVisuallyInterruptive = entry.getRanking().visuallyInterruptive();
}
if (entry.getBubbleMetadata() != null) {
@@ -361,6 +373,8 @@ class Bubble implements BubbleViewProvider {
mIntent = entry.getBubbleMetadata().getIntent();
mDeleteIntent = entry.getBubbleMetadata().getDeleteIntent();
}
+ mIsImportantConversation =
+ entry.getChannel() == null ? false : entry.getChannel().isImportantConversation();
}
@Nullable
@@ -431,6 +445,13 @@ class Bubble implements BubbleViewProvider {
}
/**
+ * Whether this notification conversation is important.
+ */
+ boolean isImportantConversation() {
+ return mIsImportantConversation;
+ }
+
+ /**
* Sets whether this notification should be suppressed in the shade.
*/
void setSuppressNotification(boolean suppressNotification) {
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
index b2c5402c7cd3..ccfbd8f57df1 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
@@ -52,13 +52,16 @@ import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.pm.ActivityInfo;
+import android.content.pm.LauncherApps;
import android.content.pm.PackageManager;
+import android.content.pm.ShortcutInfo;
import android.content.res.Configuration;
import android.graphics.PixelFormat;
import android.os.Binder;
import android.os.Handler;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.UserHandle;
import android.service.notification.NotificationListenerService;
import android.service.notification.NotificationListenerService.RankingMap;
import android.service.notification.ZenModeConfig;
@@ -67,6 +70,7 @@ import android.util.Log;
import android.util.Pair;
import android.util.SparseSetArray;
import android.view.Display;
+import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
@@ -129,7 +133,7 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
@IntDef({DISMISS_USER_GESTURE, DISMISS_AGED, DISMISS_TASK_FINISHED, DISMISS_BLOCKED,
DISMISS_NOTIF_CANCEL, DISMISS_ACCESSIBILITY_ACTION, DISMISS_NO_LONGER_BUBBLE,
DISMISS_USER_CHANGED, DISMISS_GROUP_CANCELLED, DISMISS_INVALID_INTENT,
- DISMISS_OVERFLOW_MAX_REACHED})
+ DISMISS_OVERFLOW_MAX_REACHED, DISMISS_SHORTCUT_REMOVED, DISMISS_PACKAGE_REMOVED})
@Target({FIELD, LOCAL_VARIABLE, PARAMETER})
@interface DismissReason {}
@@ -144,6 +148,8 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
static final int DISMISS_GROUP_CANCELLED = 9;
static final int DISMISS_INVALID_INTENT = 10;
static final int DISMISS_OVERFLOW_MAX_REACHED = 11;
+ static final int DISMISS_SHORTCUT_REMOVED = 12;
+ static final int DISMISS_PACKAGE_REMOVED = 13;
private final Context mContext;
private final NotificationEntryManager mNotificationEntryManager;
@@ -182,6 +188,12 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
// Only load overflow data from disk once
private boolean mOverflowDataLoaded = false;
+ /**
+ * When the shade status changes to SHADE (from anything but SHADE, like LOCKED) we'll select
+ * this bubble and expand the stack.
+ */
+ @Nullable private NotificationEntry mNotifEntryToExpandOnShadeUnlock;
+
private final NotificationInterruptStateProvider mNotificationInterruptStateProvider;
private IStatusBarService mBarService;
private WindowManager mWindowManager;
@@ -206,6 +218,9 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
*/
private int mDensityDpi = Configuration.DENSITY_DPI_UNDEFINED;
+ /** Last known direction, used to detect layout direction changes @link #onConfigChanged}. */
+ private int mLayoutDirection = View.LAYOUT_DIRECTION_UNDEFINED;
+
private boolean mInflateSynchronously;
// TODO (b/145659174): allow for multiple callbacks to support the "shadow" new notif pipeline
@@ -291,6 +306,12 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
if (shouldCollapse) {
collapseStack();
}
+
+ if (mNotifEntryToExpandOnShadeUnlock != null) {
+ expandStackAndSelectBubble(mNotifEntryToExpandOnShadeUnlock);
+ mNotifEntryToExpandOnShadeUnlock = null;
+ }
+
updateStack();
}
}
@@ -318,7 +339,8 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
SysUiState sysUiState,
INotificationManager notificationManager,
@Nullable IStatusBarService statusBarService,
- WindowManager windowManager) {
+ WindowManager windowManager,
+ LauncherApps launcherApps) {
dumpManager.registerDumpable(TAG, this);
mContext = context;
mShadeController = shadeController;
@@ -394,6 +416,7 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
: statusBarService;
mBubbleScrim = new ScrimView(mContext);
+ mBubbleScrim.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
mSavedBubbleKeysPerUser = new SparseSetArray<>();
mCurrentUserId = mNotifUserManager.getCurrentUserId();
@@ -409,6 +432,47 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
});
mBubbleIconFactory = new BubbleIconFactory(context);
+
+ launcherApps.registerCallback(new LauncherApps.Callback() {
+ @Override
+ public void onPackageAdded(String s, UserHandle userHandle) {}
+
+ @Override
+ public void onPackageChanged(String s, UserHandle userHandle) {}
+
+ @Override
+ public void onPackageRemoved(String s, UserHandle userHandle) {
+ // Remove bubbles with this package name, since it has been uninstalled and attempts
+ // to open a bubble from an uninstalled app can cause issues.
+ mBubbleData.removeBubblesWithPackageName(s, DISMISS_PACKAGE_REMOVED);
+ }
+
+ @Override
+ public void onPackagesAvailable(String[] strings, UserHandle userHandle,
+ boolean b) {
+
+ }
+
+ @Override
+ public void onPackagesUnavailable(String[] packages, UserHandle userHandle,
+ boolean b) {
+ for (String packageName : packages) {
+ // Remove bubbles from unavailable apps. This can occur when the app is on
+ // external storage that has been removed.
+ mBubbleData.removeBubblesWithPackageName(packageName, DISMISS_PACKAGE_REMOVED);
+ }
+ }
+
+ @Override
+ public void onShortcutsChanged(String packageName, List<ShortcutInfo> validShortcuts,
+ UserHandle user) {
+ super.onShortcutsChanged(packageName, validShortcuts, user);
+
+ // Remove bubbles whose shortcuts aren't in the latest list of valid shortcuts.
+ mBubbleData.removeBubblesWithInvalidShortcuts(
+ packageName, validShortcuts, DISMISS_SHORTCUT_REMOVED);
+ }
+ });
}
/**
@@ -419,12 +483,13 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
}
/**
- * Dispatches a back press into the expanded Bubble's ActivityView if its IME is visible,
- * causing it to hide.
+ * Hides the current input method, wherever it may be focused, via InputMethodManagerInternal.
*/
- public void hideImeFromExpandedBubble() {
- if (mStackView != null) {
- mStackView.hideImeFromExpandedBubble();
+ public void hideCurrentInputMethod() {
+ try {
+ mBarService.hideCurrentInputMethodForBubbles();
+ } catch (RemoteException e) {
+ e.printStackTrace();
}
}
@@ -629,8 +694,8 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
if (mStackView == null) {
mStackView = new BubbleStackView(
mContext, mBubbleData, mSurfaceSynchronizer, mFloatingContentCoordinator,
- mSysUiState, this::onAllBubblesAnimatedOut,
- this::onImeVisibilityChanged);
+ mSysUiState, this::onAllBubblesAnimatedOut, this::onImeVisibilityChanged,
+ this::hideCurrentInputMethod);
mStackView.addView(mBubbleScrim);
if (mExpandListener != null) {
mStackView.setExpandListener(mExpandListener);
@@ -830,8 +895,10 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
mBubbleIconFactory = new BubbleIconFactory(mContext);
mStackView.onDisplaySizeChanged();
}
-
- mStackView.onLayoutDirectionChanged();
+ if (newConfig.getLayoutDirection() != mLayoutDirection) {
+ mLayoutDirection = newConfig.getLayoutDirection();
+ mStackView.onLayoutDirectionChanged(mLayoutDirection);
+ }
}
}
@@ -928,20 +995,49 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
* @param entry the notification for the bubble to be selected
*/
public void expandStackAndSelectBubble(NotificationEntry entry) {
- String key = entry.getKey();
- Bubble bubble = mBubbleData.getBubbleInStackWithKey(key);
- if (bubble != null) {
- mBubbleData.setSelectedBubble(bubble);
- mBubbleData.setExpanded(true);
- } else {
- bubble = mBubbleData.getOverflowBubbleWithKey(key);
+ if (mStatusBarStateListener.getCurrentState() == SHADE) {
+ mNotifEntryToExpandOnShadeUnlock = null;
+
+ String key = entry.getKey();
+ Bubble bubble = mBubbleData.getBubbleInStackWithKey(key);
if (bubble != null) {
- promoteBubbleFromOverflow(bubble);
- } else if (entry.canBubble()) {
- // It can bubble but it's not -- it got aged out of the overflow before it
- // was dismissed or opened, make it a bubble again.
- setIsBubble(entry, true /* isBubble */, true /* autoExpand */);
+ mBubbleData.setSelectedBubble(bubble);
+ mBubbleData.setExpanded(true);
+ } else {
+ bubble = mBubbleData.getOverflowBubbleWithKey(key);
+ if (bubble != null) {
+ promoteBubbleFromOverflow(bubble);
+ } else if (entry.canBubble()) {
+ // It can bubble but it's not -- it got aged out of the overflow before it
+ // was dismissed or opened, make it a bubble again.
+ setIsBubble(entry, true /* isBubble */, true /* autoExpand */);
+ }
}
+ } else {
+ // Wait until we're unlocked to expand, so that the user can see the expand animation
+ // and also to work around bugs with expansion animation + shade unlock happening at the
+ // same time.
+ mNotifEntryToExpandOnShadeUnlock = entry;
+ }
+ }
+
+ /**
+ * When a notification is marked Priority, expand the stack if needed,
+ * then (maybe create and) select the given bubble.
+ *
+ * @param entry the notification for the bubble to show
+ */
+ public void onUserChangedImportance(NotificationEntry entry) {
+ try {
+ int flags = Notification.BubbleMetadata.FLAG_SUPPRESS_NOTIFICATION;
+ flags |= Notification.BubbleMetadata.FLAG_AUTO_EXPAND_BUBBLE;
+ mBarService.onNotificationBubbleChanged(entry.getKey(), true, flags);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.getMessage());
+ }
+ mShadeController.collapsePanel(true);
+ if (entry.getRow() != null) {
+ entry.getRow().updateBubbleButton();
}
}
@@ -1074,7 +1170,7 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
@MainThread
void removeBubble(String key, int reason) {
if (mBubbleData.hasAnyBubbleWithKey(key)) {
- mBubbleData.notificationEntryRemoved(key, reason);
+ mBubbleData.dismissBubbleWithKey(key, reason);
}
}
@@ -1132,7 +1228,7 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
rankingMap.getRanking(key, mTmpRanking);
boolean isActiveBubble = mBubbleData.hasAnyBubbleWithKey(key);
if (isActiveBubble && !mTmpRanking.canBubble()) {
- mBubbleData.notificationEntryRemoved(entry.getKey(),
+ mBubbleData.dismissBubbleWithKey(entry.getKey(),
BubbleController.DISMISS_BLOCKED);
} else if (entry != null && mTmpRanking.isBubble() && !isActiveBubble) {
entry.setFlagBubble(true);
@@ -1494,7 +1590,11 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
@Override
public void onBackPressedOnTaskRoot(RunningTaskInfo taskInfo) {
if (mStackView != null && taskInfo.displayId == getExpandedDisplayId(mContext)) {
- mBubbleData.setExpanded(false);
+ if (mImeVisible) {
+ hideCurrentInputMethod();
+ } else {
+ mBubbleData.setExpanded(false);
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java
index c8706126c1ad..7020f1cb88eb 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java
@@ -24,6 +24,7 @@ import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME
import android.annotation.NonNull;
import android.app.PendingIntent;
import android.content.Context;
+import android.content.pm.ShortcutInfo;
import android.util.Log;
import android.util.Pair;
import android.view.View;
@@ -42,8 +43,12 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Objects;
+import java.util.Set;
+import java.util.function.Consumer;
+import java.util.function.Predicate;
import javax.inject.Inject;
import javax.inject.Singleton;
@@ -286,9 +291,9 @@ public class BubbleData {
}
/**
- * Called when a notification associated with a bubble is removed.
+ * Dismisses the bubble with the matching key, if it exists.
*/
- public void notificationEntryRemoved(String key, @DismissReason int reason) {
+ public void dismissBubbleWithKey(String key, @DismissReason int reason) {
if (DEBUG_BUBBLE_DATA) {
Log.d(TAG, "notificationEntryRemoved: key=" + key + " reason=" + reason);
}
@@ -349,6 +354,44 @@ public class BubbleData {
return bubbleChildren;
}
+ /**
+ * Removes bubbles from the given package whose shortcut are not in the provided list of valid
+ * shortcuts.
+ */
+ public void removeBubblesWithInvalidShortcuts(
+ String packageName, List<ShortcutInfo> validShortcuts, int reason) {
+
+ final Set<String> validShortcutIds = new HashSet<String>();
+ for (ShortcutInfo info : validShortcuts) {
+ validShortcutIds.add(info.getId());
+ }
+
+ final Predicate<Bubble> invalidBubblesFromPackage = bubble ->
+ packageName.equals(bubble.getPackageName())
+ && (bubble.getShortcutInfo() == null
+ || !bubble.getShortcutInfo().isEnabled()
+ || !validShortcutIds.contains(bubble.getShortcutInfo().getId()));
+
+ final Consumer<Bubble> removeBubble = bubble ->
+ dismissBubbleWithKey(bubble.getKey(), reason);
+
+ performActionOnBubblesMatching(getBubbles(), invalidBubblesFromPackage, removeBubble);
+ performActionOnBubblesMatching(
+ getOverflowBubbles(), invalidBubblesFromPackage, removeBubble);
+ }
+
+ /** Dismisses all bubbles from the given package. */
+ public void removeBubblesWithPackageName(String packageName, int reason) {
+ final Predicate<Bubble> bubbleMatchesPackage = bubble ->
+ bubble.getPackageName().equals(packageName);
+
+ final Consumer<Bubble> removeBubble = bubble ->
+ dismissBubbleWithKey(bubble.getKey(), reason);
+
+ performActionOnBubblesMatching(getBubbles(), bubbleMatchesPackage, removeBubble);
+ performActionOnBubblesMatching(getOverflowBubbles(), bubbleMatchesPackage, removeBubble);
+ }
+
private void doAdd(Bubble bubble) {
if (DEBUG_BUBBLE_DATA) {
Log.d(TAG, "doAdd: " + bubble);
@@ -388,6 +431,21 @@ public class BubbleData {
}
}
+ /** Runs the given action on Bubbles that match the given predicate. */
+ private void performActionOnBubblesMatching(
+ List<Bubble> bubbles, Predicate<Bubble> predicate, Consumer<Bubble> action) {
+ final List<Bubble> matchingBubbles = new ArrayList<>();
+ for (Bubble bubble : bubbles) {
+ if (predicate.test(bubble)) {
+ matchingBubbles.add(bubble);
+ }
+ }
+
+ for (Bubble matchingBubble : matchingBubbles) {
+ action.accept(matchingBubble);
+ }
+ }
+
private void doRemove(String key, @DismissReason int reason) {
if (DEBUG_BUBBLE_DATA) {
Log.d(TAG, "doRemove: " + key);
@@ -400,9 +458,11 @@ public class BubbleData {
if (indexToRemove == -1) {
if (hasOverflowBubbleWithKey(key)
&& (reason == BubbleController.DISMISS_NOTIF_CANCEL
- || reason == BubbleController.DISMISS_GROUP_CANCELLED
- || reason == BubbleController.DISMISS_NO_LONGER_BUBBLE
- || reason == BubbleController.DISMISS_BLOCKED)) {
+ || reason == BubbleController.DISMISS_GROUP_CANCELLED
+ || reason == BubbleController.DISMISS_NO_LONGER_BUBBLE
+ || reason == BubbleController.DISMISS_BLOCKED
+ || reason == BubbleController.DISMISS_SHORTCUT_REMOVED
+ || reason == BubbleController.DISMISS_PACKAGE_REMOVED)) {
Bubble b = getOverflowBubbleWithKey(key);
if (DEBUG_BUBBLE_DATA) {
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleDataRepository.kt b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleDataRepository.kt
index 0c25d144938c..db64a13f3df3 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleDataRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleDataRepository.kt
@@ -77,7 +77,7 @@ internal class BubbleDataRepository @Inject constructor(
BubbleEntity(
userId,
b.packageName,
- b.shortcutInfo?.id ?: return@mapNotNull null,
+ b.metadataShortcutId ?: return@mapNotNull null,
b.key,
b.rawDesiredHeight,
b.rawDesiredHeightResId,
@@ -162,7 +162,7 @@ internal class BubbleDataRepository @Inject constructor(
// into Bubble.
val bubbles = entities.mapNotNull { entity ->
shortcutMap[ShortcutKey(entity.userId, entity.packageName)]
- ?.first { shortcutInfo -> entity.shortcutId == shortcutInfo.id }
+ ?.firstOrNull { shortcutInfo -> entity.shortcutId == shortcutInfo.id }
?.let { shortcutInfo -> Bubble(
entity.key,
shortcutInfo,
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
index 2f7ffde50fd4..b34312e2b473 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
@@ -35,6 +35,7 @@ import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_BUBBLES;
import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME;
import android.annotation.SuppressLint;
+import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.app.ActivityTaskManager;
import android.app.ActivityView;
@@ -119,6 +120,8 @@ public class BubbleExpandedView extends LinearLayout {
private int mPointerWidth;
private int mPointerHeight;
private ShapeDrawable mPointerDrawable;
+ private int mExpandedViewPadding;
+
@Nullable private Bubble mBubble;
@@ -126,6 +129,7 @@ public class BubbleExpandedView extends LinearLayout {
private BubbleController mBubbleController = Dependency.get(BubbleController.class);
private WindowManager mWindowManager;
+ private ActivityManager mActivityManager;
private BubbleStackView mStackView;
private View mVirtualImeView;
@@ -169,7 +173,8 @@ public class BubbleExpandedView extends LinearLayout {
return;
}
try {
- if (!mIsOverflow && mBubble.getShortcutInfo() != null) {
+ if (!mIsOverflow && mBubble.hasMetadataShortcutId()
+ && mBubble.getShortcutInfo() != null) {
options.setApplyActivityFlagsForBubbles(true);
mActivityView.startShortcutActivity(mBubble.getShortcutInfo(),
options, null /* sourceBounds */);
@@ -191,6 +196,10 @@ public class BubbleExpandedView extends LinearLayout {
}
});
mActivityViewStatus = ActivityViewStatus.ACTIVITY_STARTED;
+ break;
+ case ACTIVITY_STARTED:
+ post(() -> mActivityManager.moveTaskToFront(mTaskId, 0));
+ break;
}
}
@@ -252,6 +261,7 @@ public class BubbleExpandedView extends LinearLayout {
int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
updateDimensions();
+ mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
}
void updateDimensions() {
@@ -338,11 +348,9 @@ public class BubbleExpandedView extends LinearLayout {
return view.onApplyWindowInsets(insets);
});
- final int expandedViewPadding =
- res.getDimensionPixelSize(R.dimen.bubble_expanded_view_padding);
-
- setPadding(
- expandedViewPadding, expandedViewPadding, expandedViewPadding, expandedViewPadding);
+ mExpandedViewPadding = res.getDimensionPixelSize(R.dimen.bubble_expanded_view_padding);
+ setPadding(mExpandedViewPadding, mExpandedViewPadding, mExpandedViewPadding,
+ mExpandedViewPadding);
setOnTouchListener((view, motionEvent) -> {
if (!usingActivityView()) {
return false;
@@ -458,7 +466,6 @@ public class BubbleExpandedView extends LinearLayout {
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
- hideImeIfVisible();
mKeyboardVisible = false;
mNeedsNewHeight = false;
if (mActivityView != null) {
@@ -487,6 +494,11 @@ public class BubbleExpandedView extends LinearLayout {
+ " bubble=" + getBubbleKey());
}
final float alpha = visibility ? 1f : 0f;
+
+ if (alpha == mActivityView.getAlpha()) {
+ return;
+ }
+
mPointerView.setAlpha(alpha);
if (mActivityView != null) {
mActivityView.setAlpha(alpha);
@@ -604,7 +616,7 @@ public class BubbleExpandedView extends LinearLayout {
if (isNew) {
mPendingIntent = mBubble.getBubbleIntent();
- if (mPendingIntent != null || mBubble.getShortcutInfo() != null) {
+ if (mPendingIntent != null || mBubble.hasMetadataShortcutId()) {
setContentVisibility(false);
mActivityView.setVisibility(VISIBLE);
}
@@ -661,7 +673,7 @@ public class BubbleExpandedView extends LinearLayout {
desiredHeight = Math.max(mBubble.getDesiredHeight(mContext), mMinHeight);
}
float height = Math.min(desiredHeight, getMaxExpandedHeight());
- height = Math.max(height, mIsOverflow? mOverflowHeight : mMinHeight);
+ height = Math.max(height, mMinHeight);
ViewGroup.LayoutParams lp = mActivityView.getLayoutParams();
mNeedsNewHeight = lp.height != height;
if (!mKeyboardVisible) {
@@ -722,7 +734,7 @@ public class BubbleExpandedView extends LinearLayout {
*/
public void setPointerPosition(float x) {
float halfPointerWidth = mPointerWidth / 2f;
- float pointerLeft = x - halfPointerWidth;
+ float pointerLeft = x - halfPointerWidth - mExpandedViewPadding;
mPointerView.setTranslationX(pointerLeft);
mPointerView.setVisibility(VISIBLE);
}
@@ -746,11 +758,7 @@ public class BubbleExpandedView extends LinearLayout {
if (mActivityView == null) {
return;
}
- switch (mActivityViewStatus) {
- case INITIALIZED:
- case ACTIVITY_STARTED:
- mActivityView.release();
- }
+ mActivityView.release();
if (mTaskId != -1) {
try {
ActivityTaskManager.getService().removeTask(mTaskId);
@@ -780,7 +788,7 @@ public class BubbleExpandedView extends LinearLayout {
}
private boolean usingActivityView() {
- return (mPendingIntent != null || mBubble.getShortcutInfo() != null)
+ return (mPendingIntent != null || mBubble.hasMetadataShortcutId())
&& mActivityView != null;
}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleIconFactory.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleIconFactory.java
index a799f2d739e5..40a93e1cdc47 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleIconFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleIconFactory.java
@@ -23,6 +23,8 @@ import android.content.pm.LauncherApps;
import android.content.pm.ShortcutInfo;
import android.graphics.Bitmap;
import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
@@ -76,15 +78,36 @@ public class BubbleIconFactory extends BaseIconFactory {
* Returns a {@link BitmapInfo} for the app-badge that is shown on top of each bubble. This
* will include the workprofile indicator on the badge if appropriate.
*/
- BitmapInfo getBadgeBitmap(Drawable userBadgedAppIcon) {
+ BitmapInfo getBadgeBitmap(Drawable userBadgedAppIcon, boolean isImportantConversation) {
Bitmap userBadgedBitmap = createIconBitmap(
userBadgedAppIcon, 1f, getBadgeSize());
-
- Canvas c = new Canvas();
ShadowGenerator shadowGenerator = new ShadowGenerator(getBadgeSize());
- c.setBitmap(userBadgedBitmap);
- shadowGenerator.recreateIcon(Bitmap.createBitmap(userBadgedBitmap), c);
- return createIconBitmap(userBadgedBitmap);
+ if (!isImportantConversation) {
+ Canvas c = new Canvas();
+ c.setBitmap(userBadgedBitmap);
+ shadowGenerator.recreateIcon(Bitmap.createBitmap(userBadgedBitmap), c);
+ return createIconBitmap(userBadgedBitmap);
+ } else {
+ float ringStrokeWidth = mContext.getResources().getDimensionPixelSize(
+ com.android.internal.R.dimen.importance_ring_stroke_width);
+ int importantConversationColor = mContext.getResources().getColor(
+ com.android.settingslib.R.color.important_conversation, null);
+ Bitmap badgeAndRing = Bitmap.createBitmap(userBadgedBitmap.getWidth(),
+ userBadgedBitmap.getHeight(), userBadgedBitmap.getConfig());
+ Canvas c = new Canvas(badgeAndRing);
+ Rect dest = new Rect((int) ringStrokeWidth, (int) ringStrokeWidth,
+ c.getHeight() - (int) ringStrokeWidth, c.getWidth() - (int) ringStrokeWidth);
+ c.drawBitmap(userBadgedBitmap, null, dest, null);
+ Paint ringPaint = new Paint();
+ ringPaint.setStyle(Paint.Style.STROKE);
+ ringPaint.setColor(importantConversationColor);
+ ringPaint.setAntiAlias(true);
+ ringPaint.setStrokeWidth(ringStrokeWidth);
+ c.drawCircle(c.getWidth() / 2, c.getHeight() / 2, c.getWidth() / 2 - ringStrokeWidth,
+ ringPaint);
+ shadowGenerator.recreateIcon(Bitmap.createBitmap(badgeAndRing), c);
+ return createIconBitmap(badgeAndRing);
+ }
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleManageEducationView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleManageEducationView.java
index 47120124a55f..86244ba5248a 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleManageEducationView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleManageEducationView.java
@@ -20,6 +20,7 @@ import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.util.AttributeSet;
+import android.view.Gravity;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
@@ -34,6 +35,8 @@ import com.android.systemui.R;
public class BubbleManageEducationView extends LinearLayout {
private View mManageView;
+ private TextView mTitleTextView;
+ private TextView mDescTextView;
public BubbleManageEducationView(Context context) {
this(context, null);
@@ -57,6 +60,8 @@ public class BubbleManageEducationView extends LinearLayout {
super.onFinishInflate();
mManageView = findViewById(R.id.manage_education_view);
+ mTitleTextView = findViewById(R.id.user_education_title);
+ mDescTextView = findViewById(R.id.user_education_description);
final TypedArray ta = mContext.obtainStyledAttributes(
new int[] {android.R.attr.colorAccent,
@@ -66,8 +71,8 @@ public class BubbleManageEducationView extends LinearLayout {
ta.recycle();
textColor = ContrastColorUtil.ensureTextContrast(textColor, bgColor, true);
- ((TextView) findViewById(R.id.user_education_title)).setTextColor(textColor);
- ((TextView) findViewById(R.id.user_education_description)).setTextColor(textColor);
+ mTitleTextView.setTextColor(textColor);
+ mDescTextView.setTextColor(textColor);
}
/**
@@ -84,4 +89,18 @@ public class BubbleManageEducationView extends LinearLayout {
public int getManageViewHeight() {
return mManageView.getHeight();
}
+
+ @Override
+ public void setLayoutDirection(int direction) {
+ super.setLayoutDirection(direction);
+ if (getResources().getConfiguration().getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) {
+ mManageView.setBackgroundResource(R.drawable.bubble_stack_user_education_bg_rtl);
+ mTitleTextView.setGravity(Gravity.RIGHT);
+ mDescTextView.setGravity(Gravity.RIGHT);
+ } else {
+ mManageView.setBackgroundResource(R.drawable.bubble_stack_user_education_bg);
+ mTitleTextView.setGravity(Gravity.LEFT);
+ mDescTextView.setGravity(Gravity.LEFT);
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflowActivity.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflowActivity.java
index 0b25c444a8b8..9926f2ef9b64 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflowActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflowActivity.java
@@ -22,12 +22,10 @@ import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME
import android.app.Activity;
import android.content.Context;
-import android.content.pm.ShortcutInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Color;
-import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
@@ -59,6 +57,8 @@ public class BubbleOverflowActivity extends Activity {
private static final String TAG = TAG_WITH_CLASS_NAME ? "BubbleOverflowActivity" : TAG_BUBBLES;
private LinearLayout mEmptyState;
+ private TextView mEmptyStateTitle;
+ private TextView mEmptyStateSubtitle;
private ImageView mEmptyStateImage;
private BubbleController mBubbleController;
private BubbleOverflowAdapter mAdapter;
@@ -102,8 +102,10 @@ public class BubbleOverflowActivity extends Activity {
super.onCreate(savedInstanceState);
setContentView(R.layout.bubble_overflow_activity);
- mEmptyState = findViewById(R.id.bubble_overflow_empty_state);
mRecyclerView = findViewById(R.id.bubble_overflow_recycler);
+ mEmptyState = findViewById(R.id.bubble_overflow_empty_state);
+ mEmptyStateTitle = findViewById(R.id.bubble_overflow_empty_title);
+ mEmptyStateSubtitle = findViewById(R.id.bubble_overflow_empty_subtitle);
mEmptyStateImage = findViewById(R.id.bubble_overflow_empty_state_image);
updateDimensions();
@@ -143,21 +145,27 @@ public class BubbleOverflowActivity extends Activity {
void updateTheme() {
Resources res = getResources();
final int mode = res.getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
- switch (mode) {
- case Configuration.UI_MODE_NIGHT_YES:
- mEmptyStateImage.setImageDrawable(
- res.getDrawable(R.drawable.ic_empty_bubble_overflow_dark));
- findViewById(android.R.id.content)
- .setBackgroundColor(res.getColor(R.color.bubbles_dark));
- break;
-
- case Configuration.UI_MODE_NIGHT_NO:
- mEmptyStateImage.setImageDrawable(
- res.getDrawable(R.drawable.ic_empty_bubble_overflow_light));
- findViewById(android.R.id.content)
- .setBackgroundColor(res.getColor(R.color.bubbles_light));
- break;
- }
+ final boolean isNightMode = (mode == Configuration.UI_MODE_NIGHT_YES);
+
+ mEmptyStateImage.setImageDrawable(isNightMode
+ ? res.getDrawable(R.drawable.ic_empty_bubble_overflow_dark)
+ : res.getDrawable(R.drawable.ic_empty_bubble_overflow_light));
+
+ findViewById(android.R.id.content)
+ .setBackgroundColor(isNightMode
+ ? res.getColor(R.color.bubbles_dark)
+ : res.getColor(R.color.bubbles_light));
+
+ final TypedArray typedArray = getApplicationContext().obtainStyledAttributes(
+ new int[]{android.R.attr.colorBackgroundFloating,
+ android.R.attr.textColorSecondary});
+ int bgColor = typedArray.getColor(0, isNightMode ? Color.BLACK : Color.WHITE);
+ int textColor = typedArray.getColor(1, isNightMode ? Color.WHITE : Color.BLACK);
+ textColor = ContrastColorUtil.ensureTextContrast(textColor, bgColor, isNightMode);
+ typedArray.recycle();
+
+ mEmptyStateTitle.setTextColor(textColor);
+ mEmptyStateSubtitle.setTextColor(textColor);
}
void onDataChanged(List<Bubble> bubbles) {
@@ -290,18 +298,10 @@ class BubbleOverflowAdapter extends RecyclerView.Adapter<BubbleOverflowAdapter.V
}
});
- // If the bubble was persisted, the entry is null but it should have shortcut info
- ShortcutInfo info = b.getShortcutInfo();
- if (info == null) {
- Log.d(TAG, "ShortcutInfo required to bubble but none found for " + b);
- } else {
- CharSequence label = info.getLabel();
- if (label == null) {
- vh.textView.setText(b.getAppName());
- } else {
- vh.textView.setText(label.toString());
- }
- }
+ CharSequence label = b.getShortcutInfo() != null
+ ? b.getShortcutInfo().getLabel()
+ : b.getAppName();
+ vh.textView.setText(label);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
index 0e6ce5cbddb8..249783903c8e 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
@@ -70,6 +70,7 @@ import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.widget.FrameLayout;
import android.widget.ImageView;
+import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.MainThread;
@@ -144,6 +145,12 @@ public class BubbleStackView extends FrameLayout
@VisibleForTesting
static final int FLYOUT_HIDE_AFTER = 5000;
+ /**
+ * How long to wait to animate the stack temporarily invisible after a drag/flyout hide
+ * animation ends, if we are in fact temporarily invisible.
+ */
+ private static final int ANIMATE_TEMPORARILY_INVISIBLE_DELAY = 1000;
+
private static final PhysicsAnimator.SpringConfig FLYOUT_IME_ANIMATION_SPRING_CONFIG =
new PhysicsAnimator.SpringConfig(
StackAnimationController.IME_ANIMATION_STIFFNESS,
@@ -280,6 +287,9 @@ public class BubbleStackView extends FrameLayout
/** Whether or not the stack is temporarily invisible off the side of the screen. */
private boolean mTemporarilyInvisible = false;
+ /** Whether we're in the middle of dragging the stack around by touch. */
+ private boolean mIsDraggingStack = false;
+
/** Description of current animation controller state. */
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.println("Stack view state:");
@@ -374,6 +384,11 @@ public class BubbleStackView extends FrameLayout
public final Consumer<Boolean> mOnImeVisibilityChanged;
/**
+ * Callback to run to ask BubbleController to hide the current IME.
+ */
+ private final Runnable mHideCurrentInputMethodCallback;
+
+ /**
* The currently magnetized object, which is being dragged and will be attracted to the magnetic
* dismiss target.
*
@@ -477,6 +492,8 @@ public class BubbleStackView extends FrameLayout
private OnClickListener mBubbleClickListener = new OnClickListener() {
@Override
public void onClick(View view) {
+ mIsDraggingStack = false; // If the touch ended in a click, we're no longer dragging.
+
// Bubble clicks either trigger expansion/collapse or a bubble switch, both of which we
// shouldn't interrupt. These are quick transitions, so it's not worth trying to adjust
// the animations inflight.
@@ -548,7 +565,7 @@ public class BubbleStackView extends FrameLayout
mMagneticTarget,
mIndividualBubbleMagnetListener);
- hideImeFromExpandedBubble();
+ hideCurrentInputMethod();
// Save the magnetized individual bubble so we can dispatch touch events to it.
mMagnetizedObject = mExpandedAnimationController.getMagnetizedBubbleDraggingOut();
@@ -562,6 +579,12 @@ public class BubbleStackView extends FrameLayout
// Also, save the magnetized stack so we can dispatch touch events to it.
mMagnetizedObject = mStackAnimationController.getMagnetizedStack(mMagneticTarget);
mMagnetizedObject.setMagnetListener(mStackMagnetListener);
+
+ mIsDraggingStack = true;
+
+ // Cancel animations to make the stack temporarily invisible, since we're now
+ // dragging it.
+ updateTemporarilyInvisibleAnimation(false /* hideImmediately */);
}
passEventToMagnetizedObject(ev);
@@ -623,6 +646,11 @@ public class BubbleStackView extends FrameLayout
hideDismissTarget();
}
+
+ mIsDraggingStack = false;
+
+ // Hide the stack after a delay, if needed.
+ updateTemporarilyInvisibleAnimation(false /* hideImmediately */);
}
};
@@ -709,7 +737,8 @@ public class BubbleStackView extends FrameLayout
FloatingContentCoordinator floatingContentCoordinator,
SysUiState sysUiState,
Runnable allBubblesAnimatedOutAction,
- Consumer<Boolean> onImeVisibilityChanged) {
+ Consumer<Boolean> onImeVisibilityChanged,
+ Runnable hideCurrentInputMethodCallback) {
super(context);
mBubbleData = data;
@@ -845,6 +874,7 @@ public class BubbleStackView extends FrameLayout
setUpOverflow();
mOnImeVisibilityChanged = onImeVisibilityChanged;
+ mHideCurrentInputMethodCallback = hideCurrentInputMethodCallback;
setOnApplyWindowInsetsListener((View view, WindowInsets insets) -> {
onImeVisibilityChanged.accept(insets.getInsets(WindowInsets.Type.ime()).bottom > 0);
@@ -867,14 +897,7 @@ public class BubbleStackView extends FrameLayout
(v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> {
mExpandedAnimationController.updateResources(mOrientation, mDisplaySize);
mStackAnimationController.updateResources(mOrientation);
-
- // Reposition & adjust the height for new orientation
- if (mIsExpanded) {
- mExpandedViewContainer.setTranslationY(getExpandedViewY());
- if (mExpandedBubble != null && mExpandedBubble.getExpandedView() != null) {
- mExpandedBubble.getExpandedView().updateView(getLocationOnScreen());
- }
- }
+ mBubbleOverflow.updateDimensions();
// Need to update the padding around the view
WindowInsets insets = getRootWindowInsets();
@@ -898,9 +921,15 @@ public class BubbleStackView extends FrameLayout
if (mIsExpanded) {
// Re-draw bubble row and pointer for new orientation.
+ beforeExpandedViewAnimation();
+ updateOverflowVisibility();
+ updatePointerPosition();
mExpandedAnimationController.expandFromStack(() -> {
- updatePointerPosition();
+ afterExpandedViewAnimation();
} /* after */);
+ mExpandedViewContainer.setTranslationX(0);
+ mExpandedViewContainer.setTranslationY(getExpandedViewY());
+ mExpandedViewContainer.setAlpha(1f);
}
if (mVerticalPosPercentBeforeRotation >= 0) {
mStackAnimationController.moveStackToSimilarPositionAfterRotation(
@@ -966,14 +995,35 @@ public class BubbleStackView extends FrameLayout
*/
public void setTemporarilyInvisible(boolean invisible) {
mTemporarilyInvisible = invisible;
- animateTemporarilyInvisible();
+
+ // If we are animating out, hide immediately if possible so we animate out with the status
+ // bar.
+ updateTemporarilyInvisibleAnimation(invisible /* hideImmediately */);
}
/**
- * Animates onto or off the screen depending on whether we're temporarily invisible, and whether
- * a flyout is visible.
+ * Animates the stack to be temporarily invisible, if needed.
+ *
+ * If we're currently dragging the stack, or a flyout is visible, the stack will remain visible.
+ * regardless of the value of {@link #mTemporarilyInvisible}. This method is called on ACTION_UP
+ * as well as whenever a flyout hides, so we will animate invisible at that point if needed.
*/
- private void animateTemporarilyInvisible() {
+ private void updateTemporarilyInvisibleAnimation(boolean hideImmediately) {
+ removeCallbacks(mAnimateTemporarilyInvisibleImmediate);
+
+ if (mIsDraggingStack) {
+ // If we're dragging the stack, don't animate it invisible.
+ return;
+ }
+
+ final boolean shouldHide =
+ mTemporarilyInvisible && mFlyout.getVisibility() != View.VISIBLE;
+
+ postDelayed(mAnimateTemporarilyInvisibleImmediate,
+ shouldHide && !hideImmediately ? ANIMATE_TEMPORARILY_INVISIBLE_DELAY : 0);
+ }
+
+ private final Runnable mAnimateTemporarilyInvisibleImmediate = () -> {
if (mTemporarilyInvisible && mFlyout.getVisibility() != View.VISIBLE) {
if (mStackAnimationController.isStackOnLeftSide()) {
animate().translationX(-mBubbleSize).start();
@@ -983,7 +1033,7 @@ public class BubbleStackView extends FrameLayout
} else {
animate().translationX(0).start();
}
- }
+ };
private void setUpManageMenu() {
if (mManageMenu != null) {
@@ -1023,10 +1073,8 @@ public class BubbleStackView extends FrameLayout
if (bubble != null && mBubbleData.hasBubbleInStackWithKey(bubble.getKey())) {
final Intent intent = bubble.getSettingsIntent(mContext);
collapseStack(() -> {
-
mContext.startActivityAsUser(intent, bubble.getUser());
- logBubbleClickEvent(
- bubble,
+ logBubbleEvent(bubble,
SysUiStatsLog.BUBBLE_UICHANGED__ACTION__HEADER_GO_TO_SETTINGS);
});
}
@@ -1066,6 +1114,7 @@ public class BubbleStackView extends FrameLayout
title.setTextColor(textColor);
description.setTextColor(textColor);
+ updateUserEducationForLayoutDirection();
addView(mUserEducationView);
}
@@ -1082,7 +1131,7 @@ public class BubbleStackView extends FrameLayout
false /* attachToRoot */);
mManageEducationView.setVisibility(GONE);
mManageEducationView.setElevation(mBubbleElevation);
-
+ mManageEducationView.setLayoutDirection(View.LAYOUT_DIRECTION_LOCALE);
addView(mManageEducationView);
}
}
@@ -1164,13 +1213,17 @@ public class BubbleStackView extends FrameLayout
}
/** Tells the views with locale-dependent layout direction to resolve the new direction. */
- public void onLayoutDirectionChanged() {
- mManageMenu.resolveLayoutDirection();
- mFlyout.resolveLayoutDirection();
-
- if (mExpandedBubble != null && mExpandedBubble.getExpandedView() != null) {
- mExpandedBubble.getExpandedView().resolveLayoutDirection();
+ public void onLayoutDirectionChanged(int direction) {
+ mManageMenu.setLayoutDirection(direction);
+ mFlyout.setLayoutDirection(direction);
+ if (mUserEducationView != null) {
+ mUserEducationView.setLayoutDirection(direction);
+ updateUserEducationForLayoutDirection();
}
+ if (mManageEducationView != null) {
+ mManageEducationView.setLayoutDirection(direction);
+ }
+ updateExpandedViewDirection(direction);
}
/** Respond to the display size change by recalculating view size and location. */
@@ -1245,6 +1298,18 @@ public class BubbleStackView extends FrameLayout
});
}
+ void updateExpandedViewDirection(int direction) {
+ final List<Bubble> bubbles = mBubbleData.getBubbles();
+ if (bubbles.isEmpty()) {
+ return;
+ }
+ bubbles.forEach(bubble -> {
+ if (bubble.getExpandedView() != null) {
+ bubble.getExpandedView().setLayoutDirection(direction);
+ }
+ });
+ }
+
void setupLocalMenu(AccessibilityNodeInfo info) {
Resources res = mContext.getResources();
@@ -1446,6 +1511,7 @@ public class BubbleStackView extends FrameLayout
&& ((BadgedImageView) v).getKey().equals(bubble.getKey())) {
mBubbleContainer.removeViewAt(i);
bubble.cleanupViews();
+ updatePointerPosition();
logBubbleEvent(bubble, SysUiStatsLog.BUBBLE_UICHANGED__ACTION__DISMISSED);
return;
}
@@ -1496,6 +1562,14 @@ public class BubbleStackView extends FrameLayout
mBubbleData.setShowingOverflow(true);
}
+ if (mIsExpanded && mIsExpansionAnimating) {
+ // If the bubble selection changed during the expansion animation, the expanding bubble
+ // probably crashed or immediately removed itself (or, we just got unlucky with a new
+ // auto-expanding bubble showing up at just the right time). Cancel the animations so we
+ // can start fresh.
+ cancelAllExpandCollapseSwitchAnimations();
+ }
+
// If we're expanded, screenshot the currently expanded bubble (before expanding the newly
// selected bubble) so we can animate it out.
if (mIsExpanded && mExpandedBubble != null && mExpandedBubble.getExpandedView() != null) {
@@ -1526,6 +1600,8 @@ public class BubbleStackView extends FrameLayout
updatePointerPosition();
if (mIsExpanded) {
+ hideCurrentInputMethod();
+
// Make the container of the expanded view transparent before removing the expanded view
// from it. Otherwise a punch hole created by {@link android.view.SurfaceView} in the
// expanded view becomes visible on the screen. See b/126856255
@@ -1534,11 +1610,6 @@ public class BubbleStackView extends FrameLayout
if (previouslySelected != null) {
previouslySelected.setContentVisibility(false);
}
- if (previouslySelected != null && previouslySelected.getExpandedView() != null) {
- // Hide the currently expanded bubble's IME if it's visible before switching
- // to a new bubble.
- previouslySelected.getExpandedView().hideImeIfVisible();
- }
updateExpandedBubble();
requestUpdate();
@@ -1566,6 +1637,8 @@ public class BubbleStackView extends FrameLayout
return;
}
+ hideCurrentInputMethod();
+
mSysUiState
.setFlag(QuickStepContract.SYSUI_STATE_BUBBLES_EXPANDED, shouldExpand)
.commitUpdate(mContext.getDisplayId());
@@ -1592,6 +1665,8 @@ public class BubbleStackView extends FrameLayout
if (mShouldShowUserEducation && mUserEducationView.getVisibility() != VISIBLE) {
mUserEducationView.setAlpha(0);
mUserEducationView.setVisibility(VISIBLE);
+ updateUserEducationForLayoutDirection();
+
// Post so we have height of mUserEducationView
mUserEducationView.post(() -> {
final int viewHeight = mUserEducationView.getHeight();
@@ -1609,6 +1684,28 @@ public class BubbleStackView extends FrameLayout
return false;
}
+ private void updateUserEducationForLayoutDirection() {
+ if (mUserEducationView == null) {
+ return;
+ }
+ LinearLayout textLayout = mUserEducationView.findViewById(R.id.user_education_view);
+ TextView title = mUserEducationView.findViewById(R.id.user_education_title);
+ TextView description = mUserEducationView.findViewById(R.id.user_education_description);
+ boolean isLtr =
+ getResources().getConfiguration().getLayoutDirection() == LAYOUT_DIRECTION_LTR;
+ if (isLtr) {
+ mUserEducationView.setLayoutDirection(LAYOUT_DIRECTION_LTR);
+ textLayout.setBackgroundResource(R.drawable.bubble_stack_user_education_bg);
+ title.setGravity(Gravity.LEFT);
+ description.setGravity(Gravity.LEFT);
+ } else {
+ mUserEducationView.setLayoutDirection(LAYOUT_DIRECTION_RTL);
+ textLayout.setBackgroundResource(R.drawable.bubble_stack_user_education_bg_rtl);
+ title.setGravity(Gravity.RIGHT);
+ description.setGravity(Gravity.RIGHT);
+ }
+ }
+
/**
* If necessary, hides the user education view for the bubble stack.
*
@@ -1725,12 +1822,12 @@ public class BubbleStackView extends FrameLayout
}
}
- void hideImeFromExpandedBubble() {
- if (mExpandedBubble != null && mExpandedBubble.getExpandedView() != null) {
- // Hide the currently expanded bubble's IME if it's visible before switching to a new
- // bubble.
- mExpandedBubble.getExpandedView().hideImeIfVisible();
- }
+ /**
+ * Asks the BubbleController to hide the IME from anywhere, whether it's focused on Bubbles or
+ * not.
+ */
+ void hideCurrentInputMethod() {
+ mHideCurrentInputMethodCallback.run();
}
private void beforeExpandedViewAnimation() {
@@ -1797,33 +1894,37 @@ public class BubbleStackView extends FrameLayout
mExpandedBubble.getExpandedView().setSurfaceZOrderedOnTop(false);
}
- mDelayedAnimationHandler.postDelayed(() ->
- PhysicsAnimator.getInstance(mExpandedViewContainerMatrix)
- .spring(AnimatableScaleMatrix.SCALE_X,
- AnimatableScaleMatrix.getAnimatableValueForScaleFactor(1f),
- mScaleInSpringConfig)
- .spring(AnimatableScaleMatrix.SCALE_Y,
- AnimatableScaleMatrix.getAnimatableValueForScaleFactor(1f),
- mScaleInSpringConfig)
- .addUpdateListener((target, values) -> {
- if (mExpandedBubble.getIconView() == null) {
- return;
- }
- mExpandedViewContainerMatrix.postTranslate(
- mExpandedBubble.getIconView().getTranslationX()
- - bubbleWillBeAtX,
- 0);
- mExpandedViewContainer.setAnimationMatrix(
- mExpandedViewContainerMatrix);
- })
- .withEndActions(() -> {
- if (mExpandedBubble != null
- && mExpandedBubble.getExpandedView() != null) {
- mExpandedBubble.getExpandedView()
- .setSurfaceZOrderedOnTop(false);
- }
- })
- .start(), startDelay);
+ mDelayedAnimationHandler.postDelayed(() -> {
+ PhysicsAnimator.getInstance(mExpandedViewContainerMatrix).cancel();
+ PhysicsAnimator.getInstance(mExpandedViewContainerMatrix)
+ .spring(AnimatableScaleMatrix.SCALE_X,
+ AnimatableScaleMatrix.getAnimatableValueForScaleFactor(1f),
+ mScaleInSpringConfig)
+ .spring(AnimatableScaleMatrix.SCALE_Y,
+ AnimatableScaleMatrix.getAnimatableValueForScaleFactor(1f),
+ mScaleInSpringConfig)
+ .addUpdateListener((target, values) -> {
+ if (mExpandedBubble.getIconView() == null) {
+ return;
+ }
+ mExpandedViewContainerMatrix.postTranslate(
+ mExpandedBubble.getIconView().getTranslationX()
+ - bubbleWillBeAtX,
+ 0);
+ mExpandedViewContainer.setAnimationMatrix(
+ mExpandedViewContainerMatrix);
+ })
+ .withEndActions(() -> {
+ if (mExpandedBubble != null
+ && mExpandedBubble.getExpandedView() != null) {
+ mExpandedBubble.getExpandedView()
+ .setContentVisibility(true);
+ mExpandedBubble.getExpandedView()
+ .setSurfaceZOrderedOnTop(false);
+ }
+ })
+ .start();
+ }, startDelay);
}
private void animateCollapse() {
@@ -1843,10 +1944,6 @@ public class BubbleStackView extends FrameLayout
mAnimatingOutSurfaceContainer.setScaleX(0f);
mAnimatingOutSurfaceContainer.setScaleY(0f);
- if (mExpandedBubble != null && mExpandedBubble.getExpandedView() != null) {
- mExpandedBubble.getExpandedView().hideImeIfVisible();
- }
-
// Let the expanded animation controller know that it shouldn't animate child adds/reorders
// since we're about to animate collapsed.
mExpandedAnimationController.notifyPreparingToCollapse();
@@ -1905,7 +2002,9 @@ public class BubbleStackView extends FrameLayout
updateOverflowVisibility();
afterExpandedViewAnimation();
- previouslySelected.setContentVisibility(false);
+ if (previouslySelected != null) {
+ previouslySelected.setContentVisibility(false);
+ }
})
.start();
}
@@ -1949,6 +2048,7 @@ public class BubbleStackView extends FrameLayout
return;
}
+ PhysicsAnimator.getInstance(mExpandedViewContainerMatrix).cancel();
PhysicsAnimator.getInstance(mExpandedViewContainerMatrix)
.spring(AnimatableScaleMatrix.SCALE_X,
AnimatableScaleMatrix.getAnimatableValueForScaleFactor(1f),
@@ -1961,6 +2061,7 @@ public class BubbleStackView extends FrameLayout
})
.withEndActions(() -> {
if (mExpandedBubble != null && mExpandedBubble.getExpandedView() != null) {
+ mExpandedBubble.getExpandedView().setContentVisibility(true);
mExpandedBubble.getExpandedView().setSurfaceZOrderedOnTop(false);
}
@@ -1981,6 +2082,15 @@ public class BubbleStackView extends FrameLayout
mIsBubbleSwitchAnimating = false;
}
+ private void cancelAllExpandCollapseSwitchAnimations() {
+ cancelDelayedExpandCollapseSwitchAnimations();
+
+ PhysicsAnimator.getInstance(mAnimatingOutSurfaceView).cancel();
+ PhysicsAnimator.getInstance(mExpandedViewContainerMatrix).cancel();
+
+ mExpandedViewContainer.setAnimationMatrix(null);
+ }
+
private void notifyExpansionChanged(BubbleViewProvider bubble, boolean expanded) {
if (mExpandListener != null && bubble != null) {
mExpandListener.onBubbleExpandChanged(expanded, bubble.getKey());
@@ -2145,7 +2255,7 @@ public class BubbleStackView extends FrameLayout
private void dismissBubbleIfExists(@Nullable Bubble bubble) {
if (bubble != null && mBubbleData.hasBubbleInStackWithKey(bubble.getKey())) {
- mBubbleData.notificationEntryRemoved(
+ mBubbleData.dismissBubbleWithKey(
bubble.getKey(), BubbleController.DISMISS_USER_GESTURE);
}
}
@@ -2297,7 +2407,9 @@ public class BubbleStackView extends FrameLayout
BadgedImageView.SuppressionFlag.FLYOUT_VISIBLE);
mFlyout.setVisibility(INVISIBLE);
- animateTemporarilyInvisible();
+
+ // Hide the stack after a delay, if needed.
+ updateTemporarilyInvisibleAnimation(false /* hideImmediately */);
};
mFlyout.setVisibility(INVISIBLE);
@@ -2315,7 +2427,7 @@ public class BubbleStackView extends FrameLayout
final Runnable expandFlyoutAfterDelay = () -> {
mAnimateInFlyout = () -> {
mFlyout.setVisibility(VISIBLE);
- animateTemporarilyInvisible();
+ updateTemporarilyInvisibleAnimation(false /* hideImmediately */);
mFlyoutDragDeltaX =
mStackAnimationController.isStackOnLeftSide()
? -mFlyout.getWidth()
@@ -2464,6 +2576,10 @@ public class BubbleStackView extends FrameLayout
.spring(DynamicAnimation.SCALE_Y, 1f)
.spring(DynamicAnimation.TRANSLATION_X, targetX)
.spring(DynamicAnimation.TRANSLATION_Y, targetY)
+ .withEndActions(() -> {
+ View child = mManageMenu.getChildAt(0);
+ child.requestAccessibilityFocus();
+ })
.start();
mManageMenu.setVisibility(View.VISIBLE);
@@ -2494,6 +2610,7 @@ public class BubbleStackView extends FrameLayout
bev.setContentVisibility(false);
mExpandedViewContainerMatrix.setScaleX(0f);
mExpandedViewContainerMatrix.setScaleY(0f);
+ mExpandedViewContainerMatrix.setTranslate(0f, 0f);
mExpandedViewContainer.setVisibility(View.INVISIBLE);
mExpandedViewContainer.setAlpha(0f);
mExpandedViewContainer.addView(bev);
@@ -2707,16 +2824,28 @@ public class BubbleStackView extends FrameLayout
/**
* Logs the bubble UI event.
*
- * @param bubble the bubble that is being interacted on. Null value indicates that
- * the user interaction is not specific to one bubble.
+ * @param provider the bubble view provider that is being interacted on. Null value indicates
+ * that the user interaction is not specific to one bubble.
* @param action the user interaction enum.
*/
- private void logBubbleEvent(@Nullable BubbleViewProvider bubble, int action) {
- if (bubble == null) {
+ private void logBubbleEvent(@Nullable BubbleViewProvider provider, int action) {
+ if (provider == null || provider.getKey().equals(BubbleOverflow.KEY)) {
+ SysUiStatsLog.write(SysUiStatsLog.BUBBLE_UI_CHANGED,
+ mContext.getApplicationInfo().packageName,
+ provider == null ? null : BubbleOverflow.KEY /* notification channel */,
+ 0 /* notification ID */,
+ 0 /* bubble position */,
+ getBubbleCount(),
+ action,
+ getNormalizedXPosition(),
+ getNormalizedYPosition(),
+ false /* unread bubble */,
+ false /* on-going bubble */,
+ false /* isAppForeground (unused) */);
return;
}
- bubble.logUIEvent(getBubbleCount(), action, getNormalizedXPosition(),
- getNormalizedYPosition(), getBubbleIndex(bubble));
+ provider.logUIEvent(getBubbleCount(), action, getNormalizedXPosition(),
+ getNormalizedYPosition(), getBubbleIndex(provider));
}
/**
@@ -2755,20 +2884,4 @@ public class BubbleStackView extends FrameLayout
}
return bubbles;
}
-
- /**
- * Logs bubble UI click event.
- *
- * @param bubble the bubble notification entry that user is interacting with.
- * @param action the user interaction enum.
- */
- private void logBubbleClickEvent(Bubble bubble, int action) {
- bubble.logUIEvent(
- getBubbleCount(),
- action,
- getNormalizedXPosition(),
- getNormalizedYPosition(),
- getBubbleIndex(getExpandedBubble())
- );
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleViewInfoTask.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleViewInfoTask.java
index 3e4ff5262bbd..1929fc4e9dbf 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleViewInfoTask.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleViewInfoTask.java
@@ -176,7 +176,8 @@ public class BubbleViewInfoTask extends AsyncTask<Void, Void, BubbleViewInfoTask
bubbleDrawable = appIcon;
}
- BitmapInfo badgeBitmapInfo = iconFactory.getBadgeBitmap(badgedIcon);
+ BitmapInfo badgeBitmapInfo = iconFactory.getBadgeBitmap(badgedIcon,
+ b.isImportantConversation());
info.badgedAppIcon = badgedIcon;
info.badgedBubbleImage = iconFactory.getBubbleBitmap(bubbleDrawable,
badgeBitmapInfo).icon;
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/animation/AnimatableScaleMatrix.java b/packages/SystemUI/src/com/android/systemui/bubbles/animation/AnimatableScaleMatrix.java
index ae7833634794..07acb710c6d7 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/animation/AnimatableScaleMatrix.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/animation/AnimatableScaleMatrix.java
@@ -134,4 +134,11 @@ public class AnimatableScaleMatrix extends Matrix {
public float getPivotY() {
return mPivotY;
}
+
+ @Override
+ public boolean equals(Object obj) {
+ // Use object equality to allow this matrix to be used as a map key (which is required for
+ // PhysicsAnimator's animator caching).
+ return obj == this;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java b/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java
index cb8995a72dc3..f2a4f159f959 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java
@@ -203,12 +203,22 @@ public class ExpandedAnimationController
public void updateResources(int orientation, Point displaySize) {
mScreenOrientation = orientation;
mDisplaySize = displaySize;
- if (mLayout != null) {
- Resources res = mLayout.getContext().getResources();
- mBubblePaddingTop = res.getDimensionPixelSize(R.dimen.bubble_padding_top);
- mStatusBarHeight = res.getDimensionPixelSize(
- com.android.internal.R.dimen.status_bar_height);
+ if (mLayout == null) {
+ return;
}
+ Resources res = mLayout.getContext().getResources();
+ mBubblePaddingTop = res.getDimensionPixelSize(R.dimen.bubble_padding_top);
+ mStatusBarHeight = res.getDimensionPixelSize(
+ com.android.internal.R.dimen.status_bar_height);
+ mStackOffsetPx = res.getDimensionPixelSize(R.dimen.bubble_stack_offset);
+ mBubblePaddingTop = res.getDimensionPixelSize(R.dimen.bubble_padding_top);
+ mBubbleSizePx = res.getDimensionPixelSize(R.dimen.individual_bubble_size);
+ mBubblesMaxRendered = res.getInteger(R.integer.bubbles_max_rendered);
+
+ // Includes overflow button.
+ float totalGapWidth = getWidthForDisplayingBubbles() - (mExpandedViewPadding * 2)
+ - (mBubblesMaxRendered + 1) * mBubbleSizePx;
+ mSpaceBetweenBubbles = totalGapWidth / mBubblesMaxRendered;
}
/**
@@ -227,6 +237,10 @@ public class ExpandedAnimationController
}
mAfterExpand = null;
+
+ // Update bubble positions in case any bubbles were added or removed during the
+ // expansion animation.
+ updateBubblePositions();
};
} else {
after = () -> {
@@ -464,18 +478,7 @@ public class ExpandedAnimationController
@Override
void onActiveControllerForLayout(PhysicsAnimationLayout layout) {
- final Resources res = layout.getResources();
- mStackOffsetPx = res.getDimensionPixelSize(R.dimen.bubble_stack_offset);
- mBubblePaddingTop = res.getDimensionPixelSize(R.dimen.bubble_padding_top);
- mBubbleSizePx = res.getDimensionPixelSize(R.dimen.individual_bubble_size);
- mStatusBarHeight =
- res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
- mBubblesMaxRendered = res.getInteger(R.integer.bubbles_max_rendered);
-
- // Includes overflow button.
- float totalGapWidth = getWidthForDisplayingBubbles() - (mExpandedViewPadding * 2)
- - (mBubblesMaxRendered + 1) * mBubbleSizePx;
- mSpaceBetweenBubbles = totalGapWidth / mBubblesMaxRendered;
+ updateResources(mScreenOrientation, mDisplaySize);
// Ensure that all child views are at 1x scale, and visible, in case they were animating
// in.
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java b/packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java
index 3ef20444cb52..b378469c4c98 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java
@@ -940,8 +940,12 @@ public class StackAnimationController extends
/** Returns the default stack position, which is on the top left. */
public PointF getDefaultStartPosition() {
- return new PointF(
- getAllowableStackPositionRegion().left,
+ boolean isRtl = mLayout != null
+ && mLayout.getResources().getConfiguration().getLayoutDirection()
+ == View.LAYOUT_DIRECTION_RTL;
+ return new PointF(isRtl
+ ? getAllowableStackPositionRegion().right
+ : getAllowableStackPositionRegion().left,
getAllowableStackPositionRegion().top + mStackStartingVerticalOffset);
}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/dagger/BubbleModule.java b/packages/SystemUI/src/com/android/systemui/bubbles/dagger/BubbleModule.java
index 097932e5f447..10d301d0fa93 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/dagger/BubbleModule.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/dagger/BubbleModule.java
@@ -18,6 +18,7 @@ package com.android.systemui.bubbles.dagger;
import android.app.INotificationManager;
import android.content.Context;
+import android.content.pm.LauncherApps;
import android.view.WindowManager;
import com.android.internal.statusbar.IStatusBarService;
@@ -72,7 +73,8 @@ public interface BubbleModule {
SysUiState sysUiState,
INotificationManager notifManager,
IStatusBarService statusBarService,
- WindowManager windowManager) {
+ WindowManager windowManager,
+ LauncherApps launcherApps) {
return new BubbleController(
context,
notificationShadeWindowController,
@@ -94,6 +96,7 @@ public interface BubbleModule {
sysUiState,
notifManager,
statusBarService,
- windowManager);
+ windowManager,
+ launcherApps);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/storage/BubbleVolatileRepository.kt b/packages/SystemUI/src/com/android/systemui/bubbles/storage/BubbleVolatileRepository.kt
index bdeb714b568c..894970f903ac 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/storage/BubbleVolatileRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/storage/BubbleVolatileRepository.kt
@@ -60,7 +60,8 @@ class BubbleVolatileRepository @Inject constructor(
// Verify the size of given bubbles is within capacity, otherwise trim down to capacity
val bubblesInRange = bubbles.takeLast(capacity)
// To ensure natural ordering of the bubbles, removes bubbles which already exist
- val uniqueBubbles = bubblesInRange.filterNot { entities.remove(it) }
+ val uniqueBubbles = bubblesInRange.filterNot { b: BubbleEntity ->
+ entities.removeIf { e: BubbleEntity -> b.key == e.key } }
val overflowCount = entities.size + bubblesInRange.size - capacity
if (overflowCount > 0) {
// Uncache ShortcutInfo of bubbles that will be removed due to capacity
@@ -72,7 +73,9 @@ class BubbleVolatileRepository @Inject constructor(
}
@Synchronized
- fun removeBubbles(bubbles: List<BubbleEntity>) = uncache(bubbles.filter { entities.remove(it) })
+ fun removeBubbles(bubbles: List<BubbleEntity>) =
+ uncache(bubbles.filter { b: BubbleEntity ->
+ entities.removeIf { e: BubbleEntity -> b.key == e.key } })
private fun cache(bubbles: List<BubbleEntity>) {
bubbles.groupBy { ShortcutKey(it.userId, it.packageName) }.forEach { (key, bubbles) ->
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/storage/BubbleXmlHelper.kt b/packages/SystemUI/src/com/android/systemui/bubbles/storage/BubbleXmlHelper.kt
index 66fff3386ae1..bf163a230aff 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/storage/BubbleXmlHelper.kt
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/storage/BubbleXmlHelper.kt
@@ -25,7 +25,11 @@ import java.io.InputStream
import java.io.OutputStream
import java.nio.charset.StandardCharsets
+// TODO: handle version changes gracefully
+private const val CURRENT_VERSION = 1
+
private const val TAG_BUBBLES = "bs"
+private const val ATTR_VERSION = "v"
private const val TAG_BUBBLE = "bb"
private const val ATTR_USER_ID = "uid"
private const val ATTR_PACKAGE = "pkg"
@@ -44,6 +48,7 @@ fun writeXml(stream: OutputStream, bubbles: List<BubbleEntity>) {
serializer.setOutput(stream, StandardCharsets.UTF_8.name())
serializer.startDocument(null, true)
serializer.startTag(null, TAG_BUBBLES)
+ serializer.attribute(null, ATTR_VERSION, CURRENT_VERSION.toString())
bubbles.forEach { b -> writeXmlEntry(serializer, b) }
serializer.endTag(null, TAG_BUBBLES)
serializer.endDocument()
@@ -79,9 +84,12 @@ fun readXml(stream: InputStream): List<BubbleEntity> {
val parser: XmlPullParser = Xml.newPullParser()
parser.setInput(stream, StandardCharsets.UTF_8.name())
XmlUtils.beginDocument(parser, TAG_BUBBLES)
- val outerDepth = parser.depth
- while (XmlUtils.nextElementWithin(parser, outerDepth)) {
- bubbles.add(readXmlEntry(parser) ?: continue)
+ val version = parser.getAttributeWithName(ATTR_VERSION)?.toInt()
+ if (version != null && version == CURRENT_VERSION) {
+ val outerDepth = parser.depth
+ while (XmlUtils.nextElementWithin(parser, outerDepth)) {
+ bubbles.add(readXmlEntry(parser) ?: continue)
+ }
}
return bubbles
}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerFake.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerFake.java
index e105795ad57f..646e62062dfb 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerFake.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerFake.java
@@ -201,7 +201,7 @@ public class FalsingManagerFake implements FalsingManager {
}
@Override
- public void onNotificatonStopDismissing() {
+ public void onNotificationStopDismissing() {
}
@@ -211,7 +211,7 @@ public class FalsingManagerFake implements FalsingManager {
}
@Override
- public void onNotificatonStartDismissing() {
+ public void onNotificationStartDismissing() {
}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerImpl.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerImpl.java
index 37c7a2e3027f..cc64fb53f15f 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerImpl.java
@@ -481,15 +481,15 @@ public class FalsingManagerImpl implements FalsingManager {
mDataCollector.onNotificationDismissed();
}
- public void onNotificatonStartDismissing() {
+ public void onNotificationStartDismissing() {
if (FalsingLog.ENABLED) {
- FalsingLog.i("onNotificatonStartDismissing", "");
+ FalsingLog.i("onNotificationStartDismissing", "");
}
mHumanInteractionClassifier.setType(Classifier.NOTIFICATION_DISMISS);
mDataCollector.onNotificatonStartDismissing();
}
- public void onNotificatonStopDismissing() {
+ public void onNotificationStopDismissing() {
mDataCollector.onNotificatonStopDismissing();
}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java
index 79b691bb3e37..ef2ef4570fca 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java
@@ -302,8 +302,8 @@ public class FalsingManagerProxy implements FalsingManager, Dumpable {
}
@Override
- public void onNotificatonStopDismissing() {
- mInternalFalsingManager.onNotificatonStopDismissing();
+ public void onNotificationStopDismissing() {
+ mInternalFalsingManager.onNotificationStopDismissing();
}
@Override
@@ -312,8 +312,8 @@ public class FalsingManagerProxy implements FalsingManager, Dumpable {
}
@Override
- public void onNotificatonStartDismissing() {
- mInternalFalsingManager.onNotificatonStartDismissing();
+ public void onNotificationStartDismissing() {
+ mInternalFalsingManager.onNotificationStartDismissing();
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/BrightLineFalsingManager.java b/packages/SystemUI/src/com/android/systemui/classifier/brightline/BrightLineFalsingManager.java
index caab18712b0b..62254a64dfcc 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/brightline/BrightLineFalsingManager.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/brightline/BrightLineFalsingManager.java
@@ -380,7 +380,7 @@ public class BrightLineFalsingManager implements FalsingManager {
@Override
- public void onNotificatonStopDismissing() {
+ public void onNotificationStopDismissing() {
}
@Override
@@ -388,7 +388,7 @@ public class BrightLineFalsingManager implements FalsingManager {
}
@Override
- public void onNotificatonStartDismissing() {
+ public void onNotificationStartDismissing() {
updateInteractionType(Classifier.NOTIFICATION_DISMISS);
}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ControlStatus.kt b/packages/SystemUI/src/com/android/systemui/controls/ControlStatus.kt
index 5891a7f705c8..f0356d038065 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ControlStatus.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ControlStatus.kt
@@ -17,6 +17,7 @@
package com.android.systemui.controls
import android.content.ComponentName
+import android.graphics.drawable.Icon
import android.service.controls.Control
import android.service.controls.DeviceTypes
@@ -28,6 +29,7 @@ interface ControlInterface {
val subtitle: CharSequence
val removed: Boolean
get() = false
+ val customIcon: Icon?
@DeviceTypes.DeviceType val deviceType: Int
}
@@ -46,6 +48,9 @@ data class ControlStatus(
override val subtitle: CharSequence
get() = control.subtitle
+ override val customIcon: Icon?
+ get() = control.customIcon
+
@DeviceTypes.DeviceType override val deviceType: Int
get() = control.deviceType
}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManager.kt b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManager.kt
index a6af6a11d8b7..ec8bfc6fa2ae 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManager.kt
@@ -73,7 +73,7 @@ class ControlsProviderLifecycleManager(
companion object {
private const val BIND_RETRY_DELAY = 1000L // ms
- private const val LOAD_TIMEOUT_SECONDS = 30L // seconds
+ private const val LOAD_TIMEOUT_SECONDS = 20L // seconds
private const val MAX_BIND_RETRIES = 5
private const val DEBUG = true
private val BIND_FLAGS = Context.BIND_AUTO_CREATE or Context.BIND_FOREGROUND_SERVICE
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt
index 26124f7f3285..c683a87d6282 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt
@@ -238,7 +238,7 @@ internal class ControlHolder(
updateFavorite(!favorite.isChecked)
favoriteCallback(wrapper.controlId, favorite.isChecked)
}
- applyRenderInfo(renderInfo)
+ applyRenderInfo(renderInfo, wrapper)
}
override fun updateFavorite(favorite: Boolean) {
@@ -254,12 +254,20 @@ internal class ControlHolder(
return RenderInfo.lookup(itemView.context, component, deviceType)
}
- private fun applyRenderInfo(ri: RenderInfo) {
+ private fun applyRenderInfo(ri: RenderInfo, ci: ControlInterface) {
val context = itemView.context
val fg = context.getResources().getColorStateList(ri.foreground, context.getTheme())
- icon.setImageDrawable(ri.icon)
- icon.setImageTintList(fg)
+ ci.customIcon?.let {
+ icon.setImageIcon(it)
+ } ?: run {
+ icon.setImageDrawable(ri.icon)
+
+ // Do not color app icons
+ if (ci.deviceType != DeviceTypes.TYPE_ROUTINE) {
+ icon.setImageTintList(fg)
+ }
+ }
}
}
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 496b21b612fe..b2821579c389 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt
@@ -79,6 +79,7 @@ class ControlsFavoritingActivity @Inject constructor(
private lateinit var structurePager: ViewPager2
private lateinit var statusText: TextView
private lateinit var titleView: TextView
+ private lateinit var subtitleView: TextView
private lateinit var pageIndicator: ManagementPageIndicator
private var mTooltipManager: TooltipManager? = null
private lateinit var doneButton: View
@@ -165,33 +166,40 @@ class ControlsFavoritingActivity @Inject constructor(
structurePager.adapter = StructureAdapter(listOfStructures)
structurePager.setCurrentItem(structureIndex)
if (error) {
- statusText.text = resources.getText(R.string.controls_favorite_load_error)
+ statusText.text = resources.getString(R.string.controls_favorite_load_error,
+ appName ?: "")
+ subtitleView.visibility = View.GONE
+ } else if (listOfStructures.isEmpty()) {
+ statusText.text = resources.getString(R.string.controls_favorite_load_none)
+ subtitleView.visibility = View.GONE
} else {
statusText.visibility = View.GONE
- }
- pageIndicator.setNumPages(listOfStructures.size)
- pageIndicator.setLocation(0f)
- pageIndicator.visibility =
- if (listOfStructures.size > 1) View.VISIBLE else View.INVISIBLE
-
- ControlsAnimations.enterAnimation(pageIndicator).apply {
- addListener(object : AnimatorListenerAdapter() {
- override fun onAnimationEnd(animation: Animator?) {
- // Position the tooltip if necessary after animations are complete
- // so we can get the position on screen. The tooltip is not
- // rooted in the layout root.
- if (pageIndicator.visibility == View.VISIBLE &&
+
+ pageIndicator.setNumPages(listOfStructures.size)
+ pageIndicator.setLocation(0f)
+ pageIndicator.visibility =
+ if (listOfStructures.size > 1) View.VISIBLE else View.INVISIBLE
+
+ ControlsAnimations.enterAnimation(pageIndicator).apply {
+ addListener(object : AnimatorListenerAdapter() {
+ override fun onAnimationEnd(animation: Animator?) {
+ // Position the tooltip if necessary after animations are complete
+ // so we can get the position on screen. The tooltip is not
+ // rooted in the layout root.
+ if (pageIndicator.visibility == View.VISIBLE &&
mTooltipManager != null) {
- val p = IntArray(2)
- pageIndicator.getLocationOnScreen(p)
- val x = p[0] + pageIndicator.width / 2
- val y = p[1] + pageIndicator.height
- mTooltipManager?.show(R.string.controls_structure_tooltip, x, y)
+ val p = IntArray(2)
+ pageIndicator.getLocationOnScreen(p)
+ val x = p[0] + pageIndicator.width / 2
+ val y = p[1] + pageIndicator.height
+ mTooltipManager?.show(
+ R.string.controls_structure_tooltip, x, y)
+ }
}
- }
- })
- }.start()
- ControlsAnimations.enterAnimation(structurePager).start()
+ })
+ }.start()
+ ControlsAnimations.enterAnimation(structurePager).start()
+ }
}
}, Consumer { runnable -> cancelLoadRunnable = runnable })
}
@@ -266,8 +274,9 @@ class ControlsFavoritingActivity @Inject constructor(
titleView = requireViewById<TextView>(R.id.title).apply {
text = title
}
- requireViewById<TextView>(R.id.subtitle).text =
- resources.getText(R.string.controls_favorite_subtitle)
+ subtitleView = requireViewById<TextView>(R.id.subtitle).apply {
+ text = resources.getText(R.string.controls_favorite_subtitle)
+ }
structurePager = requireViewById<ViewPager2>(R.id.structure_pager)
structurePager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
override fun onPageSelected(position: Int) {
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsModel.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsModel.kt
index 254395368bf9..4ef64a5cddbf 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsModel.kt
@@ -17,6 +17,7 @@
package com.android.systemui.controls.management
import android.content.ComponentName
+import android.graphics.drawable.Icon
import androidx.recyclerview.widget.RecyclerView
import com.android.systemui.controls.ControlInterface
import com.android.systemui.controls.ControlStatus
@@ -126,9 +127,12 @@ data class ControlInfoWrapper(
get() = controlInfo.controlSubtitle
override val deviceType: Int
get() = controlInfo.deviceType
+ override val customIcon: Icon?
+ // Will need to address to support for edit activity
+ get() = null
}
data class DividerWrapper(
var showNone: Boolean = false,
var showDivider: Boolean = false
-) : ElementWrapper() \ No newline at end of file
+) : ElementWrapper()
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 d2501fa8a66b..c073642afa4e 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinatorImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinatorImpl.kt
@@ -35,7 +35,6 @@ import com.android.systemui.globalactions.GlobalActionsComponent
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.util.concurrency.DelayableExecutor
-import com.android.systemui.R
import javax.inject.Inject
import javax.inject.Singleton
@@ -164,8 +163,7 @@ class ControlActionCoordinatorImpl @Inject constructor(
it.show()
}
} else {
- cvh.setTransientStatus(
- cvh.context.resources.getString(R.string.controls_error_failed))
+ cvh.setErrorStatus()
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt
index ee02b85e4a00..0e4f68431c16 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt
@@ -67,7 +67,6 @@ class ControlViewHolder(
companion object {
const val STATE_ANIMATION_DURATION = 700L
- private const val UPDATE_DELAY_IN_MILLIS = 3000L
private const val ALPHA_ENABLED = 255
private const val ALPHA_DISABLED = 0
private const val STATUS_ALPHA_ENABLED = 1f
@@ -113,7 +112,6 @@ class ControlViewHolder(
val context: Context = layout.getContext()
val clipLayer: ClipDrawable
lateinit var cws: ControlWithState
- var cancelUpdate: Runnable? = null
var behavior: Behavior? = null
var lastAction: ControlAction? = null
var isLoading = false
@@ -128,6 +126,8 @@ class ControlViewHolder(
val controlTemplate: ControlTemplate
get() = cws.control?.let { it.controlTemplate } ?: ControlTemplate.NO_TEMPLATE
+ var userInteractionInProgress = false
+
init {
val ld = layout.getBackground() as LayerDrawable
ld.mutate()
@@ -139,9 +139,12 @@ class ControlViewHolder(
}
fun bindData(cws: ControlWithState) {
- this.cws = cws
+ // If an interaction is in progress, the update may visually interfere with the action the
+ // action the user wants to make. Don't apply the update, and instead assume a new update
+ // will coming from when the user interaction is complete.
+ if (userInteractionInProgress) return
- cancelUpdate?.run()
+ this.cws = cws
// For the following statuses only, assume the title/subtitle could not be set properly
// by the app and instead use the last known information from favorites
@@ -181,20 +184,20 @@ class ControlViewHolder(
lastChallengeDialog = null
ControlAction.RESPONSE_UNKNOWN -> {
lastChallengeDialog = null
- setTransientStatus(context.resources.getString(R.string.controls_error_failed))
+ setErrorStatus()
}
ControlAction.RESPONSE_FAIL -> {
lastChallengeDialog = null
- setTransientStatus(context.resources.getString(R.string.controls_error_failed))
+ setErrorStatus()
}
ControlAction.RESPONSE_CHALLENGE_PIN -> {
lastChallengeDialog = ChallengeDialogs.createPinDialog(
- this, false, failedAttempt, onDialogCancel)
+ this, false /* useAlphanumeric */, failedAttempt, onDialogCancel)
lastChallengeDialog?.show()
}
ControlAction.RESPONSE_CHALLENGE_PASSPHRASE -> {
lastChallengeDialog = ChallengeDialogs.createPinDialog(
- this, false, failedAttempt, onDialogCancel)
+ this, true /* useAlphanumeric */, failedAttempt, onDialogCancel)
lastChallengeDialog?.show()
}
ControlAction.RESPONSE_CHALLENGE_ACK -> {
@@ -212,19 +215,10 @@ class ControlViewHolder(
visibleDialog = null
}
- fun setTransientStatus(tempStatus: String) {
- val previousText = status.getText()
-
- cancelUpdate = uiExecutor.executeDelayed({
- animateStatusChange(/* animated */ true, {
- setStatusText(previousText, /* immediately */ true)
- updateContentDescription()
- })
- }, UPDATE_DELAY_IN_MILLIS)
-
+ fun setErrorStatus() {
+ val text = context.resources.getString(R.string.controls_error_failed)
animateStatusChange(/* animated */ true, {
- setStatusText(tempStatus, /* immediately */ true)
- updateContentDescription()
+ setStatusText(text, /* immediately */ true)
})
}
@@ -274,7 +268,6 @@ class ControlViewHolder(
val ri = RenderInfo.lookup(context, cws.componentName, deviceTypeOrError, offset)
val fg = context.resources.getColorStateList(ri.foreground, context.theme)
val newText = nextStatusText
- nextStatusText = ""
val control = cws.control
var shouldAnimate = animated
@@ -297,10 +290,9 @@ class ControlViewHolder(
if (immediately) {
status.alpha = STATUS_ALPHA_ENABLED
status.text = text
- nextStatusText = ""
- } else {
- nextStatusText = text
+ updateContentDescription()
}
+ nextStatusText = text
}
private fun animateBackgroundChange(
@@ -415,11 +407,15 @@ class ControlViewHolder(
setEnabled(enabled)
status.text = text
+ updateContentDescription()
+
status.setTextColor(color)
control?.getCustomIcon()?.let {
// do not tint custom icons, assume the intended icon color is correct
- icon.imageTintList = null
+ if (icon.imageTintList != null) {
+ icon.imageTintList = null
+ }
icon.setImageIcon(it)
} ?: run {
if (drawable is StateListDrawable) {
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 0f5aef7eeec1..1eb7e2168a6a 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
@@ -103,6 +103,22 @@ class ControlsUiControllerImpl @Inject constructor (
private lateinit var dismissGlobalActions: Runnable
private val popupThemedContext = ContextThemeWrapper(context, R.style.Control_ListPopupWindow)
+ private val collator = Collator.getInstance(context.resources.configuration.locales[0])
+ private val localeComparator = compareBy<SelectionItem, CharSequence>(collator) {
+ it.getTitle()
+ }
+
+ private val onSeedingComplete = Consumer<Boolean> {
+ accepted ->
+ if (accepted) {
+ selectedStructure = controlsController.get().getFavorites().maxBy {
+ it.controls.size
+ } ?: EMPTY_STRUCTURE
+ updatePreferences(selectedStructure)
+ }
+ reload(parent)
+ }
+
override val available: Boolean
get() = controlsController.get().available
@@ -113,22 +129,13 @@ class ControlsUiControllerImpl @Inject constructor (
): ControlsListingController.ControlsListingCallback {
return object : ControlsListingController.ControlsListingCallback {
override fun onServicesUpdated(serviceInfos: List<ControlsServiceInfo>) {
- bgExecutor.execute {
- val collator = Collator.getInstance(context.resources.configuration.locales[0])
- val localeComparator = compareBy<ControlsServiceInfo, CharSequence>(collator) {
- it.loadLabel()
- }
-
- val mList = serviceInfos.toMutableList()
- mList.sortWith(localeComparator)
- lastItems = mList.map {
- SelectionItem(it.loadLabel(), "", it.loadIcon(), it.componentName)
- }
- uiExecutor.execute {
- parent.removeAllViews()
- if (lastItems.size > 0) {
- onResult(lastItems)
- }
+ val lastItems = serviceInfos.map {
+ SelectionItem(it.loadLabel(), "", it.loadIcon(), it.componentName)
+ }
+ uiExecutor.execute {
+ parent.removeAllViews()
+ if (lastItems.size > 0) {
+ onResult(lastItems)
}
}
}
@@ -144,8 +151,7 @@ class ControlsUiControllerImpl @Inject constructor (
allStructures = controlsController.get().getFavorites()
selectedStructure = loadPreference(allStructures)
- val cb = Consumer<Boolean> { _ -> reload(parent) }
- if (controlsController.get().addSeedingFavoritesCallback(cb)) {
+ if (controlsController.get().addSeedingFavoritesCallback(onSeedingComplete)) {
listingCallback = createCallback(::showSeedingView)
} else if (selectedStructure.controls.isEmpty() && allStructures.size <= 1) {
// only show initial view if there are really no favorites across any structure
@@ -309,9 +315,12 @@ class ControlsUiControllerImpl @Inject constructor (
}
val itemsByComponent = items.associateBy { it.componentName }
- val itemsWithStructure = allStructures.mapNotNull {
+ val itemsWithStructure = mutableListOf<SelectionItem>()
+ allStructures.mapNotNullTo(itemsWithStructure) {
itemsByComponent.get(it.componentName)?.copy(structure = it.structure)
}
+ itemsWithStructure.sortWith(localeComparator)
+
val selectionItem = findSelectionItem(selectedStructure, itemsWithStructure) ?: items[0]
var adapter = ItemAdapter(context, R.layout.controls_spinner_item).apply {
@@ -441,6 +450,7 @@ class ControlsUiControllerImpl @Inject constructor (
}
private fun updatePreferences(si: StructureInfo) {
+ if (si == EMPTY_STRUCTURE) return
sharedPreferences.edit()
.putString(PREF_COMPONENT, si.componentName.flattenToString())
.putString(PREF_STRUCTURE, si.structure.toString())
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/StatusBehavior.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/StatusBehavior.kt
index dac55378daca..116f3ca898c0 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/StatusBehavior.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/StatusBehavior.kt
@@ -77,8 +77,7 @@ class StatusBehavior : Behavior {
cws.control?.getAppIntent()?.send()
context.sendBroadcast(Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS))
} catch (e: PendingIntent.CanceledException) {
- cvh.setTransientStatus(
- cvh.context.resources.getString(R.string.controls_error_failed))
+ cvh.setErrorStatus()
}
dialog.dismiss()
})
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ToggleRangeBehavior.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ToggleRangeBehavior.kt
index 02f80e842516..aa11df41a7b7 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ToggleRangeBehavior.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ToggleRangeBehavior.kt
@@ -163,8 +163,10 @@ class ToggleRangeBehavior : Behavior {
AccessibilityNodeInfo.RangeInfo.RANGE_TYPE_FLOAT
}
- val rangeInfo = AccessibilityNodeInfo.RangeInfo.obtain(type, min, max, current)
- info.setRangeInfo(rangeInfo)
+ if (isChecked) {
+ val rangeInfo = AccessibilityNodeInfo.RangeInfo.obtain(type, min, max, current)
+ info.setRangeInfo(rangeInfo)
+ }
info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SET_PROGRESS)
}
@@ -214,6 +216,7 @@ class ToggleRangeBehavior : Behavior {
}
fun beginUpdateRange() {
+ cvh.userInteractionInProgress = true
cvh.setStatusTextSize(context.getResources()
.getDimensionPixelSize(R.dimen.control_status_expanded).toFloat())
}
@@ -294,6 +297,7 @@ class ToggleRangeBehavior : Behavior {
cvh.setStatusText("$currentStatusText $currentRangeValue", /* immediately */ true)
cvh.controlActionCoordinator.setValue(cvh, rangeTemplate.getTemplateId(),
findNearestStep(levelToRangeValue(clipLayer.getLevel())))
+ cvh.userInteractionInProgress = false
}
fun findNearestStep(value: Float): Float {
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/TouchBehavior.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/TouchBehavior.kt
index 48f945874135..9dd0f534e3a8 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/TouchBehavior.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/TouchBehavior.kt
@@ -21,6 +21,7 @@ import android.graphics.drawable.LayerDrawable
import android.view.View
import android.service.controls.Control
import android.service.controls.templates.ControlTemplate
+import android.service.controls.templates.StatelessTemplate
import com.android.systemui.R
import com.android.systemui.controls.ui.ControlViewHolder.Companion.MAX_LEVEL
@@ -35,24 +36,44 @@ class TouchBehavior : Behavior {
lateinit var template: ControlTemplate
lateinit var control: Control
lateinit var cvh: ControlViewHolder
+ private var statelessTouch = false
+ private var lastColorOffset = 0
+ private val enabled: Boolean
+ get() = if (lastColorOffset > 0 || statelessTouch) true else false
+
+ companion object {
+ const val STATELESS_ENABLE_TIMEOUT_IN_MILLIS = 3000L
+ }
override fun initialize(cvh: ControlViewHolder) {
this.cvh = cvh
cvh.layout.setOnClickListener(View.OnClickListener() {
cvh.controlActionCoordinator.touch(cvh, template.getTemplateId(), control)
+
+ // StatelessTemplates have no state, with no way to discern between enabled and
+ // disabled. Render an enabled state for a few moments to let the user know the
+ // action is in progress.
+ if (template is StatelessTemplate) {
+ statelessTouch = true
+ cvh.applyRenderInfo(enabled, lastColorOffset)
+ cvh.uiExecutor.executeDelayed({
+ statelessTouch = false
+ cvh.applyRenderInfo(enabled, lastColorOffset)
+ }, STATELESS_ENABLE_TIMEOUT_IN_MILLIS)
+ }
})
}
override fun bind(cws: ControlWithState, colorOffset: Int) {
this.control = cws.control!!
+ lastColorOffset = colorOffset
cvh.setStatusText(control.getStatusText())
template = control.getControlTemplate()
val ld = cvh.layout.getBackground() as LayerDrawable
clipLayer = ld.findDrawableByLayerId(R.id.clip_layer)
- val enabled = if (colorOffset > 0) true else false
clipLayer.setLevel(if (enabled) MAX_LEVEL else MIN_LEVEL)
cvh.applyRenderInfo(enabled, colorOffset)
}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
index 1f30305ab169..fedc9e31a4ec 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
@@ -61,6 +61,8 @@ import com.android.systemui.statusbar.policy.DataSaverController;
import com.android.systemui.statusbar.policy.NetworkController;
import com.android.systemui.util.leak.LeakDetector;
+import java.util.concurrent.Executor;
+
import javax.inject.Named;
import javax.inject.Singleton;
@@ -188,11 +190,12 @@ public class DependencyProvider {
public BroadcastDispatcher providesBroadcastDispatcher(
Context context,
@Background Looper backgroundLooper,
+ @Background Executor backgroundExecutor,
DumpManager dumpManager,
BroadcastDispatcherLogger logger
) {
- BroadcastDispatcher bD =
- new BroadcastDispatcher(context, backgroundLooper, dumpManager, logger);
+ BroadcastDispatcher bD = new BroadcastDispatcher(context, backgroundLooper,
+ backgroundExecutor, dumpManager, logger);
bD.initialize();
return bD;
}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
index 951dc9936e1c..3bac196ca59f 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
@@ -35,7 +35,6 @@ import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.statusbar.phone.BiometricUnlockController;
import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.statusbar.policy.BatteryController;
-import com.android.systemui.util.concurrency.DelayableExecutor;
import com.android.systemui.util.sensors.AsyncSensorManager;
import com.android.systemui.util.sensors.ProximitySensor;
import com.android.systemui.util.wakelock.DelayedWakeLock;
@@ -56,9 +55,9 @@ public class DozeFactory {
private final DockManager mDockManager;
private final IWallpaperManager mWallpaperManager;
private final ProximitySensor mProximitySensor;
+ private final ProximitySensor.ProximityCheck mProximityCheck;
private final DelayedWakeLock.Builder mDelayedWakeLockBuilder;
private final Handler mHandler;
- private final DelayableExecutor mDelayableExecutor;
private final BiometricUnlockController mBiometricUnlockController;
private final BroadcastDispatcher mBroadcastDispatcher;
private final DozeHost mDozeHost;
@@ -69,9 +68,8 @@ public class DozeFactory {
AsyncSensorManager asyncSensorManager, AlarmManager alarmManager,
WakefulnessLifecycle wakefulnessLifecycle, KeyguardUpdateMonitor keyguardUpdateMonitor,
DockManager dockManager, @Nullable IWallpaperManager wallpaperManager,
- ProximitySensor proximitySensor,
+ ProximitySensor proximitySensor, ProximitySensor.ProximityCheck proximityCheck,
DelayedWakeLock.Builder delayedWakeLockBuilder, @Main Handler handler,
- @Main DelayableExecutor delayableExecutor,
BiometricUnlockController biometricUnlockController,
BroadcastDispatcher broadcastDispatcher, DozeHost dozeHost) {
mFalsingManager = falsingManager;
@@ -85,9 +83,9 @@ public class DozeFactory {
mDockManager = dockManager;
mWallpaperManager = wallpaperManager;
mProximitySensor = proximitySensor;
+ mProximityCheck = proximityCheck;
mDelayedWakeLockBuilder = delayedWakeLockBuilder;
mHandler = handler;
- mDelayableExecutor = delayableExecutor;
mBiometricUnlockController = biometricUnlockController;
mBroadcastDispatcher = broadcastDispatcher;
mDozeHost = dozeHost;
@@ -112,8 +110,8 @@ public class DozeFactory {
new DozePauser(mHandler, machine, mAlarmManager, mDozeParameters.getPolicy()),
new DozeFalsingManagerAdapter(mFalsingManager),
createDozeTriggers(dozeService, mAsyncSensorManager, mDozeHost,
- mAlarmManager, config, mDozeParameters, mDelayableExecutor, wakeLock,
- machine, mDockManager, mDozeLog),
+ mAlarmManager, config, mDozeParameters, wakeLock,
+ machine, mDockManager, mDozeLog, mProximityCheck),
createDozeUi(dozeService, mDozeHost, wakeLock, machine, mHandler,
mAlarmManager, mDozeParameters, mDozeLog),
new DozeScreenState(wrappedService, mHandler, mDozeHost, mDozeParameters,
@@ -140,12 +138,13 @@ public class DozeFactory {
private DozeTriggers createDozeTriggers(Context context, AsyncSensorManager sensorManager,
DozeHost host, AlarmManager alarmManager, AmbientDisplayConfiguration config,
- DozeParameters params, DelayableExecutor delayableExecutor, WakeLock wakeLock,
- DozeMachine machine, DockManager dockManager, DozeLog dozeLog) {
+ DozeParameters params, WakeLock wakeLock,
+ DozeMachine machine, DockManager dockManager, DozeLog dozeLog,
+ ProximitySensor.ProximityCheck proximityCheck) {
boolean allowPulseTriggers = true;
return new DozeTriggers(context, machine, host, alarmManager, config, params,
- sensorManager, delayableExecutor, wakeLock, allowPulseTriggers, dockManager,
- mProximitySensor, dozeLog, mBroadcastDispatcher);
+ sensorManager, wakeLock, allowPulseTriggers, dockManager,
+ mProximitySensor, proximityCheck, dozeLog, mBroadcastDispatcher);
}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
index 6a5501445a4d..82639ba4375e 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
@@ -42,7 +42,6 @@ import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dock.DockManager;
import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.util.Assert;
-import com.android.systemui.util.concurrency.DelayableExecutor;
import com.android.systemui.util.sensors.AsyncSensorManager;
import com.android.systemui.util.sensors.ProximitySensor;
import com.android.systemui.util.wakelock.WakeLock;
@@ -153,8 +152,8 @@ public class DozeTriggers implements DozeMachine.Part {
public DozeTriggers(Context context, DozeMachine machine, DozeHost dozeHost,
AlarmManager alarmManager, AmbientDisplayConfiguration config,
DozeParameters dozeParameters, AsyncSensorManager sensorManager,
- DelayableExecutor delayableExecutor, WakeLock wakeLock, boolean allowPulseTriggers,
- DockManager dockManager, ProximitySensor proximitySensor,
+ WakeLock wakeLock, boolean allowPulseTriggers, DockManager dockManager,
+ ProximitySensor proximitySensor, ProximitySensor.ProximityCheck proxCheck,
DozeLog dozeLog, BroadcastDispatcher broadcastDispatcher) {
mContext = context;
mMachine = machine;
@@ -168,7 +167,7 @@ public class DozeTriggers implements DozeMachine.Part {
config, wakeLock, this::onSensor, this::onProximityFar, dozeLog, proximitySensor);
mUiModeManager = mContext.getSystemService(UiModeManager.class);
mDockManager = dockManager;
- mProxCheck = new ProximitySensor.ProximityCheck(proximitySensor, delayableExecutor);
+ mProxCheck = proxCheck;
mDozeLog = dozeLog;
mBroadcastDispatcher = broadcastDispatcher;
}
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
index 915092134cc5..eed52004923d 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
@@ -22,6 +22,7 @@ import static android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_USER_REQUEST;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED;
+import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_GLOBAL_ACTIONS_SHOWING;
@@ -171,7 +172,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
@VisibleForTesting
static final String GLOBAL_ACTION_KEY_POWER = "power";
private static final String GLOBAL_ACTION_KEY_AIRPLANE = "airplane";
- private static final String GLOBAL_ACTION_KEY_BUGREPORT = "bugreport";
+ static final String GLOBAL_ACTION_KEY_BUGREPORT = "bugreport";
private static final String GLOBAL_ACTION_KEY_SILENT = "silent";
private static final String GLOBAL_ACTION_KEY_USERS = "users";
private static final String GLOBAL_ACTION_KEY_SETTINGS = "settings";
@@ -395,11 +396,14 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
controlsComponent.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
- if (mDialog != null && !mDialog.isShowingControls()
- && shouldShowControls()) {
- mDialog.showControls(mControlsUiControllerOptional.get());
+ // 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) {
+ if (!mDialog.isShowingControls() && shouldShowControls()) {
+ mDialog.showControls(mControlsUiControllerOptional.get());
+ } else if (shouldShowLockMessage()) {
+ mDialog.showLockMessage();
+ }
}
});
}
@@ -560,12 +564,10 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
* whether controls are enabled and whether the max number of shown items has been reached.
*/
private void addActionItem(Action action) {
- if (shouldShowAction(action)) {
- if (mItems.size() < getMaxShownPowerItems()) {
- mItems.add(action);
- } else {
- mOverflowItems.add(action);
- }
+ if (mItems.size() < getMaxShownPowerItems()) {
+ mItems.add(action);
+ } else {
+ mOverflowItems.add(action);
}
}
@@ -574,6 +576,12 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
return mResources.getStringArray(R.array.config_globalActionsList);
}
+ private void addIfShouldShowAction(List<Action> actions, Action action) {
+ if (shouldShowAction(action)) {
+ actions.add(action);
+ }
+ }
+
@VisibleForTesting
protected void createActionItems() {
// Simple toggle style if there's no vibrator, otherwise use a tri-state
@@ -593,10 +601,12 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
ShutDownAction shutdownAction = new ShutDownAction();
RestartAction restartAction = new RestartAction();
ArraySet<String> addedKeys = new ArraySet<String>();
+ List<Action> tempActions = new ArrayList<>();
+ CurrentUserProvider currentUser = new CurrentUserProvider();
// make sure emergency affordance action is first, if needed
if (mEmergencyAffordanceManager.needsEmergencyAffordance()) {
- addActionItem(new EmergencyAffordanceAction());
+ addIfShouldShowAction(tempActions, new EmergencyAffordanceAction());
addedKeys.add(GLOBAL_ACTION_KEY_EMERGENCY);
}
@@ -607,43 +617,43 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
continue;
}
if (GLOBAL_ACTION_KEY_POWER.equals(actionKey)) {
- addActionItem(shutdownAction);
+ addIfShouldShowAction(tempActions, shutdownAction);
} else if (GLOBAL_ACTION_KEY_AIRPLANE.equals(actionKey)) {
- addActionItem(mAirplaneModeOn);
+ addIfShouldShowAction(tempActions, mAirplaneModeOn);
} else if (GLOBAL_ACTION_KEY_BUGREPORT.equals(actionKey)) {
- if (Settings.Global.getInt(mContentResolver,
- Settings.Global.BUGREPORT_IN_POWER_MENU, 0) != 0 && isCurrentUserOwner()) {
- addActionItem(new BugReportAction());
+ if (shouldDisplayBugReport(currentUser.get())) {
+ addIfShouldShowAction(tempActions, new BugReportAction());
}
} else if (GLOBAL_ACTION_KEY_SILENT.equals(actionKey)) {
if (mShowSilentToggle) {
- addActionItem(mSilentModeAction);
+ addIfShouldShowAction(tempActions, mSilentModeAction);
}
} else if (GLOBAL_ACTION_KEY_USERS.equals(actionKey)) {
if (SystemProperties.getBoolean("fw.power_user_switcher", false)) {
- addUsersToMenu();
+ addUserActions(tempActions, currentUser.get());
}
} else if (GLOBAL_ACTION_KEY_SETTINGS.equals(actionKey)) {
- addActionItem(getSettingsAction());
+ addIfShouldShowAction(tempActions, getSettingsAction());
} else if (GLOBAL_ACTION_KEY_LOCKDOWN.equals(actionKey)) {
- if (shouldDisplayLockdown(getCurrentUser())) {
- addActionItem(getLockdownAction());
+ if (shouldDisplayLockdown(currentUser.get())) {
+ addIfShouldShowAction(tempActions, new LockDownAction());
}
} else if (GLOBAL_ACTION_KEY_VOICEASSIST.equals(actionKey)) {
- addActionItem(getVoiceAssistAction());
+ addIfShouldShowAction(tempActions, getVoiceAssistAction());
} else if (GLOBAL_ACTION_KEY_ASSIST.equals(actionKey)) {
- addActionItem(getAssistAction());
+ addIfShouldShowAction(tempActions, getAssistAction());
} else if (GLOBAL_ACTION_KEY_RESTART.equals(actionKey)) {
- addActionItem(restartAction);
+ addIfShouldShowAction(tempActions, restartAction);
} else if (GLOBAL_ACTION_KEY_SCREENSHOT.equals(actionKey)) {
- addActionItem(new ScreenshotAction());
+ addIfShouldShowAction(tempActions, new ScreenshotAction());
} else if (GLOBAL_ACTION_KEY_LOGOUT.equals(actionKey)) {
if (mDevicePolicyManager.isLogoutEnabled()
- && getCurrentUser().id != UserHandle.USER_SYSTEM) {
- addActionItem(new LogoutAction());
+ && currentUser.get() != null
+ && currentUser.get().id != UserHandle.USER_SYSTEM) {
+ addIfShouldShowAction(tempActions, new LogoutAction());
}
} else if (GLOBAL_ACTION_KEY_EMERGENCY.equals(actionKey)) {
- addActionItem(new EmergencyDialerAction());
+ addIfShouldShowAction(tempActions, new EmergencyDialerAction());
} else {
Log.e(TAG, "Invalid global action key " + actionKey);
}
@@ -652,22 +662,21 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
}
// replace power and restart with a single power options action, if needed
- if (mItems.contains(shutdownAction) && mItems.contains(restartAction)
- && mOverflowItems.size() > 0) {
+ if (tempActions.contains(shutdownAction) && tempActions.contains(restartAction)
+ && tempActions.size() > getMaxShownPowerItems()) {
// transfer shutdown and restart to their own list of power actions
- mItems.remove(shutdownAction);
- mItems.remove(restartAction);
+ int powerOptionsIndex = Math.min(tempActions.indexOf(restartAction),
+ tempActions.indexOf(shutdownAction));
+ tempActions.remove(shutdownAction);
+ tempActions.remove(restartAction);
mPowerItems.add(shutdownAction);
mPowerItems.add(restartAction);
// add the PowerOptionsAction after Emergency, if present
- int powerIndex = addedKeys.contains(GLOBAL_ACTION_KEY_EMERGENCY) ? 1 : 0;
- mItems.add(powerIndex, new PowerOptionsAction());
-
- // transfer the first overflow action to the main set of items
- Action firstOverflowAction = mOverflowItems.get(0);
- mOverflowItems.remove(0);
- mItems.add(firstOverflowAction);
+ tempActions.add(powerOptionsIndex, new PowerOptionsAction());
+ }
+ for (Action action : tempActions) {
+ addActionItem(action);
}
}
@@ -700,9 +709,8 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
mStatusBarService, mNotificationShadeWindowController,
controlsAvailable(), uiController,
mSysUiState, this::onRotate, mKeyguardShowing, mPowerAdapter);
- boolean walletViewAvailable = walletViewController != null
- && walletViewController.getPanelContent() != null;
- if (shouldShowLockMessage(walletViewAvailable)) {
+
+ if (shouldShowLockMessage()) {
dialog.showLockMessage();
}
dialog.setCanceledOnTouchOutside(false); // Handled by the custom class.
@@ -713,7 +721,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
}
@VisibleForTesting
- protected boolean shouldDisplayLockdown(UserInfo user) {
+ boolean shouldDisplayLockdown(UserInfo user) {
if (user == null) {
return false;
}
@@ -737,6 +745,13 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
|| state == SOME_AUTH_REQUIRED_AFTER_USER_REQUEST);
}
+ @VisibleForTesting
+ boolean shouldDisplayBugReport(UserInfo currentUser) {
+ return Settings.Global.getInt(
+ mContentResolver, Settings.Global.BUGREPORT_IN_POWER_MENU, 0) != 0
+ && (currentUser == null || currentUser.isPrimary());
+ }
+
@Override
public void onUiModeChanged() {
mContext.getTheme().applyStyle(mContext.getThemeResId(), true);
@@ -801,7 +816,8 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
}
}
- private final class ShutDownAction extends SinglePressAction implements LongPressAction {
+ @VisibleForTesting
+ final class ShutDownAction extends SinglePressAction implements LongPressAction {
private ShutDownAction() {
super(R.drawable.ic_lock_power_off,
R.string.global_action_power_off);
@@ -913,7 +929,8 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
return new EmergencyDialerAction();
}
- private final class RestartAction extends SinglePressAction implements LongPressAction {
+ @VisibleForTesting
+ final class RestartAction extends SinglePressAction implements LongPressAction {
private RestartAction() {
super(R.drawable.ic_restart, R.string.global_action_restart);
}
@@ -1158,33 +1175,34 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
};
}
- private Action getLockdownAction() {
- return new SinglePressAction(R.drawable.ic_lock_lockdown,
- R.string.global_action_lockdown) {
+ @VisibleForTesting
+ class LockDownAction extends SinglePressAction {
+ LockDownAction() {
+ super(R.drawable.ic_lock_lockdown, R.string.global_action_lockdown);
+ }
- @Override
- public void onPress() {
- mLockPatternUtils.requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN,
- UserHandle.USER_ALL);
- try {
- mIWindowManager.lockNow(null);
- // Lock profiles (if any) on the background thread.
- mBackgroundExecutor.execute(() -> lockProfiles());
- } catch (RemoteException e) {
- Log.e(TAG, "Error while trying to lock device.", e);
- }
+ @Override
+ public void onPress() {
+ mLockPatternUtils.requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN,
+ UserHandle.USER_ALL);
+ try {
+ mIWindowManager.lockNow(null);
+ // Lock profiles (if any) on the background thread.
+ mBackgroundExecutor.execute(() -> lockProfiles());
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error while trying to lock device.", e);
}
+ }
- @Override
- public boolean showDuringKeyguard() {
- return true;
- }
+ @Override
+ public boolean showDuringKeyguard() {
+ return true;
+ }
- @Override
- public boolean showBeforeProvisioning() {
- return false;
- }
- };
+ @Override
+ public boolean showBeforeProvisioning() {
+ return false;
+ }
}
private void lockProfiles() {
@@ -1205,15 +1223,27 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
}
}
- private boolean isCurrentUserOwner() {
- UserInfo currentUser = getCurrentUser();
- return currentUser == null || currentUser.isPrimary();
+ /**
+ * Non-thread-safe current user provider that caches the result - helpful when a method needs
+ * to fetch it an indeterminate number of times.
+ */
+ private class CurrentUserProvider {
+ private UserInfo mUserInfo = null;
+ private boolean mFetched = false;
+
+ @Nullable
+ UserInfo get() {
+ if (!mFetched) {
+ mFetched = true;
+ mUserInfo = getCurrentUser();
+ }
+ return mUserInfo;
+ }
}
- private void addUsersToMenu() {
+ private void addUserActions(List<Action> actions, UserInfo currentUser) {
if (mUserManager.isUserSwitcherEnabled()) {
List<UserInfo> users = mUserManager.getUsers();
- UserInfo currentUser = getCurrentUser();
for (final UserInfo user : users) {
if (user.supportsSwitchToByUser()) {
boolean isCurrentUser = currentUser == null
@@ -1240,7 +1270,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
return false;
}
};
- addActionItem(switchToUser);
+ addIfShouldShowAction(actions, switchToUser);
}
}
}
@@ -1422,16 +1452,26 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
Log.w(TAG, "No power options action found at position: " + position);
return null;
}
- int viewLayoutResource = com.android.systemui.R.layout.controls_more_item;
+ int viewLayoutResource = com.android.systemui.R.layout.global_actions_power_item;
View view = convertView != null ? convertView
: LayoutInflater.from(mContext).inflate(viewLayoutResource, parent, false);
- TextView textView = (TextView) view;
- if (action.getMessageResId() != 0) {
- textView.setText(action.getMessageResId());
+ view.setOnClickListener(v -> onClickItem(position));
+ if (action instanceof LongPressAction) {
+ view.setOnLongClickListener(v -> onLongClickItem(position));
+ }
+ ImageView icon = view.findViewById(R.id.icon);
+ TextView messageView = view.findViewById(R.id.message);
+ messageView.setSelected(true); // necessary for marquee to work
+
+ icon.setImageDrawable(action.getIcon(mContext));
+ icon.setScaleType(ScaleType.CENTER_CROP);
+
+ if (action.getMessage() != null) {
+ messageView.setText(action.getMessage());
} else {
- textView.setText(action.getMessage());
+ messageView.setText(action.getMessageResId());
}
- return textView;
+ return view;
}
private boolean onLongClickItem(int position) {
@@ -1567,6 +1607,11 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
int getMessageResId();
/**
+ * Return the icon drawable for this action.
+ */
+ Drawable getIcon(Context context);
+
+ /**
* Return the message associated with this action, or null if it doesn't have one.
* @return
*/
@@ -1630,6 +1675,15 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
return mMessage;
}
+ @Override
+ public Drawable getIcon(Context context) {
+ if (mIcon != null) {
+ return mIcon;
+ } else {
+ return context.getDrawable(mIconResId);
+ }
+ }
+
public View create(
Context context, View convertView, ViewGroup parent, LayoutInflater inflater) {
View v = inflater.inflate(com.android.systemui.R.layout.global_actions_grid_item_v2,
@@ -1639,12 +1693,9 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
TextView messageView = v.findViewById(R.id.message);
messageView.setSelected(true); // necessary for marquee to work
- if (mIcon != null) {
- icon.setImageDrawable(mIcon);
- icon.setScaleType(ScaleType.CENTER_CROP);
- } else if (mIconResId != 0) {
- icon.setImageDrawable(context.getDrawable(mIconResId));
- }
+ icon.setImageDrawable(getIcon(context));
+ icon.setScaleType(ScaleType.CENTER_CROP);
+
if (mMessage != null) {
messageView.setText(mMessage);
} else {
@@ -1735,6 +1786,11 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
return isOn() ? mEnabledIconResId : mDisabledIconResid;
}
+ @Override
+ public Drawable getIcon(Context context) {
+ return context.getDrawable(getIconResId());
+ }
+
public View create(Context context, View convertView, ViewGroup parent,
LayoutInflater inflater) {
willCreate();
@@ -1901,6 +1957,12 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
return null;
}
+ @Override
+ public Drawable getIcon(Context context) {
+ return null;
+ }
+
+
public View create(Context context, View convertView, ViewGroup parent,
LayoutInflater inflater) {
View v = inflater.inflate(R.layout.global_actions_silent_mode, parent, false);
@@ -2072,7 +2134,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
private final NotificationShadeDepthController mDepthController;
private final SysUiState mSysUiState;
private ListPopupWindow mOverflowPopup;
- private ListPopupWindow mPowerOptionsPopup;
+ private Dialog mPowerOptionsDialog;
private final Runnable mOnRotateCallback;
private final boolean mControlsAvailable;
@@ -2208,21 +2270,6 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
}
}
- private ListPopupWindow createPowerOptionsPopup() {
- GlobalActionsPopupMenu popup = new GlobalActionsPopupMenu(
- new ContextThemeWrapper(
- mContext,
- com.android.systemui.R.style.Control_ListPopupWindow
- ), false /* isDropDownMode */);
- popup.setOnItemClickListener(
- (parent, view, position, id) -> mPowerOptionsAdapter.onClickItem(position));
- popup.setOnItemLongClickListener(
- (parent, view, position, id) -> mPowerOptionsAdapter.onLongClickItem(position));
- popup.setAnchorView(mGlobalActionsLayout);
- popup.setAdapter(mPowerOptionsAdapter);
- return popup;
- }
-
private ListPopupWindow createPowerOverflowPopup() {
GlobalActionsPopupMenu popup = new GlobalActionsPopupMenu(
new ContextThemeWrapper(
@@ -2241,8 +2288,8 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
}
public void showPowerOptionsMenu() {
- mPowerOptionsPopup = createPowerOptionsPopup();
- mPowerOptionsPopup.show();
+ mPowerOptionsDialog = GlobalActionsPowerDialog.create(mContext, mPowerOptionsAdapter);
+ mPowerOptionsDialog.show();
}
private void showPowerOverflowMenu() {
@@ -2476,11 +2523,11 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
}
private void dismissPowerOptions(boolean immediate) {
- if (mPowerOptionsPopup != null) {
+ if (mPowerOptionsDialog != null) {
if (immediate) {
- mPowerOptionsPopup.dismissImmediate();
+ mPowerOptionsDialog.dismiss();
} else {
- mPowerOptionsPopup.dismiss();
+ mPowerOptionsDialog.dismiss();
}
}
}
@@ -2591,7 +2638,9 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
private boolean shouldShowControls() {
return (mKeyguardStateController.isUnlocked() || mShowLockScreenCardsAndControls)
- && controlsAvailable();
+ && controlsAvailable()
+ && mLockPatternUtils.getStrongAuthForUser(getCurrentUser().id)
+ != STRONG_AUTH_REQUIRED_AFTER_BOOT;
}
private boolean controlsAvailable() {
@@ -2601,10 +2650,18 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
&& !mControlsServiceInfos.isEmpty();
}
- private boolean shouldShowLockMessage(boolean walletViewAvailable) {
+ private boolean walletViewAvailable() {
+ GlobalActionsPanelPlugin.PanelViewController walletViewController =
+ getWalletViewController();
+ return walletViewController != null && walletViewController.getPanelContent() != null;
+ }
+
+ private boolean shouldShowLockMessage() {
+ boolean isLockedAfterBoot = mLockPatternUtils.getStrongAuthForUser(getCurrentUser().id)
+ == STRONG_AUTH_REQUIRED_AFTER_BOOT;
return !mKeyguardStateController.isUnlocked()
- && !mShowLockScreenCardsAndControls
- && (controlsAvailable() || walletViewAvailable);
+ && (!mShowLockScreenCardsAndControls || isLockedAfterBoot)
+ && (controlsAvailable() || walletViewAvailable());
}
private void onPowerMenuLockScreenSettingsChanged() {
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsPopupMenu.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsPopupMenu.java
index 1dbbb4d69493..ac4fc62bf1c9 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsPopupMenu.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsPopupMenu.java
@@ -54,6 +54,7 @@ public class GlobalActionsPopupMenu extends ListPopupWindow {
// required to show above the global actions dialog
setWindowLayoutType(WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY);
+ setInputMethodMode(INPUT_METHOD_NOT_NEEDED);
setModal(true);
mGlobalActionsSidePadding = res.getDimensionPixelSize(R.dimen.global_actions_side_margin);
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsPowerDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsPowerDialog.java
new file mode 100644
index 000000000000..caa88a372036
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsPowerDialog.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.globalactions;
+
+import android.annotation.NonNull;
+import android.app.Dialog;
+import android.content.Context;
+import android.content.res.Resources;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.view.WindowManager;
+import android.widget.ListAdapter;
+
+/**
+ * Creates a customized Dialog for displaying the Shut Down and Restart actions.
+ */
+public class GlobalActionsPowerDialog {
+
+ /**
+ * Create a dialog for displaying Shut Down and Restart actions.
+ */
+ public static Dialog create(@NonNull Context context, ListAdapter adapter) {
+ ViewGroup listView = (ViewGroup) LayoutInflater.from(context).inflate(
+ com.android.systemui.R.layout.global_actions_power_dialog, null);
+
+ for (int i = 0; i < adapter.getCount(); i++) {
+ View action = adapter.getView(i, null, listView);
+ listView.addView(action);
+ }
+
+ Resources res = context.getResources();
+
+ Dialog dialog = new Dialog(context);
+ dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
+ dialog.setContentView(listView);
+
+ Window window = dialog.getWindow();
+ window.setType(WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY);
+ window.setTitle(""); // prevent Talkback from speaking first item name twice
+ window.setBackgroundDrawable(res.getDrawable(
+ com.android.systemui.R.drawable.control_background, context.getTheme()));
+ window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
+
+ return dialog;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
index a2086e8d3ac6..16f76deca6c6 100644
--- a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
@@ -68,7 +68,7 @@ public class LogModule {
public static LogBuffer provideNotificationSectionLogBuffer(
LogcatEchoTracker bufferFilter,
DumpManager dumpManager) {
- LogBuffer buffer = new LogBuffer("NotifSectionLog", 500, 10, bufferFilter);
+ LogBuffer buffer = new LogBuffer("NotifSectionLog", 1000, 10, bufferFilter);
buffer.attach(dumpManager);
return buffer;
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/KeyguardMediaController.kt b/packages/SystemUI/src/com/android/systemui/media/KeyguardMediaController.kt
index 5f43e43c03c6..8ef20f89085c 100644
--- a/packages/SystemUI/src/com/android/systemui/media/KeyguardMediaController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/KeyguardMediaController.kt
@@ -46,7 +46,9 @@ class KeyguardMediaController @Inject constructor(
})
}
- private var view: MediaHeaderView? = null
+ var visibilityChangedListener: ((Boolean) -> Unit)? = null
+ var view: MediaHeaderView? = null
+ private set
/**
* Attach this controller to a media view, initializing its state
@@ -54,9 +56,10 @@ class KeyguardMediaController @Inject constructor(
fun attach(mediaView: MediaHeaderView) {
view = mediaView
// First let's set the desired state that we want for this host
- mediaHost.visibleChangedListener = { updateVisibility() }
+ mediaHost.addVisibilityChangeListener { updateVisibility() }
mediaHost.expansion = 0.0f
mediaHost.showsOnlyActiveMedia = true
+ mediaHost.falsingProtectionNeeded = true
// Let's now initialize this view, which also creates the host view for us.
mediaHost.init(MediaHierarchyManager.LOCATION_LOCKSCREEN)
@@ -70,6 +73,11 @@ class KeyguardMediaController @Inject constructor(
!bypassController.bypassEnabled &&
keyguardOrUserSwitcher &&
notifLockscreenUserManager.shouldShowLockscreenNotifications()
- view?.visibility = if (shouldBeVisible) View.VISIBLE else View.GONE
+ val previousVisibility = view?.visibility ?: View.GONE
+ val newVisibility = if (shouldBeVisible) View.VISIBLE else View.GONE
+ view?.visibility = newVisibility
+ if (previousVisibility != newVisibility) {
+ visibilityChangedListener?.invoke(shouldBeVisible)
+ }
}
} \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaViewManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt
index 9b9a6b4b13ab..e2215d57a094 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaViewManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt
@@ -1,40 +1,67 @@
package com.android.systemui.media
import android.content.Context
+import android.content.Intent
import android.graphics.Color
+import android.provider.Settings.ACTION_MEDIA_CONTROLS_SETTINGS
import android.view.LayoutInflater
-import android.view.GestureDetector
-import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
-import android.widget.HorizontalScrollView
import android.widget.LinearLayout
-import androidx.core.view.GestureDetectorCompat
import com.android.systemui.R
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.plugins.FalsingManager
import com.android.systemui.qs.PageIndicator
import com.android.systemui.statusbar.notification.VisualStabilityManager
+import com.android.systemui.statusbar.policy.ConfigurationController
+import com.android.systemui.util.Utils
import com.android.systemui.util.animation.UniqueObjectHostView
import com.android.systemui.util.animation.requiresRemeasuring
+import com.android.systemui.util.concurrency.DelayableExecutor
import javax.inject.Inject
import javax.inject.Provider
import javax.inject.Singleton
-private const val FLING_SLOP = 1000000
+private val settingsIntent = Intent().setAction(ACTION_MEDIA_CONTROLS_SETTINGS)
/**
* Class that is responsible for keeping the view carousel up to date.
* This also handles changes in state and applies them to the media carousel like the expansion.
*/
@Singleton
-class MediaViewManager @Inject constructor(
+class MediaCarouselController @Inject constructor(
private val context: Context,
private val mediaControlPanelFactory: Provider<MediaControlPanel>,
private val visualStabilityManager: VisualStabilityManager,
private val mediaHostStatesManager: MediaHostStatesManager,
- mediaManager: MediaDataCombineLatest
+ private val activityStarter: ActivityStarter,
+ @Main executor: DelayableExecutor,
+ mediaManager: MediaDataCombineLatest,
+ configurationController: ConfigurationController,
+ mediaDataManager: MediaDataManager,
+ falsingManager: FalsingManager
) {
+ /**
+ * The current width of the carousel
+ */
+ private var currentCarouselWidth: Int = 0
+
+ /**
+ * The current height of the carousel
+ */
+ private var currentCarouselHeight: Int = 0
+
+ /**
+ * Are we currently showing only active players
+ */
+ private var currentlyShowingOnlyActive: Boolean = false
/**
+ * Is the player currently visible (at the end of the transformation
+ */
+ private var playersVisible: Boolean = false
+ /**
* The desired location where we'll be at the end of the transformation. Usually this matches
* the end location, except when we're still waiting on a state update call.
*/
@@ -71,16 +98,16 @@ class MediaViewManager @Inject constructor(
private var carouselMeasureHeight: Int = 0
private var playerWidthPlusPadding: Int = 0
private var desiredHostState: MediaHostState? = null
- private val mediaCarousel: HorizontalScrollView
+ private val mediaCarousel: MediaScrollView
+ private val mediaCarouselScrollHandler: MediaCarouselScrollHandler
val mediaFrame: ViewGroup
val mediaPlayers: MutableMap<String, MediaControlPanel> = mutableMapOf()
+ private lateinit var settingsButton: View
+ private val mediaData: MutableMap<String, MediaData> = mutableMapOf()
private val mediaContent: ViewGroup
private val pageIndicator: PageIndicator
- private val gestureDetector: GestureDetectorCompat
private val visualStabilityCallback: VisualStabilityManager.Callback
- private var activeMediaIndex: Int = 0
private var needsReordering: Boolean = false
- private var scrollIntoCurrentMedia: Int = 0
private var currentlyExpanded = true
set(value) {
if (field != value) {
@@ -90,46 +117,27 @@ class MediaViewManager @Inject constructor(
}
}
}
- private val scrollChangedListener = object : View.OnScrollChangeListener {
- override fun onScrollChange(
- v: View?,
- scrollX: Int,
- scrollY: Int,
- oldScrollX: Int,
- oldScrollY: Int
- ) {
- if (playerWidthPlusPadding == 0) {
- return
- }
- onMediaScrollingChanged(scrollX / playerWidthPlusPadding,
- scrollX % playerWidthPlusPadding)
+ private val configListener = object : ConfigurationController.ConfigurationListener {
+ override fun onDensityOrFontScaleChanged() {
+ recreatePlayers()
+ inflateSettingsButton()
}
- }
- private val gestureListener = object : GestureDetector.SimpleOnGestureListener() {
- override fun onFling(
- eStart: MotionEvent?,
- eCurrent: MotionEvent?,
- vX: Float,
- vY: Float
- ): Boolean {
- return this@MediaViewManager.onFling(eStart, eCurrent, vX, vY)
- }
- }
- private val touchListener = object : View.OnTouchListener {
- override fun onTouch(view: View, motionEvent: MotionEvent?): Boolean {
- return this@MediaViewManager.onTouch(view, motionEvent)
+
+ override fun onOverlayChanged() {
+ inflateSettingsButton()
}
}
init {
- gestureDetector = GestureDetectorCompat(context, gestureListener)
mediaFrame = inflateMediaCarousel()
mediaCarousel = mediaFrame.requireViewById(R.id.media_carousel_scroller)
pageIndicator = mediaFrame.requireViewById(R.id.media_page_indicator)
- mediaCarousel.setOnScrollChangeListener(scrollChangedListener)
- mediaCarousel.setOnTouchListener(touchListener)
- mediaCarousel.setOverScrollMode(View.OVER_SCROLL_NEVER)
+ mediaCarouselScrollHandler = MediaCarouselScrollHandler(mediaCarousel, pageIndicator,
+ executor, mediaDataManager::onSwipeToDismiss, this::updatePageIndicatorLocation,
+ falsingManager)
+ inflateSettingsButton()
mediaContent = mediaCarousel.requireViewById(R.id.media_carousel)
+ configurationController.addCallback(configListener)
visualStabilityCallback = VisualStabilityManager.Callback {
if (needsReordering) {
needsReordering = false
@@ -142,31 +150,28 @@ class MediaViewManager @Inject constructor(
true /* persistent */)
mediaManager.addListener(object : MediaDataManager.Listener {
override fun onMediaDataLoaded(key: String, oldKey: String?, data: MediaData) {
- updateView(key, oldKey, data)
- updatePlayerVisibilities()
- mediaCarousel.requiresRemeasuring = true
+ oldKey?.let { mediaData.remove(it) }
+ if (!data.active && !Utils.useMediaResumption(context)) {
+ // This view is inactive, let's remove this! This happens e.g when dismissing /
+ // timing out a view. We still have the data around because resumption could
+ // be on, but we should save the resources and release this.
+ onMediaDataRemoved(key)
+ } else {
+ mediaData.put(key, data)
+ addOrUpdatePlayer(key, oldKey, data)
+ }
}
override fun onMediaDataRemoved(key: String) {
- val removed = mediaPlayers.remove(key)
- removed?.apply {
- val beforeActive = mediaContent.indexOfChild(removed.view?.player) <=
- activeMediaIndex
- mediaContent.removeView(removed.view?.player)
- removed.onDestroy()
- updateMediaPaddings()
- if (beforeActive) {
- // also update the index here since the scroll below might not always lead
- // to a scrolling changed
- activeMediaIndex = Math.max(0, activeMediaIndex - 1)
- mediaCarousel.scrollX = Math.max(mediaCarousel.scrollX -
- playerWidthPlusPadding, 0)
- }
- updatePlayerVisibilities()
- updatePageIndicator()
- }
+ mediaData.remove(key)
+ removePlayer(key)
}
})
+ mediaFrame.addOnLayoutChangeListener { _, _, _, _, _, _, _, _, _ ->
+ // The pageIndicator is not laid out yet when we get the current state update,
+ // Lets make sure we have the right dimensions
+ updatePageIndicatorLocation()
+ }
mediaHostStatesManager.addCallback(object : MediaHostStatesManager.Callback {
override fun onHostStateChanged(location: Int, mediaHostState: MediaHostState) {
if (location == desiredLocation) {
@@ -176,6 +181,20 @@ class MediaViewManager @Inject constructor(
})
}
+ private fun inflateSettingsButton() {
+ val settings = LayoutInflater.from(context).inflate(R.layout.media_carousel_settings_button,
+ mediaFrame, false) as View
+ if (this::settingsButton.isInitialized) {
+ mediaFrame.removeView(settingsButton)
+ }
+ settingsButton = settings
+ mediaFrame.addView(settingsButton)
+ mediaCarouselScrollHandler.onSettingsButtonUpdated(settings)
+ settingsButton.setOnClickListener {
+ activityStarter.startActivity(settingsIntent, true /* dismissShade */)
+ }
+ }
+
private fun inflateMediaCarousel(): ViewGroup {
return LayoutInflater.from(context).inflate(R.layout.media_carousel,
UniqueObjectHostView(context), false) as ViewGroup
@@ -189,71 +208,10 @@ class MediaViewManager @Inject constructor(
mediaContent.addView(view, 0)
}
}
- updateMediaPaddings()
- updatePlayerVisibilities()
- }
-
- private fun onMediaScrollingChanged(newIndex: Int, scrollInAmount: Int) {
- val wasScrolledIn = scrollIntoCurrentMedia != 0
- scrollIntoCurrentMedia = scrollInAmount
- val nowScrolledIn = scrollIntoCurrentMedia != 0
- if (newIndex != activeMediaIndex || wasScrolledIn != nowScrolledIn) {
- activeMediaIndex = newIndex
- updatePlayerVisibilities()
- }
- val location = activeMediaIndex.toFloat() + if (playerWidthPlusPadding > 0)
- scrollInAmount.toFloat() / playerWidthPlusPadding else 0f
- pageIndicator.setLocation(location)
- }
-
- private fun onTouch(view: View, motionEvent: MotionEvent?): Boolean {
- if (gestureDetector.onTouchEvent(motionEvent)) {
- return true
- }
- if (motionEvent?.getAction() == MotionEvent.ACTION_UP) {
- val pos = mediaCarousel.scrollX % playerWidthPlusPadding
- if (pos > playerWidthPlusPadding / 2) {
- mediaCarousel.smoothScrollBy(playerWidthPlusPadding - pos, 0)
- } else {
- mediaCarousel.smoothScrollBy(-1 * pos, 0)
- }
- return true
- }
- return view.onTouchEvent(motionEvent)
- }
-
- private fun onFling(
- eStart: MotionEvent?,
- eCurrent: MotionEvent?,
- vX: Float,
- vY: Float
- ): Boolean {
- if (vX * vX < 0.5 * vY * vY) {
- return false
- }
- if (vX * vX < FLING_SLOP) {
- return false
- }
- val pos = mediaCarousel.scrollX
- val currentIndex = if (playerWidthPlusPadding > 0) pos / playerWidthPlusPadding else 0
- var destIndex = if (vX <= 0) currentIndex + 1 else currentIndex
- destIndex = Math.max(0, destIndex)
- destIndex = Math.min(mediaContent.getChildCount() - 1, destIndex)
- val view = mediaContent.getChildAt(destIndex)
- mediaCarousel.smoothScrollTo(view.left, mediaCarousel.scrollY)
- return true
+ mediaCarouselScrollHandler.onPlayersChanged()
}
- private fun updatePlayerVisibilities() {
- val scrolledIn = scrollIntoCurrentMedia != 0
- for (i in 0 until mediaContent.childCount) {
- val view = mediaContent.getChildAt(i)
- val visible = (i == activeMediaIndex) || ((i == (activeMediaIndex + 1)) && scrolledIn)
- view.visibility = if (visible) View.VISIBLE else View.INVISIBLE
- }
- }
-
- private fun updateView(key: String, oldKey: String?, data: MediaData) {
+ private fun addOrUpdatePlayer(key: String, oldKey: String?, data: MediaData) {
// If the key was changed, update entry
val oldData = mediaPlayers[oldKey]
if (oldData != null) {
@@ -265,6 +223,7 @@ class MediaViewManager @Inject constructor(
existingPlayer = mediaControlPanelFactory.get()
existingPlayer.attach(PlayerViewHolder.create(LayoutInflater.from(context),
mediaContent))
+ existingPlayer.mediaViewController.sizeChangedListener = this::updateCarouselDimensions
mediaPlayers[key] = existingPlayer
val lp = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT)
@@ -286,21 +245,30 @@ class MediaViewManager @Inject constructor(
}
}
existingPlayer?.bind(data)
- updateMediaPaddings()
updatePageIndicator()
+ mediaCarouselScrollHandler.onPlayersChanged()
+ mediaCarousel.requiresRemeasuring = true
}
- private fun updateMediaPaddings() {
- val padding = context.resources.getDimensionPixelSize(R.dimen.qs_media_padding)
- val childCount = mediaContent.childCount
- for (i in 0 until childCount) {
- val mediaView = mediaContent.getChildAt(i)
- val desiredPaddingEnd = if (i == childCount - 1) 0 else padding
- val layoutParams = mediaView.layoutParams as ViewGroup.MarginLayoutParams
- if (layoutParams.marginEnd != desiredPaddingEnd) {
- layoutParams.marginEnd = desiredPaddingEnd
- mediaView.layoutParams = layoutParams
- }
+ private fun removePlayer(key: String) {
+ val removed = mediaPlayers.remove(key)
+ removed?.apply {
+ mediaCarouselScrollHandler.onPrePlayerRemoved(removed)
+ mediaContent.removeView(removed.view?.player)
+ removed.onDestroy()
+ mediaCarouselScrollHandler.onPlayersChanged()
+ updatePageIndicator()
+ }
+ }
+
+ private fun recreatePlayers() {
+ // Note that this will scramble the order of players. Actively playing sessions will, at
+ // least, still be put in the front. If we want to maintain order, then more work is
+ // needed.
+ mediaData.forEach {
+ key, data ->
+ removePlayer(key)
+ addOrUpdatePlayer(key = key, oldKey = null, data = data)
}
}
@@ -315,6 +283,12 @@ class MediaViewManager @Inject constructor(
/**
* Set a new interpolated state for all players. This is a state that is usually controlled
* by a finger movement where the user drags from one state to the next.
+ *
+ * @param startLocation the start location of our state or -1 if this is directly set
+ * @param endLocation the ending location of our state.
+ * @param progress the progress of the transition between startLocation and endlocation. If
+ * this is not a guided transformation, this will be 1.0f
+ * @param immediately should this state be applied immediately, canceling all animations?
*/
fun setCurrentState(
@MediaLocation startLocation: Int,
@@ -322,9 +296,6 @@ class MediaViewManager @Inject constructor(
progress: Float,
immediately: Boolean
) {
- // Hack: Since the indicator doesn't move with the player expansion, just make it disappear
- // and then reappear at the end.
- pageIndicator.alpha = if (progress == 1f || progress == 0f) 1f else 0f
if (startLocation != currentStartLocation ||
endLocation != currentEndLocation ||
progress != currentTransitionProgress ||
@@ -336,6 +307,51 @@ class MediaViewManager @Inject constructor(
for (mediaPlayer in mediaPlayers.values) {
updatePlayerToState(mediaPlayer, immediately)
}
+ maybeResetSettingsCog()
+ }
+ }
+
+ private fun updatePageIndicatorLocation() {
+ // Update the location of the page indicator, carousel clipping
+ pageIndicator.translationX = (currentCarouselWidth - pageIndicator.width) / 2.0f +
+ mediaCarouselScrollHandler.contentTranslation
+ val layoutParams = pageIndicator.layoutParams as ViewGroup.MarginLayoutParams
+ pageIndicator.translationY = (currentCarouselHeight - pageIndicator.height -
+ layoutParams.bottomMargin).toFloat()
+ }
+
+ /**
+ * Update the dimension of this carousel.
+ */
+ private fun updateCarouselDimensions() {
+ var width = 0
+ var height = 0
+ for (mediaPlayer in mediaPlayers.values) {
+ val controller = mediaPlayer.mediaViewController
+ width = Math.max(width, controller.currentWidth)
+ height = Math.max(height, controller.currentHeight)
+ }
+ if (width != currentCarouselWidth || height != currentCarouselHeight) {
+ currentCarouselWidth = width
+ currentCarouselHeight = height
+ mediaCarouselScrollHandler.setCarouselBounds(currentCarouselWidth, currentCarouselHeight)
+ updatePageIndicatorLocation()
+ }
+ }
+
+ private fun maybeResetSettingsCog() {
+ val hostStates = mediaHostStatesManager.mediaHostStates
+ val endShowsActive = hostStates[currentEndLocation]?.showsOnlyActiveMedia
+ ?: true
+ val startShowsActive = hostStates[currentStartLocation]?.showsOnlyActiveMedia
+ ?: endShowsActive
+ if (currentlyShowingOnlyActive != endShowsActive ||
+ ((currentTransitionProgress != 1.0f && currentTransitionProgress != 0.0f) &&
+ startShowsActive != endShowsActive)) {
+ /// Whenever we're transitioning from between differing states or the endstate differs
+ // we reset the translation
+ currentlyShowingOnlyActive = endShowsActive
+ mediaCarouselScrollHandler.resetTranslation(animate = true)
}
}
@@ -377,6 +393,15 @@ class MediaViewManager @Inject constructor(
}
mediaPlayer.mediaViewController.onLocationPreChange(desiredLocation)
}
+ mediaCarouselScrollHandler.showsSettingsButton = !it.showsOnlyActiveMedia
+ mediaCarouselScrollHandler.falsingProtectionNeeded = it.falsingProtectionNeeded
+ val nowVisible = it.visible
+ if (nowVisible != playersVisible) {
+ playersVisible = nowVisible
+ if (nowVisible) {
+ mediaCarouselScrollHandler.resetTranslation()
+ }
+ }
updateCarouselSize()
}
}
@@ -393,16 +418,7 @@ class MediaViewManager @Inject constructor(
carouselMeasureHeight = height
playerWidthPlusPadding = carouselMeasureWidth + context.resources.getDimensionPixelSize(
R.dimen.qs_media_padding)
- // The player width has changed, let's update the scroll position to make sure
- // it's still at the same place
- var newScroll = activeMediaIndex * playerWidthPlusPadding
- if (scrollIntoCurrentMedia > playerWidthPlusPadding) {
- newScroll += playerWidthPlusPadding -
- (scrollIntoCurrentMedia - playerWidthPlusPadding)
- } else {
- newScroll += scrollIntoCurrentMedia
- }
- mediaCarousel.scrollX = newScroll
+ mediaCarouselScrollHandler.playerWidthPlusPadding = playerWidthPlusPadding
// Let's remeasure the carousel
val widthSpec = desiredHostState?.measurementInput?.widthMeasureSpec ?: 0
val heightSpec = desiredHostState?.measurementInput?.heightMeasureSpec ?: 0
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselScrollHandler.kt b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselScrollHandler.kt
new file mode 100644
index 000000000000..993c05fbbd6f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselScrollHandler.kt
@@ -0,0 +1,516 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.media
+
+import android.graphics.Outline
+import android.util.MathUtils
+import android.view.GestureDetector
+import android.view.MotionEvent
+import android.view.View
+import android.view.ViewGroup
+import android.view.ViewOutlineProvider
+import androidx.core.view.GestureDetectorCompat
+import androidx.dynamicanimation.animation.FloatPropertyCompat
+import androidx.dynamicanimation.animation.SpringForce
+import com.android.settingslib.Utils
+import com.android.systemui.Gefingerpoken
+import com.android.systemui.qs.PageIndicator
+import com.android.systemui.R
+import com.android.systemui.plugins.FalsingManager
+import com.android.systemui.util.animation.PhysicsAnimator
+import com.android.systemui.util.concurrency.DelayableExecutor
+
+private const val FLING_SLOP = 1000000
+private const val DISMISS_DELAY = 100L
+private const val RUBBERBAND_FACTOR = 0.2f
+private const val SETTINGS_BUTTON_TRANSLATION_FRACTION = 0.3f
+
+/**
+ * Default spring configuration to use for animations where stiffness and/or damping ratio
+ * were not provided, and a default spring was not set via [PhysicsAnimator.setDefaultSpringConfig].
+ */
+private val translationConfig = PhysicsAnimator.SpringConfig(
+ SpringForce.STIFFNESS_MEDIUM,
+ SpringForce.DAMPING_RATIO_LOW_BOUNCY)
+
+/**
+ * A controller class for the media scrollview, responsible for touch handling
+ */
+class MediaCarouselScrollHandler(
+ private val scrollView: MediaScrollView,
+ private val pageIndicator: PageIndicator,
+ private val mainExecutor: DelayableExecutor,
+ private val dismissCallback: () -> Unit,
+ private var translationChangedListener: () -> Unit,
+ private val falsingManager: FalsingManager
+) {
+ /**
+ * Do we need falsing protection?
+ */
+ var falsingProtectionNeeded: Boolean = false
+ /**
+ * The width of the carousel
+ */
+ private var carouselWidth: Int = 0
+
+ /**
+ * The height of the carousel
+ */
+ private var carouselHeight: Int = 0
+
+ /**
+ * How much are we scrolled into the current media?
+ */
+ private var cornerRadius: Int = 0
+
+ /**
+ * The content where the players are added
+ */
+ private var mediaContent: ViewGroup
+ /**
+ * The gesture detector to detect touch gestures
+ */
+ private val gestureDetector: GestureDetectorCompat
+
+ /**
+ * The settings button view
+ */
+ private lateinit var settingsButton: View
+
+ /**
+ * What's the currently active player index?
+ */
+ var activeMediaIndex: Int = 0
+ private set
+ /**
+ * How much are we scrolled into the current media?
+ */
+ private var scrollIntoCurrentMedia: Int = 0
+
+ /**
+ * how much is the content translated in X
+ */
+ var contentTranslation = 0.0f
+ private set(value) {
+ field = value
+ mediaContent.translationX = value
+ updateSettingsPresentation()
+ translationChangedListener.invoke()
+ updateClipToOutline()
+ }
+
+ /**
+ * The width of a player including padding
+ */
+ var playerWidthPlusPadding: Int = 0
+ set(value) {
+ field = value
+ // The player width has changed, let's update the scroll position to make sure
+ // it's still at the same place
+ var newScroll = activeMediaIndex * playerWidthPlusPadding
+ if (scrollIntoCurrentMedia > playerWidthPlusPadding) {
+ newScroll += playerWidthPlusPadding -
+ (scrollIntoCurrentMedia - playerWidthPlusPadding)
+ } else {
+ newScroll += scrollIntoCurrentMedia
+ }
+ scrollView.scrollX = newScroll
+ }
+
+ /**
+ * Does the dismiss currently show the setting cog?
+ */
+ var showsSettingsButton: Boolean = false
+
+ /**
+ * A utility to detect gestures, used in the touch listener
+ */
+ private val gestureListener = object : GestureDetector.SimpleOnGestureListener() {
+ override fun onFling(
+ eStart: MotionEvent?,
+ eCurrent: MotionEvent?,
+ vX: Float,
+ vY: Float
+ ) = onFling(vX, vY)
+
+ override fun onScroll(
+ down: MotionEvent?,
+ lastMotion: MotionEvent?,
+ distanceX: Float,
+ distanceY: Float
+ ) = onScroll(down!!, lastMotion!!, distanceX)
+
+ override fun onDown(e: MotionEvent?): Boolean {
+ if (falsingProtectionNeeded) {
+ falsingManager.onNotificationStartDismissing()
+ }
+ return false
+ }
+ }
+
+ /**
+ * The touch listener for the scroll view
+ */
+ private val touchListener = object : Gefingerpoken {
+ override fun onTouchEvent(motionEvent: MotionEvent?) = onTouch(motionEvent!!)
+ override fun onInterceptTouchEvent(ev: MotionEvent?) = onInterceptTouch(ev!!)
+ }
+
+ /**
+ * A listener that is invoked when the scrolling changes to update player visibilities
+ */
+ private val scrollChangedListener = object : View.OnScrollChangeListener {
+ override fun onScrollChange(
+ v: View?,
+ scrollX: Int,
+ scrollY: Int,
+ oldScrollX: Int,
+ oldScrollY: Int
+ ) {
+ if (playerWidthPlusPadding == 0) {
+ return
+ }
+ onMediaScrollingChanged(scrollX / playerWidthPlusPadding,
+ scrollX % playerWidthPlusPadding)
+ }
+ }
+
+ init {
+ gestureDetector = GestureDetectorCompat(scrollView.context, gestureListener)
+ scrollView.touchListener = touchListener
+ scrollView.setOverScrollMode(View.OVER_SCROLL_NEVER)
+ mediaContent = scrollView.contentContainer
+ scrollView.setOnScrollChangeListener(scrollChangedListener)
+ scrollView.outlineProvider = object : ViewOutlineProvider() {
+ override fun getOutline(view: View?, outline: Outline?) {
+ outline?.setRoundRect(0, 0, carouselWidth, carouselHeight, cornerRadius.toFloat())
+ }
+ }
+ }
+
+ fun onSettingsButtonUpdated(button: View) {
+ settingsButton = button
+ // We don't have a context to resolve, lets use the settingsbuttons one since that is
+ // reinflated appropriately
+ cornerRadius = settingsButton.resources.getDimensionPixelSize(
+ Utils.getThemeAttr(settingsButton.context, android.R.attr.dialogCornerRadius))
+ updateSettingsPresentation()
+ scrollView.invalidateOutline()
+ }
+
+ private fun updateSettingsPresentation() {
+ if (showsSettingsButton) {
+ val settingsOffset = MathUtils.map(
+ 0.0f,
+ getMaxTranslation().toFloat(),
+ 0.0f,
+ 1.0f,
+ Math.abs(contentTranslation))
+ val settingsTranslation = (1.0f - settingsOffset) * -settingsButton.width *
+ SETTINGS_BUTTON_TRANSLATION_FRACTION
+ val newTranslationX: Float
+ if (contentTranslation > 0) {
+ newTranslationX = settingsTranslation
+ } else {
+ newTranslationX = scrollView.width - settingsTranslation - settingsButton.width
+ }
+ val rotation = (1.0f - settingsOffset) * 50
+ settingsButton.rotation = rotation * -Math.signum(contentTranslation)
+ val alpha = MathUtils.map(0.5f, 1.0f, 0.0f, 1.0f, settingsOffset)
+ settingsButton.alpha = alpha
+ settingsButton.visibility = if (alpha != 0.0f) View.VISIBLE else View.INVISIBLE
+ settingsButton.translationX = newTranslationX
+ settingsButton.translationY = (scrollView.height - settingsButton.height) / 2.0f
+ } else {
+ settingsButton.visibility = View.INVISIBLE
+ }
+ }
+
+ private fun onTouch(motionEvent: MotionEvent): Boolean {
+ val isUp = motionEvent.action == MotionEvent.ACTION_UP
+ if (isUp && falsingProtectionNeeded) {
+ falsingManager.onNotificationStopDismissing()
+ }
+ if (gestureDetector.onTouchEvent(motionEvent)) {
+ if (isUp) {
+ // If this is an up and we're flinging, we don't want to have this touch reach
+ // the view, otherwise that would scroll, while we are trying to snap to the
+ // new page. Let's dispatch a cancel instead.
+ scrollView.cancelCurrentScroll()
+ return true
+ } else {
+ // Pass touches to the scrollView
+ return false
+ }
+ }
+ if (isUp || motionEvent.action == MotionEvent.ACTION_CANCEL) {
+ // It's an up and the fling didn't take it above
+ val pos = scrollView.scrollX % playerWidthPlusPadding
+ val scollXAmount: Int
+ if (pos > playerWidthPlusPadding / 2) {
+ scollXAmount = playerWidthPlusPadding - pos
+ } else {
+ scollXAmount = -1 * pos
+ }
+ if (scollXAmount != 0) {
+ // Delay the scrolling since scrollView calls springback which cancels
+ // the animation again..
+ mainExecutor.execute {
+ scrollView.smoothScrollBy(scollXAmount, 0)
+ }
+ }
+ val currentTranslation = scrollView.getContentTranslation()
+ if (currentTranslation != 0.0f) {
+ // We started a Swipe but didn't end up with a fling. Let's either go to the
+ // dismissed position or go back.
+ val springBack = Math.abs(currentTranslation) < getMaxTranslation() / 2
+ || isFalseTouch()
+ val newTranslation: Float
+ if (springBack) {
+ newTranslation = 0.0f
+ } else {
+ newTranslation = getMaxTranslation() * Math.signum(currentTranslation)
+ if (!showsSettingsButton) {
+ // Delay the dismiss a bit to avoid too much overlap. Waiting until the
+ // animation has finished also feels a bit too slow here.
+ mainExecutor.executeDelayed({
+ dismissCallback.invoke()
+ }, DISMISS_DELAY)
+ }
+ }
+ PhysicsAnimator.getInstance(this).spring(CONTENT_TRANSLATION,
+ newTranslation, startVelocity = 0.0f, config = translationConfig).start()
+ scrollView.animationTargetX = newTranslation
+ }
+ }
+ // Always pass touches to the scrollView
+ return false
+ }
+
+ private fun isFalseTouch() = falsingProtectionNeeded && falsingManager.isFalseTouch
+
+ private fun getMaxTranslation() = if (showsSettingsButton) {
+ settingsButton.width
+ } else {
+ playerWidthPlusPadding
+ }
+
+ private fun onInterceptTouch(motionEvent: MotionEvent): Boolean {
+ return gestureDetector.onTouchEvent(motionEvent)
+ }
+
+ fun onScroll(down: MotionEvent,
+ lastMotion: MotionEvent,
+ distanceX: Float): Boolean {
+ val totalX = lastMotion.x - down.x
+ val currentTranslation = scrollView.getContentTranslation()
+ if (currentTranslation != 0.0f ||
+ !scrollView.canScrollHorizontally((-totalX).toInt())) {
+ var newTranslation = currentTranslation - distanceX
+ val absTranslation = Math.abs(newTranslation)
+ if (absTranslation > getMaxTranslation()) {
+ // Rubberband all translation above the maximum
+ if (Math.signum(distanceX) != Math.signum(currentTranslation)) {
+ // The movement is in the same direction as our translation,
+ // Let's rubberband it.
+ if (Math.abs(currentTranslation) > getMaxTranslation()) {
+ // we were already overshooting before. Let's add the distance
+ // fully rubberbanded.
+ newTranslation = currentTranslation - distanceX * RUBBERBAND_FACTOR
+ } else {
+ // We just crossed the boundary, let's rubberband it all
+ newTranslation = Math.signum(newTranslation) * (getMaxTranslation() +
+ (absTranslation - getMaxTranslation()) * RUBBERBAND_FACTOR)
+ }
+ } // Otherwise we don't have do do anything, and will remove the unrubberbanded
+ // translation
+ }
+ if (Math.signum(newTranslation) != Math.signum(currentTranslation)
+ && currentTranslation != 0.0f) {
+ // We crossed the 0.0 threshold of the translation. Let's see if we're allowed
+ // to scroll into the new direction
+ if (scrollView.canScrollHorizontally(-newTranslation.toInt())) {
+ // We can actually scroll in the direction where we want to translate,
+ // Let's make sure to stop at 0
+ newTranslation = 0.0f
+ }
+ }
+ val physicsAnimator = PhysicsAnimator.getInstance(this)
+ if (physicsAnimator.isRunning()) {
+ physicsAnimator.spring(CONTENT_TRANSLATION,
+ newTranslation, startVelocity = 0.0f, config = translationConfig).start()
+ } else {
+ contentTranslation = newTranslation
+ }
+ scrollView.animationTargetX = newTranslation
+ return true
+ }
+ return false
+ }
+
+ private fun onFling(
+ vX: Float,
+ vY: Float
+ ): Boolean {
+ if (vX * vX < 0.5 * vY * vY) {
+ return false
+ }
+ if (vX * vX < FLING_SLOP) {
+ return false
+ }
+ val currentTranslation = scrollView.getContentTranslation()
+ if (currentTranslation != 0.0f) {
+ // We're translated and flung. Let's see if the fling is in the same direction
+ val newTranslation: Float
+ if (Math.signum(vX) != Math.signum(currentTranslation) || isFalseTouch()) {
+ // The direction of the fling isn't the same as the translation, let's go to 0
+ newTranslation = 0.0f
+ } else {
+ newTranslation = getMaxTranslation() * Math.signum(currentTranslation)
+ // Delay the dismiss a bit to avoid too much overlap. Waiting until the animation
+ // has finished also feels a bit too slow here.
+ if (!showsSettingsButton) {
+ mainExecutor.executeDelayed({
+ dismissCallback.invoke()
+ }, DISMISS_DELAY)
+ }
+ }
+ PhysicsAnimator.getInstance(this).spring(CONTENT_TRANSLATION,
+ newTranslation, startVelocity = vX, config = translationConfig).start()
+ scrollView.animationTargetX = newTranslation
+ } else {
+ // We're flinging the player! Let's go either to the previous or to the next player
+ val pos = scrollView.scrollX
+ val currentIndex = if (playerWidthPlusPadding > 0) pos / playerWidthPlusPadding else 0
+ var destIndex = if (vX <= 0) currentIndex + 1 else currentIndex
+ destIndex = Math.max(0, destIndex)
+ destIndex = Math.min(mediaContent.getChildCount() - 1, destIndex)
+ val view = mediaContent.getChildAt(destIndex)
+ // We need to post this since we're dispatching a touch to the underlying view to cancel
+ // but canceling will actually abort the animation.
+ mainExecutor.execute {
+ scrollView.smoothScrollTo(view.left, scrollView.scrollY)
+ }
+ }
+ return true
+ }
+
+ /**
+ * Reset the translation of the players when swiped
+ */
+ fun resetTranslation(animate: Boolean = false) {
+ if (scrollView.getContentTranslation() != 0.0f) {
+ if (animate) {
+ PhysicsAnimator.getInstance(this).spring(CONTENT_TRANSLATION,
+ 0.0f, config = translationConfig).start()
+ scrollView.animationTargetX = 0.0f
+ } else {
+ PhysicsAnimator.getInstance(this).cancel()
+ contentTranslation = 0.0f
+ }
+ }
+ }
+
+ private fun updateClipToOutline() {
+ val clip = contentTranslation != 0.0f || scrollIntoCurrentMedia != 0
+ scrollView.clipToOutline = clip
+ }
+
+ private fun onMediaScrollingChanged(newIndex: Int, scrollInAmount: Int) {
+ val wasScrolledIn = scrollIntoCurrentMedia != 0
+ scrollIntoCurrentMedia = scrollInAmount
+ val nowScrolledIn = scrollIntoCurrentMedia != 0
+ if (newIndex != activeMediaIndex || wasScrolledIn != nowScrolledIn) {
+ activeMediaIndex = newIndex
+ updatePlayerVisibilities()
+ }
+ val location = activeMediaIndex.toFloat() + if (playerWidthPlusPadding > 0)
+ scrollInAmount.toFloat() / playerWidthPlusPadding else 0f
+ pageIndicator.setLocation(location)
+ updateClipToOutline()
+ }
+
+ /**
+ * Notified whenever the players or their order has changed
+ */
+ fun onPlayersChanged() {
+ updatePlayerVisibilities()
+ updateMediaPaddings()
+ }
+
+ private fun updateMediaPaddings() {
+ val padding = scrollView.context.resources.getDimensionPixelSize(R.dimen.qs_media_padding)
+ val childCount = mediaContent.childCount
+ for (i in 0 until childCount) {
+ val mediaView = mediaContent.getChildAt(i)
+ val desiredPaddingEnd = if (i == childCount - 1) 0 else padding
+ val layoutParams = mediaView.layoutParams as ViewGroup.MarginLayoutParams
+ if (layoutParams.marginEnd != desiredPaddingEnd) {
+ layoutParams.marginEnd = desiredPaddingEnd
+ mediaView.layoutParams = layoutParams
+ }
+ }
+ }
+
+ private fun updatePlayerVisibilities() {
+ val scrolledIn = scrollIntoCurrentMedia != 0
+ for (i in 0 until mediaContent.childCount) {
+ val view = mediaContent.getChildAt(i)
+ val visible = (i == activeMediaIndex) || ((i == (activeMediaIndex + 1)) && scrolledIn)
+ view.visibility = if (visible) View.VISIBLE else View.INVISIBLE
+ }
+ }
+
+ /**
+ * Notify that a player will be removed right away. This gives us the opporunity to look
+ * where it was and update our scroll position.
+ */
+ fun onPrePlayerRemoved(removed: MediaControlPanel) {
+ val beforeActive = mediaContent.indexOfChild(removed.view?.player) <= activeMediaIndex
+ if (beforeActive) {
+ // also update the index here since the scroll below might not always lead
+ // to a scrolling changed
+ activeMediaIndex = Math.max(0, activeMediaIndex - 1)
+ scrollView.scrollX = Math.max(scrollView.scrollX -
+ playerWidthPlusPadding, 0)
+ }
+ }
+
+ /**
+ * Update the bounds of the carousel
+ */
+ fun setCarouselBounds(currentCarouselWidth: Int, currentCarouselHeight: Int) {
+ if (currentCarouselHeight != carouselHeight || currentCarouselWidth != carouselHeight) {
+ carouselWidth = currentCarouselWidth
+ carouselHeight = currentCarouselHeight
+ scrollView.invalidateOutline()
+ }
+ }
+
+ companion object {
+ private val CONTENT_TRANSLATION = object : FloatPropertyCompat<MediaCarouselScrollHandler>(
+ "contentTranslation") {
+ override fun getValue(handler: MediaCarouselScrollHandler): Float {
+ return handler.contentTranslation
+ }
+
+ override fun setValue(handler: MediaCarouselScrollHandler, value: Float) {
+ handler.contentTranslation = value
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
index 50081001e65a..3fc162ead6d1 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
@@ -20,19 +20,16 @@ import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.res.ColorStateList;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Color;
+import android.graphics.Outline;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
-import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.Icon;
-import android.graphics.drawable.RippleDrawable;
import android.media.session.MediaController;
import android.media.session.MediaSession;
import android.media.session.PlaybackState;
import android.util.Log;
import android.view.View;
+import android.view.ViewOutlineProvider;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
@@ -41,8 +38,6 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.UiThread;
import androidx.constraintlayout.widget.ConstraintSet;
-import androidx.core.graphics.drawable.RoundedBitmapDrawable;
-import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory;
import com.android.settingslib.Utils;
import com.android.settingslib.media.MediaOutputSliceConstants;
@@ -52,8 +47,6 @@ import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.util.animation.TransitionLayout;
-import org.jetbrains.annotations.NotNull;
-
import java.util.List;
import java.util.concurrent.Executor;
@@ -64,6 +57,7 @@ import javax.inject.Inject;
*/
public class MediaControlPanel {
private static final String TAG = "MediaControlPanel";
+ private static final float DISABLED_ALPHA = 0.38f;
// Button IDs for QS controls
static final int[] ACTION_IDS = {
@@ -87,6 +81,8 @@ public class MediaControlPanel {
private int mBackgroundColor;
private int mAlbumArtSize;
private int mAlbumArtRadius;
+ // This will provide the corners for the album art.
+ private final ViewOutlineProvider mViewOutlineProvider;
/**
* Initialize a new control panel
@@ -96,14 +92,21 @@ public class MediaControlPanel {
*/
@Inject
public MediaControlPanel(Context context, @Background Executor backgroundExecutor,
- ActivityStarter activityStarter, MediaHostStatesManager mediaHostStatesManager,
+ ActivityStarter activityStarter, MediaViewController mediaViewController,
SeekBarViewModel seekBarViewModel) {
mContext = context;
mBackgroundExecutor = backgroundExecutor;
mActivityStarter = activityStarter;
mSeekBarViewModel = seekBarViewModel;
- mMediaViewController = new MediaViewController(context, mediaHostStatesManager);
+ mMediaViewController = mediaViewController;
loadDimens();
+
+ mViewOutlineProvider = new ViewOutlineProvider() {
+ @Override
+ public void getOutline(View view, Outline outline) {
+ outline.setRoundRect(0, 0, mAlbumArtSize, mAlbumArtSize, mAlbumArtRadius);
+ }
+ };
}
public void onDestroy() {
@@ -162,6 +165,11 @@ public class MediaControlPanel {
public void attach(PlayerViewHolder vh) {
mViewHolder = vh;
TransitionLayout player = vh.getPlayer();
+
+ ImageView albumView = vh.getAlbumView();
+ albumView.setOutlineProvider(mViewOutlineProvider);
+ albumView.setClipToOutline(true);
+
mSeekBarObserver = new SeekBarObserver(vh);
mSeekBarViewModel.getProgress().observeForever(mSeekBarObserver);
mSeekBarViewModel.attachTouchHandlers(vh.getSeekBar());
@@ -171,7 +179,7 @@ public class MediaControlPanel {
/**
* Bind this view based on the data given
*/
- public void bind(@NotNull MediaData data) {
+ public void bind(@NonNull MediaData data) {
if (mViewHolder == null) {
return;
}
@@ -202,11 +210,9 @@ public class MediaControlPanel {
}
ImageView albumView = mViewHolder.getAlbumView();
- // TODO: migrate this to a view with rounded corners instead of baking the rounding
- // into the bitmap
boolean hasArtwork = data.getArtwork() != null;
if (hasArtwork) {
- Drawable artwork = createRoundedBitmap(data.getArtwork());
+ Drawable artwork = scaleDrawable(data.getArtwork());
albumView.setImageDrawable(artwork);
}
setVisibleAndAlpha(collapsedSet, R.id.album_art, hasArtwork);
@@ -250,26 +256,29 @@ public class MediaControlPanel {
ImageView iconView = mViewHolder.getSeamlessIcon();
TextView deviceName = mViewHolder.getSeamlessText();
- // Update the outline color
- RippleDrawable bkgDrawable = (RippleDrawable) mViewHolder.getSeamless().getForeground();
- GradientDrawable rect = (GradientDrawable) bkgDrawable.getDrawable(0);
- rect.setStroke(2, deviceName.getCurrentTextColor());
- rect.setColor(Color.TRANSPARENT);
-
final MediaDeviceData device = data.getDevice();
- if (device != null && !device.getEnabled()) {
- mViewHolder.getSeamless().setEnabled(false);
- // TODO(b/156875717): setEnabled should cause the alpha to change.
- mViewHolder.getSeamless().setAlpha(0.38f);
- iconView.setImageResource(R.drawable.ic_hardware_speaker);
- iconView.setVisibility(View.VISIBLE);
- deviceName.setText(R.string.media_seamless_remote_device);
+ final int seamlessId = mViewHolder.getSeamless().getId();
+ final int seamlessFallbackId = mViewHolder.getSeamlessFallback().getId();
+ final boolean showFallback = device != null && !device.getEnabled();
+ final int seamlessFallbackVisibility = showFallback ? View.VISIBLE : View.GONE;
+ mViewHolder.getSeamlessFallback().setVisibility(seamlessFallbackVisibility);
+ expandedSet.setVisibility(seamlessFallbackId, seamlessFallbackVisibility);
+ collapsedSet.setVisibility(seamlessFallbackId, seamlessFallbackVisibility);
+ final int seamlessVisibility = showFallback ? View.GONE : View.VISIBLE;
+ mViewHolder.getSeamless().setVisibility(seamlessVisibility);
+ expandedSet.setVisibility(seamlessId, seamlessVisibility);
+ collapsedSet.setVisibility(seamlessId, seamlessVisibility);
+ final float seamlessAlpha = data.getResumption() ? DISABLED_ALPHA : 1.0f;
+ expandedSet.setAlpha(seamlessId, seamlessAlpha);
+ collapsedSet.setAlpha(seamlessId, seamlessAlpha);
+ // Disable clicking on output switcher for resumption controls.
+ mViewHolder.getSeamless().setEnabled(!data.getResumption());
+ if (showFallback) {
+ iconView.setImageDrawable(null);
+ deviceName.setText(null);
} else if (device != null) {
- mViewHolder.getSeamless().setEnabled(true);
- mViewHolder.getSeamless().setAlpha(1f);
Drawable icon = device.getIcon();
iconView.setVisibility(View.VISIBLE);
-
if (icon instanceof AdaptiveIcon) {
AdaptiveIcon aIcon = (AdaptiveIcon) icon;
aIcon.setBackgroundColor(mBackgroundColor);
@@ -281,8 +290,6 @@ public class MediaControlPanel {
} else {
// Reset to default
Log.w(TAG, "device is null. Not binding output chip.");
- mViewHolder.getSeamless().setEnabled(true);
- mViewHolder.getSeamless().setAlpha(1f);
iconView.setVisibility(View.GONE);
deviceName.setText(com.android.internal.R.string.ext_media_seamless_action);
}
@@ -331,7 +338,7 @@ public class MediaControlPanel {
}
@UiThread
- private Drawable createRoundedBitmap(Icon icon) {
+ private Drawable scaleDrawable(Icon icon) {
if (icon == null) {
return null;
}
@@ -352,22 +359,7 @@ public class MediaControlPanel {
bounds.offset((int) -offsetX,(int) -offsetY);
}
drawable.setBounds(bounds);
- Bitmap scaled = Bitmap.createBitmap(mAlbumArtSize, mAlbumArtSize,
- Bitmap.Config.ARGB_8888);
- Canvas canvas = new Canvas(scaled);
- drawable.draw(canvas);
- RoundedBitmapDrawable artwork = RoundedBitmapDrawableFactory.create(
- mContext.getResources(), scaled);
- artwork.setCornerRadius(mAlbumArtRadius);
- return artwork;
- }
-
- /**
- * Return the token for the current media session
- * @return the token
- */
- public MediaSession.Token getMediaSessionToken() {
- return mToken;
+ return drawable;
}
/**
@@ -379,25 +371,6 @@ public class MediaControlPanel {
}
/**
- * Get the name of the package associated with the current media controller
- * @return the package name, or null if no controller
- */
- public String getMediaPlayerPackage() {
- if (mController == null) {
- return null;
- }
- return mController.getPackageName();
- }
-
- /**
- * Check whether this player has an attached media session.
- * @return whether there is a controller with a current media session.
- */
- public boolean hasMediaSession() {
- return mController != null && mController.getPlaybackState() != null;
- }
-
- /**
* Check whether the media controlled by this player is currently playing
* @return whether it is playing, or false if no controller information
*/
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaData.kt b/packages/SystemUI/src/com/android/systemui/media/MediaData.kt
index 5d28178a3b1b..8c9cb1b240bf 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaData.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaData.kt
@@ -25,19 +25,70 @@ import android.media.session.MediaSession
data class MediaData(
val initialized: Boolean = false,
val backgroundColor: Int,
+ /**
+ * App name that will be displayed on the player.
+ */
val app: String?,
+ /**
+ * Icon shown on player, close to app name.
+ */
val appIcon: Drawable?,
+ /**
+ * Artist name.
+ */
val artist: CharSequence?,
+ /**
+ * Song name.
+ */
val song: CharSequence?,
+ /**
+ * Album artwork.
+ */
val artwork: Icon?,
+ /**
+ * List of actions that can be performed on the player: prev, next, play, pause, etc.
+ */
val actions: List<MediaAction>,
+ /**
+ * Same as above, but shown on smaller versions of the player, like in QQS or keyguard.
+ */
val actionsToShowInCompact: List<Int>,
+ /**
+ * Package name of the app that's posting the media.
+ */
val packageName: String,
+ /**
+ * Unique media session identifier.
+ */
val token: MediaSession.Token?,
+ /**
+ * Action to perform when the player is tapped.
+ * This is unrelated to {@link #actions}.
+ */
val clickIntent: PendingIntent?,
+ /**
+ * Where the media is playing: phone, headphones, ear buds, remote session.
+ */
val device: MediaDeviceData?,
+ /**
+ * When active, a player will be displayed on keyguard and quick-quick settings.
+ * This is unrelated to the stream being playing or not, a player will not be active if
+ * timed out, or in resumption mode.
+ */
+ var active: Boolean,
+ /**
+ * Action that should be performed to restart a non active session.
+ */
var resumeAction: Runnable?,
- val notificationKey: String = "INVALID",
+ /**
+ * Indicates that this player is a resumption player (ie. It only shows a play actions which
+ * will start the app and start playing).
+ */
+ var resumption: Boolean = false,
+ /**
+ * Notification key for cancelling a media player after a timeout (when not using resumption.)
+ */
+ val notificationKey: String? = null,
var hasCheckedForResume: Boolean = false
)
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
index 5fe39958fd67..5052386e65e1 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
@@ -38,18 +38,19 @@ import android.service.notification.StatusBarNotification
import android.text.TextUtils
import android.util.Log
import com.android.internal.graphics.ColorUtils
+import com.android.systemui.Dumpable
import com.android.systemui.R
import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
-import com.android.systemui.statusbar.NotificationMediaManager
+import com.android.systemui.dump.DumpManager
import com.android.systemui.statusbar.notification.MediaNotificationProcessor
-import com.android.systemui.statusbar.notification.NotificationEntryManager
-import com.android.systemui.statusbar.notification.NotificationEntryManager.UNDEFINED_DISMISS_REASON
import com.android.systemui.statusbar.notification.row.HybridGroupManager
import com.android.systemui.util.Assert
import com.android.systemui.util.Utils
+import java.io.FileDescriptor
import java.io.IOException
+import java.io.PrintWriter
import java.util.concurrent.Executor
import javax.inject.Inject
import javax.inject.Singleton
@@ -67,7 +68,7 @@ private const val LUMINOSITY_THRESHOLD = 0.05f
private const val SATURATION_MULTIPLIER = 0.8f
private val LOADING = MediaData(false, 0, null, null, null, null, null,
- emptyList(), emptyList(), "INVALID", null, null, null, null)
+ emptyList(), emptyList(), "INVALID", null, null, null, true, null)
fun isMediaNotification(sbn: StatusBarNotification): Boolean {
if (!sbn.notification.hasMediaSession()) {
@@ -85,20 +86,35 @@ fun isMediaNotification(sbn: StatusBarNotification): Boolean {
* A class that facilitates management and loading of Media Data, ready for binding.
*/
@Singleton
-class MediaDataManager @Inject constructor(
+class MediaDataManager(
private val context: Context,
- private val mediaControllerFactory: MediaControllerFactory,
- private val mediaTimeoutListener: MediaTimeoutListener,
- private val notificationEntryManager: NotificationEntryManager,
- private val mediaResumeListener: MediaResumeListener,
@Background private val backgroundExecutor: Executor,
@Main private val foregroundExecutor: Executor,
- private val broadcastDispatcher: BroadcastDispatcher
-) {
+ private val mediaControllerFactory: MediaControllerFactory,
+ private val broadcastDispatcher: BroadcastDispatcher,
+ dumpManager: DumpManager,
+ mediaTimeoutListener: MediaTimeoutListener,
+ mediaResumeListener: MediaResumeListener,
+ private var useMediaResumption: Boolean,
+ private val useQsMediaPlayer: Boolean
+) : Dumpable {
private val listeners: MutableSet<Listener> = mutableSetOf()
private val mediaEntries: LinkedHashMap<String, MediaData> = LinkedHashMap()
- private val useMediaResumption: Boolean = Utils.useMediaResumption(context)
+
+ @Inject
+ constructor(
+ context: Context,
+ @Background backgroundExecutor: Executor,
+ @Main foregroundExecutor: Executor,
+ mediaControllerFactory: MediaControllerFactory,
+ dumpManager: DumpManager,
+ broadcastDispatcher: BroadcastDispatcher,
+ mediaTimeoutListener: MediaTimeoutListener,
+ mediaResumeListener: MediaResumeListener
+ ) : this(context, backgroundExecutor, foregroundExecutor, mediaControllerFactory,
+ broadcastDispatcher, dumpManager, mediaTimeoutListener, mediaResumeListener,
+ Utils.useMediaResumption(context), Utils.useQsMediaPlayer(context))
private val userChangeReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
@@ -128,22 +144,13 @@ class MediaDataManager @Inject constructor(
}
init {
+ dumpManager.registerDumpable(TAG, this)
mediaTimeoutListener.timeoutCallback = { token: String, timedOut: Boolean ->
setTimedOut(token, timedOut) }
addListener(mediaTimeoutListener)
- if (useMediaResumption) {
- mediaResumeListener.addTrackToResumeCallback = { desc: MediaDescription,
- resumeAction: Runnable, token: MediaSession.Token, appName: String,
- appIntent: PendingIntent, packageName: String ->
- addResumptionControls(desc, resumeAction, token, appName, appIntent, packageName)
- }
- mediaResumeListener.resumeComponentFoundCallback = { key: String, action: Runnable? ->
- mediaEntries.get(key)?.resumeAction = action
- mediaEntries.get(key)?.hasCheckedForResume = true
- }
- addListener(mediaResumeListener)
- }
+ mediaResumeListener.setManager(this)
+ addListener(mediaResumeListener)
val userFilter = IntentFilter(Intent.ACTION_USER_SWITCHED)
broadcastDispatcher.registerReceiver(userChangeReceiver, userFilter, null, UserHandle.ALL)
@@ -160,8 +167,13 @@ class MediaDataManager @Inject constructor(
context.registerReceiver(appChangeReceiver, uninstallFilter)
}
+ fun destroy() {
+ context.unregisterReceiver(appChangeReceiver)
+ broadcastDispatcher.unregisterReceiver(userChangeReceiver)
+ }
+
fun onNotificationAdded(key: String, sbn: StatusBarNotification) {
- if (Utils.useQsMediaPlayer(context) && isMediaNotification(sbn)) {
+ if (useQsMediaPlayer && isMediaNotification(sbn)) {
Assert.isMainThread()
val oldKey = findExistingEntry(key, sbn.packageName)
if (oldKey == null) {
@@ -201,7 +213,14 @@ class MediaDataManager @Inject constructor(
}
}
- private fun addResumptionControls(
+ fun setResumeAction(key: String, action: Runnable?) {
+ mediaEntries.get(key)?.let {
+ it.resumeAction = action
+ it.hasCheckedForResume = true
+ }
+ }
+
+ fun addResumptionControls(
desc: MediaDescription,
action: Runnable,
token: MediaSession.Token,
@@ -211,11 +230,12 @@ class MediaDataManager @Inject constructor(
) {
// Resume controls don't have a notification key, so store by package name instead
if (!mediaEntries.containsKey(packageName)) {
- val resumeData = LOADING.copy(packageName = packageName, resumeAction = action)
+ val resumeData = LOADING.copy(packageName = packageName, resumeAction = action,
+ hasCheckedForResume = true)
mediaEntries.put(packageName, resumeData)
}
backgroundExecutor.execute {
- loadMediaDataInBg(desc, action, token, appName, appIntent, packageName)
+ loadMediaDataInBgForResumption(desc, action, token, appName, appIntent, packageName)
}
}
@@ -254,17 +274,22 @@ class MediaDataManager @Inject constructor(
*/
fun removeListener(listener: Listener) = listeners.remove(listener)
+ /**
+ * Called whenever the player has been paused or stopped for a while.
+ * This will make the player not active anymore, hiding it from QQS and Keyguard.
+ * @see MediaData.active
+ */
private fun setTimedOut(token: String, timedOut: Boolean) {
- if (!timedOut) {
- return
- }
mediaEntries[token]?.let {
- notificationEntryManager.removeNotification(it.notificationKey, null /* ranking */,
- UNDEFINED_DISMISS_REASON)
+ if (it.active == !timedOut) {
+ return
+ }
+ it.active = !timedOut
+ onMediaDataLoaded(token, token, it)
}
}
- private fun loadMediaDataInBg(
+ private fun loadMediaDataInBgForResumption(
desc: MediaDescription,
resumeAction: Runnable,
token: MediaSession.Token,
@@ -272,13 +297,10 @@ class MediaDataManager @Inject constructor(
appIntent: PendingIntent,
packageName: String
) {
- if (resumeAction == null) {
- Log.e(TAG, "Resume action cannot be null")
- return
- }
-
if (TextUtils.isEmpty(desc.title)) {
Log.e(TAG, "Description incomplete")
+ // Delete the placeholder entry
+ mediaEntries.remove(packageName)
return
}
@@ -294,12 +316,15 @@ class MediaDataManager @Inject constructor(
} else {
null
}
+ val bgColor = artworkBitmap?.let { computeBackgroundColor(it) } ?: Color.DKGRAY
val mediaAction = getResumeMediaAction(resumeAction)
foregroundExecutor.execute {
- onMediaDataLoaded(packageName, null, MediaData(true, Color.DKGRAY, appName,
- null, desc.subtitle, desc.title, artworkIcon, listOf(mediaAction), listOf(0),
- packageName, token, appIntent, null, resumeAction, packageName))
+ onMediaDataLoaded(packageName, null, MediaData(true, bgColor, appName,
+ null, desc.subtitle, desc.title, artworkIcon, listOf(mediaAction), listOf(0),
+ packageName, token, appIntent, device = null, active = false,
+ resumeAction = resumeAction, resumption = true, notificationKey = packageName,
+ hasCheckedForResume = true))
}
}
@@ -319,7 +344,6 @@ class MediaDataManager @Inject constructor(
// Foreground and Background colors computed from album art
val notif: Notification = sbn.notification
- var bgColor = Color.WHITE
var artworkBitmap = metadata.getBitmap(MediaMetadata.METADATA_KEY_ART)
if (artworkBitmap == null) {
artworkBitmap = metadata.getBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART)
@@ -349,26 +373,8 @@ class MediaDataManager @Inject constructor(
drawable.draw(canvas)
}
}
- val p = MediaNotificationProcessor.generateArtworkPaletteBuilder(artworkBitmap)
- .generate()
- val swatch = MediaNotificationProcessor.findBackgroundSwatch(p)
- bgColor = swatch.rgb
- }
- // Adapt background color, so it's always subdued and text is legible
- val tmpHsl = floatArrayOf(0f, 0f, 0f)
- ColorUtils.colorToHSL(bgColor, tmpHsl)
-
- val l = tmpHsl[2]
- // Colors with very low luminosity can have any saturation. This means that changing the
- // luminosity can make a black become red. Let's remove the saturation of very light or
- // very dark colors to avoid this issue.
- if (l < LUMINOSITY_THRESHOLD || l > 1f - LUMINOSITY_THRESHOLD) {
- tmpHsl[1] = 0f
}
- tmpHsl[1] *= SATURATION_MULTIPLIER
- tmpHsl[2] = DEFAULT_LUMINOSITY
-
- bgColor = ColorUtils.HSLToColor(tmpHsl)
+ val bgColor = computeBackgroundColor(artworkBitmap)
// App name
val builder = Notification.Builder.recoverBuilder(context, notif)
@@ -426,11 +432,14 @@ class MediaDataManager @Inject constructor(
}
}
- val resumeAction: Runnable? = mediaEntries.get(key)?.resumeAction
foregroundExecutor.execute {
+ val resumeAction: Runnable? = mediaEntries[key]?.resumeAction
+ val hasCheckedForResume = mediaEntries[key]?.hasCheckedForResume == true
+ val active = mediaEntries[key]?.active ?: true
onMediaDataLoaded(key, oldKey, MediaData(true, bgColor, app, smallIconDrawable, artist,
song, artWorkIcon, actionIcons, actionsToShowCollapsed, sbn.packageName, token,
- notif.contentIntent, null, resumeAction, key))
+ notif.contentIntent, null, active, resumeAction = resumeAction,
+ notificationKey = key, hasCheckedForResume = hasCheckedForResume))
}
}
@@ -479,6 +488,33 @@ class MediaDataManager @Inject constructor(
}
}
+ private fun computeBackgroundColor(artworkBitmap: Bitmap?): Int {
+ var color = Color.WHITE
+ if (artworkBitmap != null) {
+ // If we have art, get colors from that
+ val p = MediaNotificationProcessor.generateArtworkPaletteBuilder(artworkBitmap)
+ .generate()
+ val swatch = MediaNotificationProcessor.findBackgroundSwatch(p)
+ color = swatch.rgb
+ }
+ // Adapt background color, so it's always subdued and text is legible
+ val tmpHsl = floatArrayOf(0f, 0f, 0f)
+ ColorUtils.colorToHSL(color, tmpHsl)
+
+ val l = tmpHsl[2]
+ // Colors with very low luminosity can have any saturation. This means that changing the
+ // luminosity can make a black become red. Let's remove the saturation of very light or
+ // very dark colors to avoid this issue.
+ if (l < LUMINOSITY_THRESHOLD || l > 1f - LUMINOSITY_THRESHOLD) {
+ tmpHsl[1] = 0f
+ }
+ tmpHsl[1] *= SATURATION_MULTIPLIER
+ tmpHsl[2] = DEFAULT_LUMINOSITY
+
+ color = ColorUtils.HSLToColor(tmpHsl)
+ return color
+ }
+
private fun getResumeMediaAction(action: Runnable): MediaAction {
return MediaAction(
context.getDrawable(R.drawable.lb_ic_play),
@@ -507,7 +543,7 @@ class MediaDataManager @Inject constructor(
val data = mediaEntries.remove(key)!!
val resumeAction = getResumeMediaAction(data.resumeAction!!)
val updated = data.copy(token = null, actions = listOf(resumeAction),
- actionsToShowInCompact = listOf(0))
+ actionsToShowInCompact = listOf(0), active = false, resumption = true)
mediaEntries.put(data.packageName, updated)
// Notify listeners of "new" controls
val listenersCopy = listeners.toSet()
@@ -528,21 +564,44 @@ class MediaDataManager @Inject constructor(
/**
* Are there any media notifications active?
*/
- fun hasActiveMedia() = mediaEntries.any({ isActive(it.value) })
+ fun hasActiveMedia() = mediaEntries.any { it.value.active }
+
+ /**
+ * Are there any media entries we should display?
+ * If resumption is enabled, this will include inactive players
+ * If resumption is disabled, we only want to show active players
+ */
+ fun hasAnyMedia() = if (useMediaResumption) mediaEntries.isNotEmpty() else hasActiveMedia()
- fun isActive(data: MediaData): Boolean {
- if (data.token == null) {
- return false
+ fun setMediaResumptionEnabled(isEnabled: Boolean) {
+ if (useMediaResumption == isEnabled) {
+ return
+ }
+
+ useMediaResumption = isEnabled
+
+ if (!useMediaResumption) {
+ // Remove any existing resume controls
+ val listenersCopy = listeners.toSet()
+ val filtered = mediaEntries.filter { !it.value.active }
+ filtered.forEach {
+ mediaEntries.remove(it.key)
+ listenersCopy.forEach { listener ->
+ listener.onMediaDataRemoved(it.key)
+ }
+ }
}
- val controller = mediaControllerFactory.create(data.token)
- val state = controller?.playbackState?.state
- return state != null && NotificationMediaManager.isActiveState(state)
}
/**
- * Are there any media entries, including resume controls?
+ * Invoked when the user has dismissed the media carousel
*/
- fun hasAnyMedia() = mediaEntries.isNotEmpty()
+ fun onSwipeToDismiss() {
+ val mediaKeys = mediaEntries.keys.toSet()
+ mediaKeys.forEach {
+ setTimedOut(it, timedOut = true)
+ }
+ }
interface Listener {
@@ -560,4 +619,12 @@ class MediaDataManager @Inject constructor(
*/
fun onMediaDataRemoved(key: String) {}
}
+
+ override fun dump(fd: FileDescriptor, pw: PrintWriter, args: Array<out String>) {
+ pw.apply {
+ println("listeners: $listeners")
+ println("mediaEntries: $mediaEntries")
+ println("useMediaResumption: $useMediaResumption")
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt
index de0af16bc2fa..7ae2dc5c0941 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt
@@ -22,6 +22,10 @@ import android.media.session.MediaController
import com.android.settingslib.media.LocalMediaManager
import com.android.settingslib.media.MediaDevice
import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.Dumpable
+import com.android.systemui.dump.DumpManager
+import java.io.FileDescriptor
+import java.io.PrintWriter
import java.util.concurrent.Executor
import javax.inject.Inject
import javax.inject.Singleton
@@ -35,13 +39,15 @@ class MediaDeviceManager @Inject constructor(
private val localMediaManagerFactory: LocalMediaManagerFactory,
private val mr2manager: MediaRouter2Manager,
@Main private val fgExecutor: Executor,
- private val mediaDataManager: MediaDataManager
-) : MediaDataManager.Listener {
+ private val mediaDataManager: MediaDataManager,
+ private val dumpManager: DumpManager
+) : MediaDataManager.Listener, Dumpable {
private val listeners: MutableSet<Listener> = mutableSetOf()
private val entries: MutableMap<String, Token> = mutableMapOf()
init {
mediaDataManager.addListener(this)
+ dumpManager.registerDumpable(javaClass.name, this)
}
/**
@@ -81,6 +87,17 @@ class MediaDeviceManager @Inject constructor(
}
}
+ override fun dump(fd: FileDescriptor, pw: PrintWriter, args: Array<String>) {
+ with(pw) {
+ println("MediaDeviceManager state:")
+ entries.forEach {
+ key, entry ->
+ println(" key=$key")
+ entry.dump(fd, pw, args)
+ }
+ }
+ }
+
private fun processDevice(key: String, device: MediaDevice?) {
val enabled = device != null
val data = MediaDeviceData(enabled, device?.iconWithoutBackground, device?.name)
@@ -122,6 +139,17 @@ class MediaDeviceManager @Inject constructor(
localMediaManager.stopScan()
localMediaManager.unregisterCallback(this)
}
+ fun dump(fd: FileDescriptor, pw: PrintWriter, args: Array<String>) {
+ val route = controller?.let {
+ mr2manager.getRoutingSessionForMediaController(it)
+ }
+ with(pw) {
+ println(" current device is ${current?.name}")
+ val type = controller?.playbackInfo?.playbackType
+ println(" PlaybackType=$type (1 for local, 2 for remote)")
+ println(" route=$route")
+ }
+ }
override fun onDeviceListUpdate(devices: List<MediaDevice>?) = fgExecutor.execute {
updateCurrent()
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt
index b86e1d0503d4..c41e6104833e 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt
@@ -49,7 +49,7 @@ class MediaHierarchyManager @Inject constructor(
private val statusBarStateController: SysuiStatusBarStateController,
private val keyguardStateController: KeyguardStateController,
private val bypassController: KeyguardBypassController,
- private val mediaViewManager: MediaViewManager,
+ private val mediaCarouselController: MediaCarouselController,
private val notifLockscreenUserManager: NotificationLockscreenUserManager,
wakefulnessLifecycle: WakefulnessLifecycle
) {
@@ -65,7 +65,7 @@ class MediaHierarchyManager @Inject constructor(
private var animationStartBounds: Rect = Rect()
private var targetBounds: Rect = Rect()
private val mediaFrame
- get() = mediaViewManager.mediaFrame
+ get() = mediaCarouselController.mediaFrame
private var statusbarState: Int = statusBarStateController.state
private var animator = ValueAnimator.ofFloat(0.0f, 1.0f).apply {
interpolator = Interpolators.FAST_OUT_SLOW_IN
@@ -140,6 +140,18 @@ class MediaHierarchyManager @Inject constructor(
}
/**
+ * Is the shade currently collapsing from the expanded qs? If we're on the lockscreen and in qs,
+ * we wouldn't want to transition in that case.
+ */
+ var collapsingShadeFromQS: Boolean = false
+ set(value) {
+ if (field != value) {
+ field = value
+ updateDesiredLocation(forceNoAnimation = true)
+ }
+ }
+
+ /**
* Are location changes currently blocked?
*/
private val blockLocationChanges: Boolean
@@ -161,6 +173,19 @@ class MediaHierarchyManager @Inject constructor(
}
/**
+ * Are we currently fullyAwake
+ */
+ private var fullyAwake: Boolean = false
+ set(value) {
+ if (field != value) {
+ field = value
+ if (value) {
+ updateDesiredLocation(forceNoAnimation = true)
+ }
+ }
+ }
+
+ /**
* Is the doze animation currently Running
*/
private var dozeAnimationRunning: Boolean = false
@@ -193,6 +218,8 @@ class MediaHierarchyManager @Inject constructor(
override fun onDozingChanged(isDozing: Boolean) {
if (!isDozing) {
dozeAnimationRunning = false
+ } else {
+ updateDesiredLocation()
}
}
})
@@ -204,10 +231,12 @@ class MediaHierarchyManager @Inject constructor(
override fun onStartedGoingToSleep() {
goingToSleep = true
+ fullyAwake = false
}
override fun onFinishedWakingUp() {
goingToSleep = false
+ fullyAwake = true
}
override fun onStartedWakingUp() {
@@ -225,6 +254,10 @@ class MediaHierarchyManager @Inject constructor(
fun register(mediaObject: MediaHost): UniqueObjectHostView {
val viewHost = createUniqueObjectHost()
mediaObject.hostView = viewHost
+ mediaObject.addVisibilityChangeListener {
+ // Never animate because of a visibility change, only state changes should do that
+ updateDesiredLocation(forceNoAnimation = true)
+ }
mediaHosts[mediaObject.location] = mediaObject
if (mediaObject.location == desiredLocation) {
// In case we are overriding a view that is already visible, make sure we attach it
@@ -258,8 +291,10 @@ class MediaHierarchyManager @Inject constructor(
/**
* Updates the location that the view should be in. If it changes, an animation may be triggered
* going from the old desired location to the new one.
+ *
+ * @param forceNoAnimation optional parameter telling the system not to animate
*/
- private fun updateDesiredLocation() {
+ private fun updateDesiredLocation(forceNoAnimation: Boolean = false) {
val desiredLocation = calculateLocation()
if (desiredLocation != this.desiredLocation) {
if (this.desiredLocation >= 0) {
@@ -268,11 +303,12 @@ class MediaHierarchyManager @Inject constructor(
val isNewView = this.desiredLocation == -1
this.desiredLocation = desiredLocation
// Let's perform a transition
- val animate = shouldAnimateTransition(desiredLocation, previousLocation)
+ val animate = !forceNoAnimation &&
+ shouldAnimateTransition(desiredLocation, previousLocation)
val (animDuration, delay) = getAnimationParams(previousLocation, desiredLocation)
val host = getHost(desiredLocation)
- mediaViewManager.onDesiredLocationChanged(desiredLocation, host, animate, animDuration,
- delay)
+ mediaCarouselController.onDesiredLocationChanged(desiredLocation, host, animate,
+ animDuration, delay)
performTransitionToNewLocation(isNewView, animate)
}
}
@@ -455,7 +491,7 @@ class MediaHierarchyManager @Inject constructor(
val startLocation = if (currentlyInGuidedTransformation) previousLocation else -1
val progress = if (currentlyInGuidedTransformation) getTransformationProgress() else 1.0f
val endLocation = desiredLocation
- mediaViewManager.setCurrentState(startLocation, endLocation, progress, immediately)
+ mediaCarouselController.setCurrentState(startLocation, endLocation, progress, immediately)
updateHostAttachment()
if (currentAttachmentLocation == IN_OVERLAY) {
mediaFrame.setLeftTopRightBottom(
@@ -510,12 +546,31 @@ class MediaHierarchyManager @Inject constructor(
(statusbarState == StatusBarState.KEYGUARD ||
statusbarState == StatusBarState.FULLSCREEN_USER_SWITCHER))
val allowedOnLockscreen = notifLockscreenUserManager.shouldShowLockscreenNotifications()
- return when {
+ val location = when {
qsExpansion > 0.0f && !onLockscreen -> LOCATION_QS
qsExpansion > 0.4f && onLockscreen -> LOCATION_QS
onLockscreen && allowedOnLockscreen -> LOCATION_LOCKSCREEN
else -> LOCATION_QQS
}
+ // When we're on lock screen and the player is not active, we should keep it in QS.
+ // Otherwise it will try to animate a transition that doesn't make sense.
+ if (location == LOCATION_LOCKSCREEN && getHost(location)?.visible != true &&
+ !statusBarStateController.isDozing) {
+ return LOCATION_QS
+ }
+ if (location == LOCATION_LOCKSCREEN && desiredLocation == LOCATION_QS &&
+ collapsingShadeFromQS) {
+ // When collapsing on the lockscreen, we want to remain in QS
+ return LOCATION_QS
+ }
+ if (location != LOCATION_LOCKSCREEN && desiredLocation == LOCATION_LOCKSCREEN
+ && !fullyAwake) {
+ // When unlocking from dozing / while waking up, the media shouldn't be transitioning
+ // in an animated way. Let's keep it in the lockscreen until we're fully awake and
+ // reattach it without an animation
+ return LOCATION_LOCKSCREEN
+ }
+ return location
}
companion object {
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaHost.kt b/packages/SystemUI/src/com/android/systemui/media/MediaHost.kt
index 2bd8c0cbeab2..1ae9d3ff4ca5 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaHost.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaHost.kt
@@ -1,6 +1,8 @@
package com.android.systemui.media
+import android.graphics.PointF
import android.graphics.Rect
+import android.util.ArraySet
import android.view.View
import android.view.View.OnAttachStateChangeListener
import com.android.systemui.util.animation.MeasurementInput
@@ -19,9 +21,7 @@ class MediaHost @Inject constructor(
lateinit var hostView: UniqueObjectHostView
var location: Int = -1
private set
- var visibleChangedListener: ((Boolean) -> Unit)? = null
- var visible: Boolean = false
- private set
+ private var visibleChangedListeners: ArraySet<(Boolean) -> Unit> = ArraySet()
private val tmpLocationOnScreen: IntArray = intArrayOf(0, 0)
@@ -59,6 +59,10 @@ class MediaHost @Inject constructor(
}
}
+ fun addVisibilityChangeListener(listener: (Boolean) -> Unit) {
+ visibleChangedListeners.add(listener)
+ }
+
/**
* Initialize this MediaObject and create a host view.
* All state should already be set on this host before calling this method in order to avoid
@@ -109,16 +113,22 @@ class MediaHost @Inject constructor(
}
private fun updateViewVisibility() {
- if (showsOnlyActiveMedia) {
- visible = mediaDataManager.hasActiveMedia()
+ visible = if (showsOnlyActiveMedia) {
+ mediaDataManager.hasActiveMedia()
} else {
- visible = mediaDataManager.hasAnyMedia()
+ mediaDataManager.hasAnyMedia()
+ }
+ val newVisibility = if (visible) View.VISIBLE else View.GONE
+ if (newVisibility != hostView.visibility) {
+ hostView.visibility = newVisibility
+ visibleChangedListeners.forEach {
+ it.invoke(visible)
+ }
}
- hostView.visibility = if (visible) View.VISIBLE else View.GONE
- visibleChangedListener?.invoke(visible)
}
class MediaHostStateHolder @Inject constructor() : MediaHostState {
+ private var gonePivot: PointF = PointF()
override var measurementInput: MeasurementInput? = null
set(value) {
@@ -144,6 +154,34 @@ class MediaHost @Inject constructor(
}
}
+ override var visible: Boolean = true
+ set(value) {
+ if (field == value) {
+ return
+ }
+ field = value
+ changedListener?.invoke()
+ }
+
+ override var falsingProtectionNeeded: Boolean = false
+ set(value) {
+ if (field == value) {
+ return
+ }
+ field = value
+ changedListener?.invoke()
+ }
+
+ override fun getPivotX(): Float = gonePivot.x
+ override fun getPivotY(): Float = gonePivot.y
+ override fun setGonePivot(x: Float, y: Float) {
+ if (gonePivot.equals(x, y)) {
+ return
+ }
+ gonePivot.set(x, y)
+ changedListener?.invoke()
+ }
+
/**
* A listener for all changes. This won't be copied over when invoking [copy]
*/
@@ -157,6 +195,9 @@ class MediaHost @Inject constructor(
mediaHostState.expansion = expansion
mediaHostState.showsOnlyActiveMedia = showsOnlyActiveMedia
mediaHostState.measurementInput = measurementInput?.copy()
+ mediaHostState.visible = visible
+ mediaHostState.gonePivot.set(gonePivot)
+ mediaHostState.falsingProtectionNeeded = falsingProtectionNeeded
return mediaHostState
}
@@ -173,13 +214,25 @@ class MediaHost @Inject constructor(
if (showsOnlyActiveMedia != other.showsOnlyActiveMedia) {
return false
}
+ if (visible != other.visible) {
+ return false
+ }
+ if (falsingProtectionNeeded != other.falsingProtectionNeeded) {
+ return false
+ }
+ if (!gonePivot.equals(other.getPivotX(), other.getPivotY())) {
+ return false
+ }
return true
}
override fun hashCode(): Int {
var result = measurementInput?.hashCode() ?: 0
result = 31 * result + expansion.hashCode()
+ result = 31 * result + falsingProtectionNeeded.hashCode()
result = 31 * result + showsOnlyActiveMedia.hashCode()
+ result = 31 * result + if (visible) 1 else 2
+ result = 31 * result + gonePivot.hashCode()
return result
}
}
@@ -194,7 +247,8 @@ interface MediaHostState {
var measurementInput: MeasurementInput?
/**
- * The expansion of the player, 0 for fully collapsed, 1 for fully expanded
+ * The expansion of the player, 0 for fully collapsed (up to 3 actions), 1 for fully expanded
+ * (up to 5 actions.)
*/
var expansion: Float
@@ -204,6 +258,35 @@ interface MediaHostState {
var showsOnlyActiveMedia: Boolean
/**
+ * If the view should be VISIBLE or GONE.
+ */
+ var visible: Boolean
+
+ /**
+ * Does this host need any falsing protection?
+ */
+ var falsingProtectionNeeded: Boolean
+
+ /**
+ * Sets the pivot point when clipping the height or width.
+ * Clipping happens when animating visibility when we're visible in QS but not on QQS,
+ * for example.
+ */
+ fun setGonePivot(x: Float, y: Float)
+
+ /**
+ * x position of pivot, from 0 to 1
+ * @see [setGonePivot]
+ */
+ fun getPivotX(): Float
+
+ /**
+ * y position of pivot, from 0 to 1
+ * @see [setGonePivot]
+ */
+ fun getPivotY(): Float
+
+ /**
* Get a copy of this view state, deepcopying all appropriate members
*/
fun copy(): MediaHostState
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaResumeListener.kt b/packages/SystemUI/src/com/android/systemui/media/MediaResumeListener.kt
index e8a4b1e46fec..0cc1e7bb1b56 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaResumeListener.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaResumeListener.kt
@@ -16,7 +16,6 @@
package com.android.systemui.media
-import android.app.PendingIntent
import android.content.BroadcastReceiver
import android.content.ComponentName
import android.content.Context
@@ -25,12 +24,13 @@ import android.content.IntentFilter
import android.content.pm.PackageManager
import android.media.MediaDescription
import android.media.session.MediaController
-import android.media.session.MediaSession
import android.os.UserHandle
+import android.provider.Settings
import android.service.media.MediaBrowserService
import android.util.Log
import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.tuner.TunerService
import com.android.systemui.util.Utils
import java.util.concurrent.ConcurrentLinkedQueue
import java.util.concurrent.Executor
@@ -46,21 +46,14 @@ private const val MEDIA_PREFERENCE_KEY = "browser_components_"
class MediaResumeListener @Inject constructor(
private val context: Context,
private val broadcastDispatcher: BroadcastDispatcher,
- @Background private val backgroundExecutor: Executor
+ @Background private val backgroundExecutor: Executor,
+ private val tunerService: TunerService
) : MediaDataManager.Listener {
- private val useMediaResumption: Boolean = Utils.useMediaResumption(context)
+ private var useMediaResumption: Boolean = Utils.useMediaResumption(context)
private val resumeComponents: ConcurrentLinkedQueue<ComponentName> = ConcurrentLinkedQueue()
- lateinit var addTrackToResumeCallback: (
- MediaDescription,
- Runnable,
- MediaSession.Token,
- String,
- PendingIntent,
- String
- ) -> Unit
- lateinit var resumeComponentFoundCallback: (String, Runnable?) -> Unit
+ private lateinit var mediaDataManager: MediaDataManager
private var mediaBrowser: ResumeMediaBrowser? = null
private var currentUserId: Int
@@ -96,8 +89,8 @@ class MediaResumeListener @Inject constructor(
}
Log.d(TAG, "Adding resume controls $desc")
- addTrackToResumeCallback(desc, resumeAction, token, appName.toString(), appIntent,
- component.packageName)
+ mediaDataManager.addResumptionControls(desc, resumeAction, token, appName.toString(),
+ appIntent, component.packageName)
}
}
@@ -113,6 +106,18 @@ class MediaResumeListener @Inject constructor(
}
}
+ fun setManager(manager: MediaDataManager) {
+ mediaDataManager = manager
+
+ // Add listener for resumption setting changes
+ tunerService.addTunable(object : TunerService.Tunable {
+ override fun onTuningChanged(key: String?, newValue: String?) {
+ useMediaResumption = Utils.useMediaResumption(context)
+ mediaDataManager.setMediaResumptionEnabled(useMediaResumption)
+ }
+ }, Settings.Secure.MEDIA_CONTROLS_RESUME)
+ }
+
private fun loadSavedComponents() {
// Make sure list is empty (if we switched users)
resumeComponents.clear()
@@ -165,7 +170,7 @@ class MediaResumeListener @Inject constructor(
}
} else {
// No service found
- resumeComponentFoundCallback(key, null)
+ mediaDataManager.setResumeAction(key, null)
}
}
}
@@ -182,7 +187,7 @@ class MediaResumeListener @Inject constructor(
object : ResumeMediaBrowser.Callback() {
override fun onConnected() {
Log.d(TAG, "yes we can resume with $componentName")
- resumeComponentFoundCallback(key, getResumeAction(componentName))
+ mediaDataManager.setResumeAction(key, getResumeAction(componentName))
updateResumptionList(componentName)
mediaBrowser?.disconnect()
mediaBrowser = null
@@ -190,7 +195,7 @@ class MediaResumeListener @Inject constructor(
override fun onError() {
Log.e(TAG, "Cannot resume with $componentName")
- resumeComponentFoundCallback(key, null)
+ mediaDataManager.setResumeAction(key, null)
mediaBrowser?.disconnect()
mediaBrowser = null
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaScrollView.kt b/packages/SystemUI/src/com/android/systemui/media/MediaScrollView.kt
new file mode 100644
index 000000000000..a079b06a0b10
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaScrollView.kt
@@ -0,0 +1,100 @@
+package com.android.systemui.media
+
+import android.content.Context
+import android.os.SystemClock
+import android.util.AttributeSet
+import android.view.InputDevice
+import android.view.MotionEvent
+import android.view.ViewGroup
+import android.widget.HorizontalScrollView
+import com.android.systemui.Gefingerpoken
+import com.android.systemui.util.animation.physicsAnimator
+
+/**
+ * A ScrollView used in Media that doesn't limit itself to the childs bounds. This is useful
+ * when only measuring children but not the parent, when trying to apply a new scroll position
+ */
+class MediaScrollView @JvmOverloads constructor(
+ context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0)
+ : HorizontalScrollView(context, attrs, defStyleAttr) {
+
+ lateinit var contentContainer: ViewGroup
+ private set
+ var touchListener: Gefingerpoken? = null
+
+ /**
+ * The target value of the translation X animation. Only valid if the physicsAnimator is running
+ */
+ var animationTargetX = 0.0f
+
+ /**
+ * Get the current content translation. This is usually the normal translationX of the content,
+ * but when animating, it might differ
+ */
+ fun getContentTranslation() = if (contentContainer.physicsAnimator.isRunning()) {
+ animationTargetX
+ } else {
+ contentContainer.translationX
+ }
+
+ /**
+ * Allow all scrolls to go through, use base implementation
+ */
+ override fun scrollTo(x: Int, y: Int) {
+ if (mScrollX != x || mScrollY != y) {
+ val oldX: Int = mScrollX
+ val oldY: Int = mScrollY
+ mScrollX = x
+ mScrollY = y
+ invalidateParentCaches()
+ onScrollChanged(mScrollX, mScrollY, oldX, oldY)
+ if (!awakenScrollBars()) {
+ postInvalidateOnAnimation()
+ }
+ }
+ }
+
+ override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean {
+ var intercept = false;
+ touchListener?.let {
+ intercept = it.onInterceptTouchEvent(ev)
+ }
+ return super.onInterceptTouchEvent(ev) || intercept;
+ }
+
+ override fun onTouchEvent(ev: MotionEvent?): Boolean {
+ var touch = false;
+ touchListener?.let {
+ touch = it.onTouchEvent(ev)
+ }
+ return super.onTouchEvent(ev) || touch
+ }
+
+ override fun onFinishInflate() {
+ super.onFinishInflate()
+ contentContainer = getChildAt(0) as ViewGroup
+ }
+
+ override fun overScrollBy(deltaX: Int, deltaY: Int, scrollX: Int, scrollY: Int,
+ scrollRangeX: Int, scrollRangeY: Int, maxOverScrollX: Int,
+ maxOverScrollY: Int, isTouchEvent: Boolean): Boolean {
+ if (getContentTranslation() != 0.0f) {
+ // When we're dismissing we ignore all the scrolling
+ return false
+ }
+ return super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX,
+ scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent)
+ }
+
+ /**
+ * Cancel the current touch event going on.
+ */
+ fun cancelCurrentScroll() {
+ val now = SystemClock.uptimeMillis()
+ val event = MotionEvent.obtain(now, now,
+ MotionEvent.ACTION_CANCEL, 0.0f, 0.0f, 0)
+ event.source = InputDevice.SOURCE_TOUCHSCREEN
+ super.onTouchEvent(event)
+ event.recycle()
+ }
+} \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaTimeoutListener.kt b/packages/SystemUI/src/com/android/systemui/media/MediaTimeoutListener.kt
index 3c3f4a977ee7..9a134dbe0264 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaTimeoutListener.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaTimeoutListener.kt
@@ -43,6 +43,11 @@ class MediaTimeoutListener @Inject constructor(
private val mediaListeners: MutableMap<String, PlaybackStateListener> = mutableMapOf()
+ /**
+ * Callback representing that a media object is now expired:
+ * @param token Media session unique identifier
+ * @param pauseTimeuot True when expired for {@code PAUSED_MEDIA_TIMEOUT}
+ */
lateinit var timeoutCallback: (String, Boolean) -> Unit
override fun onMediaDataLoaded(key: String, oldKey: String?, data: MediaData) {
@@ -66,6 +71,7 @@ class MediaTimeoutListener @Inject constructor(
) : MediaController.Callback() {
var timedOut = false
+ private var playing: Boolean? = null
// Resume controls may have null token
private val mediaController = if (data.token != null) {
@@ -77,6 +83,7 @@ class MediaTimeoutListener @Inject constructor(
init {
mediaController?.registerCallback(this)
+ onPlaybackStateChanged(mediaController?.playbackState)
}
fun destroy() {
@@ -88,7 +95,13 @@ class MediaTimeoutListener @Inject constructor(
Log.v(TAG, "onPlaybackStateChanged: $state")
}
- if (state == null || !isPlayingState(state.state)) {
+ val isPlaying = state != null && isPlayingState(state.state)
+ if (playing == isPlaying && playing != null) {
+ return
+ }
+ playing = isPlaying
+
+ if (!isPlaying) {
if (DEBUG) {
Log.v(TAG, "schedule timeout for $key")
}
@@ -112,11 +125,11 @@ class MediaTimeoutListener @Inject constructor(
}
}
- private fun expireMediaTimeout(mediaNotificationKey: String, reason: String) {
+ private fun expireMediaTimeout(mediaKey: String, reason: String) {
cancellation?.apply {
if (DEBUG) {
Log.v(TAG,
- "media timeout cancelled for $mediaNotificationKey, reason: $reason")
+ "media timeout cancelled for $mediaKey, reason: $reason")
}
run()
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaViewController.kt b/packages/SystemUI/src/com/android/systemui/media/MediaViewController.kt
index e82bb402407e..fc22c026974a 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaViewController.kt
@@ -17,22 +17,31 @@
package com.android.systemui.media
import android.content.Context
+import android.content.res.Configuration
+import android.graphics.PointF
import androidx.constraintlayout.widget.ConstraintSet
import com.android.systemui.R
+import com.android.systemui.statusbar.policy.ConfigurationController
+import com.android.systemui.util.animation.MeasurementOutput
import com.android.systemui.util.animation.TransitionLayout
import com.android.systemui.util.animation.TransitionLayoutController
import com.android.systemui.util.animation.TransitionViewState
-import com.android.systemui.util.animation.MeasurementOutput
+import javax.inject.Inject
/**
* A class responsible for controlling a single instance of a media player handling interactions
* with the view instance and keeping the media view states up to date.
*/
-class MediaViewController(
+class MediaViewController @Inject constructor(
context: Context,
- val mediaHostStatesManager: MediaHostStatesManager
+ private val configurationController: ConfigurationController,
+ private val mediaHostStatesManager: MediaHostStatesManager
) {
+ /**
+ * A listener when the current dimensions of the player change
+ */
+ lateinit var sizeChangedListener: () -> Unit
private var firstRefresh: Boolean = true
private var transitionLayout: TransitionLayout? = null
private val layoutController = TransitionLayoutController()
@@ -44,18 +53,20 @@ class MediaViewController(
/**
* A map containing all viewStates for all locations of this mediaState
*/
- private val mViewStates: MutableMap<MediaHostState, TransitionViewState?> = mutableMapOf()
+ private val viewStates: MutableMap<MediaHostState, TransitionViewState?> = mutableMapOf()
/**
* The ending location of the view where it ends when all animations and transitions have
* finished
*/
+ @MediaLocation
private var currentEndLocation: Int = -1
/**
* The ending location of the view where it ends when all animations and transitions have
* finished
*/
+ @MediaLocation
private var currentStartLocation: Int = -1
/**
@@ -69,10 +80,47 @@ class MediaViewController(
private val tmpState = TransitionViewState()
/**
+ * Temporary variable to avoid unnecessary allocations.
+ */
+ private val tmpPoint = PointF()
+
+ /**
+ * The current width of the player. This might not factor in case the player is animating
+ * to the current state, but represents the end state
+ */
+ var currentWidth: Int = 0
+ /**
+ * The current height of the player. This might not factor in case the player is animating
+ * to the current state, but represents the end state
+ */
+ var currentHeight: Int = 0
+
+ /**
+ * A callback for RTL config changes
+ */
+ private val configurationListener = object : ConfigurationController.ConfigurationListener {
+ override fun onConfigChanged(newConfig: Configuration?) {
+ // Because the TransitionLayout is not always attached (and calculates/caches layout
+ // results regardless of attach state), we have to force the layoutDirection of the view
+ // to the correct value for the user's current locale to ensure correct recalculation
+ // when/after calling refreshState()
+ newConfig?.apply {
+ if (transitionLayout?.rawLayoutDirection != layoutDirection) {
+ transitionLayout?.layoutDirection = layoutDirection
+ refreshState()
+ }
+ }
+ }
+ }
+
+ /**
* A callback for media state changes
*/
val stateCallback = object : MediaHostStatesManager.Callback {
- override fun onHostStateChanged(location: Int, mediaHostState: MediaHostState) {
+ override fun onHostStateChanged(
+ @MediaLocation location: Int,
+ mediaHostState: MediaHostState
+ ) {
if (location == currentEndLocation || location == currentStartLocation) {
setCurrentState(currentStartLocation,
currentEndLocation,
@@ -98,6 +146,12 @@ class MediaViewController(
collapsedLayout.load(context, R.xml.media_collapsed)
expandedLayout.load(context, R.xml.media_expanded)
mediaHostStatesManager.addController(this)
+ layoutController.sizeChangedListener = { width: Int, height: Int ->
+ currentWidth = width
+ currentHeight = height
+ sizeChangedListener.invoke()
+ }
+ configurationController.addCallback(configurationListener)
}
/**
@@ -105,6 +159,7 @@ class MediaViewController(
*/
fun onDestroy() {
mediaHostStatesManager.removeController(this)
+ configurationController.removeCallback(configurationListener)
}
private fun ensureAllMeasurements() {
@@ -125,7 +180,7 @@ class MediaViewController(
* it's not available, it will recreate one by measuring, which may be expensive.
*/
private fun obtainViewState(state: MediaHostState): TransitionViewState? {
- val viewState = mViewStates[state]
+ val viewState = viewStates[state]
if (viewState != null) {
// we already have cached this measurement, let's continue
return viewState
@@ -143,7 +198,7 @@ class MediaViewController(
// We don't want to cache interpolated or null states as this could quickly fill up
// our cache. We only cache the start and the end states since the interpolation
// is cheap
- mViewStates[state.copy()] = result
+ viewStates[state.copy()] = result
} else {
// This is an interpolated state
val startState = state.copy().also { it.expansion = 0.0f }
@@ -153,11 +208,13 @@ class MediaViewController(
val startViewState = obtainViewState(startState) as TransitionViewState
val endState = state.copy().also { it.expansion = 1.0f }
val endViewState = obtainViewState(endState) as TransitionViewState
+ tmpPoint.set(startState.getPivotX(), startState.getPivotY())
result = TransitionViewState()
layoutController.getInterpolatedState(
startViewState,
endViewState,
state.expansion,
+ tmpPoint,
result)
}
} else {
@@ -213,11 +270,35 @@ class MediaViewController(
val shouldAnimate = animateNextStateChange && !applyImmediately
+ var startHostState = mediaHostStatesManager.mediaHostStates[startLocation]
+ var endHostState = mediaHostStatesManager.mediaHostStates[endLocation]
+ var swappedStartState = false
+ var swappedEndState = false
+
+ // if we're going from or to a non visible state, let's grab the visible one and animate
+ // the view being clipped instead.
+ if (endHostState?.visible != true) {
+ endHostState = startHostState
+ swappedEndState = true
+ }
+ if (startHostState?.visible != true) {
+ startHostState = endHostState
+ swappedStartState = true
+ }
+ if (startHostState == null || endHostState == null) {
+ return
+ }
+
+ var endViewState = obtainViewState(endHostState) ?: return
+ if (swappedEndState) {
+ endViewState = endViewState.copy()
+ endViewState.height = 0
+ }
+
// Obtain the view state that we'd want to be at the end
// The view might not be bound yet or has never been measured and in that case will be
// reset once the state is fully available
- val endState = obtainViewStateForLocation(endLocation) ?: return
- layoutController.setMeasureState(endState)
+ layoutController.setMeasureState(endViewState)
// If the view isn't bound, we can drop the animation, otherwise we'll executute it
animateNextStateChange = false
@@ -225,24 +306,45 @@ class MediaViewController(
return
}
- val startState = obtainViewStateForLocation(startLocation)
+ var startViewState = obtainViewState(startHostState)
+ if (swappedStartState) {
+ startViewState = startViewState?.copy()
+ startViewState?.height = 0
+ }
+
val result: TransitionViewState?
- if (transitionProgress == 1.0f || startState == null) {
- result = endState
+ result = if (transitionProgress == 1.0f || startViewState == null) {
+ endViewState
} else if (transitionProgress == 0.0f) {
- result = startState
+ startViewState
} else {
- layoutController.getInterpolatedState(startState, endState, transitionProgress,
- tmpState)
- result = tmpState
+ if (swappedEndState || swappedStartState) {
+ tmpPoint.set(startHostState.getPivotX(), startHostState.getPivotY())
+ } else {
+ tmpPoint.set(0.0f, 0.0f)
+ }
+ layoutController.getInterpolatedState(startViewState, endViewState, transitionProgress,
+ tmpPoint, tmpState)
+ tmpState
}
+ currentWidth = result.width
+ currentHeight = result.height
layoutController.setState(result, applyImmediately, shouldAnimate, animationDuration,
animationDelay)
}
- private fun obtainViewStateForLocation(location: Int): TransitionViewState? {
- val mediaState = mediaHostStatesManager.mediaHostStates[location] ?: return null
- return obtainViewState(mediaState)
+ /**
+ * Retrieves the [TransitionViewState] and [MediaHostState] of a [@MediaLocation].
+ * In the event of [location] not being visible, [locationWhenHidden] will be used instead.
+ *
+ * @param location Target
+ * @param locationWhenHidden Location that will be used when the target is not
+ * [MediaHost.visible]
+ * @return State require for executing a transition, and also the respective [MediaHost].
+ */
+ private fun obtainViewStateForLocation(@MediaLocation location: Int): TransitionViewState? {
+ val mediaHostState = mediaHostStatesManager.mediaHostStates[location] ?: return null
+ return obtainViewState(mediaHostState)
}
/**
@@ -250,8 +352,7 @@ class MediaViewController(
* This updates the width the view will me measured with.
*/
fun onLocationPreChange(@MediaLocation newLocation: Int) {
- val viewState = obtainViewStateForLocation(newLocation)
- viewState?.let {
+ obtainViewStateForLocation(newLocation)?.let {
layoutController.setMeasureState(it)
}
}
@@ -271,9 +372,9 @@ class MediaViewController(
fun refreshState() {
if (!firstRefresh) {
// Let's clear all of our measurements and recreate them!
- mViewStates.clear()
+ viewStates.clear()
setCurrentState(currentStartLocation, currentEndLocation, currentTransitionProgress,
- applyImmediately = false)
+ applyImmediately = true)
}
firstRefresh = false
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/PlayerViewHolder.kt b/packages/SystemUI/src/com/android/systemui/media/PlayerViewHolder.kt
index 610e00ddd7f1..600fdc27ef89 100644
--- a/packages/SystemUI/src/com/android/systemui/media/PlayerViewHolder.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/PlayerViewHolder.kt
@@ -44,9 +44,11 @@ class PlayerViewHolder private constructor(itemView: View) {
val seamless = itemView.requireViewById<ViewGroup>(R.id.media_seamless)
val seamlessIcon = itemView.requireViewById<ImageView>(R.id.media_seamless_image)
val seamlessText = itemView.requireViewById<TextView>(R.id.media_seamless_text)
+ val seamlessFallback = itemView.requireViewById<ImageView>(R.id.media_seamless_fallback)
// Seek bar
val seekBar = itemView.requireViewById<SeekBar>(R.id.media_progress_bar)
+ val progressTimes = itemView.requireViewById<ViewGroup>(R.id.notification_media_progress_time)
val elapsedTimeView = itemView.requireViewById<TextView>(R.id.media_elapsed_time)
val totalTimeView = itemView.requireViewById<TextView>(R.id.media_total_time)
@@ -92,8 +94,16 @@ class PlayerViewHolder private constructor(itemView: View) {
* @param parent Parent of inflated view.
*/
@JvmStatic fun create(inflater: LayoutInflater, parent: ViewGroup): PlayerViewHolder {
- val v = inflater.inflate(R.layout.media_view, parent, false)
- return PlayerViewHolder(v)
+ val mediaView = inflater.inflate(R.layout.media_view, parent, false)
+ // Because this media view (a TransitionLayout) is used to measure and layout the views
+ // in various states before being attached to its parent, we can't depend on the default
+ // LAYOUT_DIRECTION_INHERIT to correctly resolve the ltr direction.
+ mediaView.layoutDirection = View.LAYOUT_DIRECTION_LOCALE
+ return PlayerViewHolder(mediaView).apply {
+ // Media playback is in the direction of tape, not time, so it stays LTR
+ seekBar.layoutDirection = View.LAYOUT_DIRECTION_LTR
+ progressTimes.layoutDirection = View.LAYOUT_DIRECTION_LTR
+ }
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/ResumeMediaBrowser.java b/packages/SystemUI/src/com/android/systemui/media/ResumeMediaBrowser.java
index 6462f072bc74..1842564a4574 100644
--- a/packages/SystemUI/src/com/android/systemui/media/ResumeMediaBrowser.java
+++ b/packages/SystemUI/src/com/android/systemui/media/ResumeMediaBrowser.java
@@ -30,8 +30,6 @@ import android.service.media.MediaBrowserService;
import android.text.TextUtils;
import android.util.Log;
-import com.android.systemui.util.Utils;
-
import java.util.List;
/**
@@ -46,7 +44,6 @@ public class ResumeMediaBrowser {
public static final String DELIMITER = ":";
private static final String TAG = "ResumeMediaBrowser";
- private boolean mIsEnabled = false;
private final Context mContext;
private final Callback mCallback;
private MediaBrowser mMediaBrowser;
@@ -59,7 +56,6 @@ public class ResumeMediaBrowser {
* @param componentName Component name of the MediaBrowserService this browser will connect to
*/
public ResumeMediaBrowser(Context context, Callback callback, ComponentName componentName) {
- mIsEnabled = Utils.useMediaResumption(context);
mContext = context;
mCallback = callback;
mComponentName = componentName;
@@ -74,9 +70,6 @@ public class ResumeMediaBrowser {
* ResumeMediaBrowser#disconnect will be called automatically with this function.
*/
public void findRecentMedia() {
- if (!mIsEnabled) {
- return;
- }
Log.d(TAG, "Connecting to " + mComponentName);
disconnect();
Bundle rootHints = new Bundle();
@@ -186,9 +179,6 @@ public class ResumeMediaBrowser {
* ResumeMediaBrowser#disconnect should be called after this to ensure the connection is closed.
*/
public void restart() {
- if (!mIsEnabled) {
- return;
- }
disconnect();
Bundle rootHints = new Bundle();
rootHints.putBoolean(MediaBrowserService.BrowserRoot.EXTRA_RECENT, true);
@@ -250,9 +240,6 @@ public class ResumeMediaBrowser {
* ResumeMediaBrowser#disconnect should be called after this to ensure the connection is closed.
*/
public void testConnection() {
- if (!mIsEnabled) {
- return;
- }
disconnect();
final MediaBrowser.ConnectionCallback connectionCallback =
new MediaBrowser.ConnectionCallback() {
diff --git a/packages/SystemUI/src/com/android/systemui/media/SeekBarObserver.kt b/packages/SystemUI/src/com/android/systemui/media/SeekBarObserver.kt
index cd8ed265bd53..c2631c923e45 100644
--- a/packages/SystemUI/src/com/android/systemui/media/SeekBarObserver.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/SeekBarObserver.kt
@@ -19,6 +19,7 @@ package com.android.systemui.media
import android.text.format.DateUtils
import androidx.annotation.UiThread
import androidx.lifecycle.Observer
+import com.android.systemui.R
/**
* Observer for changes from SeekBarViewModel.
@@ -27,10 +28,18 @@ import androidx.lifecycle.Observer
*/
class SeekBarObserver(private val holder: PlayerViewHolder) : Observer<SeekBarViewModel.Progress> {
+ val seekBarDefaultMaxHeight = holder.seekBar.context.resources
+ .getDimensionPixelSize(R.dimen.qs_media_enabled_seekbar_height)
+ val seekBarDisabledHeight = holder.seekBar.context.resources
+ .getDimensionPixelSize(R.dimen.qs_media_disabled_seekbar_height)
+
/** Updates seek bar views when the data model changes. */
@UiThread
override fun onChanged(data: SeekBarViewModel.Progress) {
if (!data.enabled) {
+ if (holder.seekBar.maxHeight != seekBarDisabledHeight) {
+ holder.seekBar.maxHeight = seekBarDisabledHeight
+ }
holder.seekBar.setEnabled(false)
holder.seekBar.getThumb().setAlpha(0)
holder.seekBar.setProgress(0)
@@ -42,6 +51,10 @@ class SeekBarObserver(private val holder: PlayerViewHolder) : Observer<SeekBarVi
holder.seekBar.getThumb().setAlpha(if (data.seekAvailable) 255 else 0)
holder.seekBar.setEnabled(data.seekAvailable)
+ if (holder.seekBar.maxHeight != seekBarDefaultMaxHeight) {
+ holder.seekBar.maxHeight = seekBarDefaultMaxHeight
+ }
+
data.elapsedTime?.let {
holder.seekBar.setProgress(it)
holder.elapsedTimeView.setText(DateUtils.formatElapsedTime(
diff --git a/packages/SystemUI/src/com/android/systemui/media/UnboundHorizontalScrollView.kt b/packages/SystemUI/src/com/android/systemui/media/UnboundHorizontalScrollView.kt
deleted file mode 100644
index 8efc9549068a..000000000000
--- a/packages/SystemUI/src/com/android/systemui/media/UnboundHorizontalScrollView.kt
+++ /dev/null
@@ -1,31 +0,0 @@
-package com.android.systemui.media
-
-import android.content.Context
-import android.util.AttributeSet
-import android.widget.HorizontalScrollView
-
-/**
- * A Horizontal scrollview that doesn't limit itself to the childs bounds. This is useful
- * when only measuring children but not the parent, when trying to apply a new scroll position
- */
-class UnboundHorizontalScrollView @JvmOverloads constructor(
- context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0)
- : HorizontalScrollView(context, attrs, defStyleAttr) {
-
- /**
- * Allow all scrolls to go through, use base implementation
- */
- override fun scrollTo(x: Int, y: Int) {
- if (mScrollX != x || mScrollY != y) {
- val oldX: Int = mScrollX
- val oldY: Int = mScrollY
- mScrollX = x
- mScrollY = y
- invalidateParentCaches()
- onScrollChanged(mScrollX, mScrollY, oldX, oldY)
- if (!awakenScrollBars()) {
- postInvalidateOnAnimation()
- }
- }
- }
-} \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java
index b93e07e65c73..e2feb71735ff 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java
@@ -202,14 +202,15 @@ public class PipTaskOrganizer extends TaskOrganizer implements
public PipTaskOrganizer(Context context, @NonNull PipBoundsHandler boundsHandler,
@NonNull PipSurfaceTransactionHelper surfaceTransactionHelper,
@Nullable Divider divider,
- @NonNull DisplayController displayController) {
+ @NonNull DisplayController displayController,
+ @NonNull PipAnimationController pipAnimationController) {
mMainHandler = new Handler(Looper.getMainLooper());
mUpdateHandler = new Handler(PipUpdateThread.get().getLooper(), mUpdateCallbacks);
mPipBoundsHandler = boundsHandler;
mEnterExitAnimationDuration = context.getResources()
.getInteger(R.integer.config_pipResizeAnimationDuration);
mSurfaceTransactionHelper = surfaceTransactionHelper;
- mPipAnimationController = new PipAnimationController(context, surfaceTransactionHelper);
+ mPipAnimationController = pipAnimationController;
mSurfaceControlTransactionFactory = SurfaceControl.Transaction::new;
mSplitDivider = divider;
displayController.addDisplayWindowListener(this);
@@ -272,8 +273,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements
sendOnPipTransitionStarted(direction);
// Don't bother doing an animation if the display rotation differs or if it's in
// a non-supported windowing mode
- wct.setWindowingMode(mToken, WINDOWING_MODE_UNDEFINED);
- wct.setActivityWindowingMode(mToken, WINDOWING_MODE_UNDEFINED);
+ applyWindowingModeChangeOnExit(wct, direction);
WindowOrganizer.applyTransaction(wct);
// Send finished callback though animation is ignored.
sendOnPipTransitionFinished(direction);
@@ -302,6 +302,16 @@ public class PipTaskOrganizer extends TaskOrganizer implements
mExitingPip = true;
}
+ private void applyWindowingModeChangeOnExit(WindowContainerTransaction wct, int direction) {
+ // Reset the final windowing mode.
+ wct.setWindowingMode(mToken, getOutPipWindowingMode());
+ // Simply reset the activity mode set prior to the animation running.
+ wct.setActivityWindowingMode(mToken, WINDOWING_MODE_UNDEFINED);
+ if (mSplitDivider != null && direction == TRANSITION_DIRECTION_TO_SPLIT_SCREEN) {
+ wct.reparent(mToken, mSplitDivider.getSecondaryRoot(), true /* onTop */);
+ }
+ }
+
/**
* Removes PiP immediately.
*/
@@ -708,6 +718,12 @@ public class PipTaskOrganizer extends TaskOrganizer implements
Log.w(TAG, "Abort animation, invalid leash");
return;
}
+
+ if (startBounds.isEmpty() || destinationBounds.isEmpty()) {
+ Log.w(TAG, "Attempted to user resize PIP to or from empty bounds, aborting.");
+ return;
+ }
+
final SurfaceControl.Transaction tx = mSurfaceControlTransactionFactory.getTransaction();
mSurfaceTransactionHelper.scale(tx, mLeash, startBounds, destinationBounds);
tx.apply();
@@ -738,13 +754,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements
// on the task to ensure that the task "matches" the parent's bounds.
taskBounds = (direction == TRANSITION_DIRECTION_TO_FULLSCREEN)
? null : destinationBounds;
- // As for the final windowing mode, simply reset it to undefined and reset the activity
- // mode set prior to the animation running
- wct.setWindowingMode(mToken, WINDOWING_MODE_UNDEFINED);
- wct.setActivityWindowingMode(mToken, WINDOWING_MODE_UNDEFINED);
- if (mSplitDivider != null && direction == TRANSITION_DIRECTION_TO_SPLIT_SCREEN) {
- wct.reparent(mToken, mSplitDivider.getSecondaryRoot(), true /* onTop */);
- }
+ applyWindowingModeChangeOnExit(wct, direction);
} else {
// Just a resize in PIP
taskBounds = destinationBounds;
@@ -752,9 +762,30 @@ public class PipTaskOrganizer extends TaskOrganizer implements
wct.setBounds(mToken, taskBounds);
wct.setBoundsChangeTransaction(mToken, tx);
+ applyFinishBoundsResize(wct, direction);
+ }
+
+ /**
+ * Applies the window container transaction to finish a bounds resize.
+ *
+ * Called by {@link #finishResize(SurfaceControl.Transaction, Rect, int, int)}} once it has
+ * finished preparing the transaction. It allows subclasses to modify the transaction before
+ * applying it.
+ */
+ public void applyFinishBoundsResize(@NonNull WindowContainerTransaction wct,
+ @PipAnimationController.TransitionDirection int direction) {
WindowOrganizer.applyTransaction(wct);
}
+ /**
+ * The windowing mode to restore to when resizing out of PIP direction. Defaults to undefined
+ * and can be overridden to restore to an alternate windowing mode.
+ */
+ public int getOutPipWindowingMode() {
+ // By default, simply reset the windowing mode to undefined.
+ return WINDOWING_MODE_UNDEFINED;
+ }
+
private void animateResizePip(Rect currentBounds, Rect destinationBounds,
@PipAnimationController.TransitionDirection int direction, int durationMs) {
if (Looper.myLooper() != mUpdateHandler.getLooper()) {
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipAccessibilityInteractionConnection.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipAccessibilityInteractionConnection.java
index f1eef4353d32..8b3f4cb196bf 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipAccessibilityInteractionConnection.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipAccessibilityInteractionConnection.java
@@ -15,6 +15,7 @@
*/
package com.android.systemui.pip.phone;
+import android.content.Context;
import android.graphics.Rect;
import android.graphics.Region;
import android.os.Bundle;
@@ -26,6 +27,10 @@ import android.view.accessibility.AccessibilityWindowInfo;
import android.view.accessibility.IAccessibilityInteractionConnection;
import android.view.accessibility.IAccessibilityInteractionConnectionCallback;
+import com.android.systemui.R;
+import com.android.systemui.pip.PipSnapAlgorithm;
+import com.android.systemui.pip.PipTaskOrganizer;
+
import java.util.ArrayList;
import java.util.List;
@@ -43,16 +48,30 @@ public class PipAccessibilityInteractionConnection
private static final long ACCESSIBILITY_NODE_ID = 1;
private List<AccessibilityNodeInfo> mAccessibilityNodeInfoList;
+ private Context mContext;
private Handler mHandler;
private PipMotionHelper mMotionHelper;
+ private PipTaskOrganizer mTaskOrganizer;
+ private PipSnapAlgorithm mSnapAlgorithm;
+ private Runnable mUpdateMovementBoundCallback;
private AccessibilityCallbacks mCallbacks;
+ private final Rect mNormalBounds = new Rect();
+ private final Rect mExpandedBounds = new Rect();
+ private final Rect mNormalMovementBounds = new Rect();
+ private final Rect mExpandedMovementBounds = new Rect();
private Rect mTmpBounds = new Rect();
- public PipAccessibilityInteractionConnection(PipMotionHelper motionHelper,
- AccessibilityCallbacks callbacks, Handler handler) {
+ public PipAccessibilityInteractionConnection(Context context, PipMotionHelper motionHelper,
+ PipTaskOrganizer taskOrganizer, PipSnapAlgorithm snapAlgorithm,
+ AccessibilityCallbacks callbacks, Runnable updateMovementBoundCallback,
+ Handler handler) {
+ mContext = context;
mHandler = handler;
mMotionHelper = motionHelper;
+ mTaskOrganizer = taskOrganizer;
+ mSnapAlgorithm = snapAlgorithm;
+ mUpdateMovementBoundCallback = updateMovementBoundCallback;
mCallbacks = callbacks;
}
@@ -78,34 +97,46 @@ public class PipAccessibilityInteractionConnection
// We only support one view. A request for anything else is invalid
boolean result = false;
if (accessibilityNodeId == AccessibilityNodeInfo.ROOT_NODE_ID) {
- switch (action) {
- case AccessibilityNodeInfo.ACTION_CLICK:
- mHandler.post(() -> {
- mCallbacks.onAccessibilityShowMenu();
- });
- result = true;
- break;
- case AccessibilityNodeInfo.ACTION_DISMISS:
- mMotionHelper.dismissPip();
- result = true;
- break;
- case com.android.internal.R.id.accessibilityActionMoveWindow:
- int newX = arguments.getInt(
- AccessibilityNodeInfo.ACTION_ARGUMENT_MOVE_WINDOW_X);
- int newY = arguments.getInt(
- AccessibilityNodeInfo.ACTION_ARGUMENT_MOVE_WINDOW_Y);
- Rect pipBounds = new Rect();
- pipBounds.set(mMotionHelper.getBounds());
- mTmpBounds.offsetTo(newX, newY);
- mMotionHelper.movePip(mTmpBounds);
- result = true;
- break;
- case AccessibilityNodeInfo.ACTION_EXPAND:
- mMotionHelper.expandPipToFullscreen();
- result = true;
- break;
- default:
- // Leave result as false
+
+ // R constants are not final so this cannot be put in the switch-case.
+ if (action == R.id.action_pip_resize) {
+ if (mMotionHelper.getBounds().width() == mNormalBounds.width()
+ && mMotionHelper.getBounds().height() == mNormalBounds.height()) {
+ setToExpandedBounds();
+ } else {
+ setToNormalBounds();
+ }
+ result = true;
+ } else {
+ switch (action) {
+ case AccessibilityNodeInfo.ACTION_CLICK:
+ mHandler.post(() -> {
+ mCallbacks.onAccessibilityShowMenu();
+ });
+ result = true;
+ break;
+ case AccessibilityNodeInfo.ACTION_DISMISS:
+ mMotionHelper.dismissPip();
+ result = true;
+ break;
+ case com.android.internal.R.id.accessibilityActionMoveWindow:
+ int newX = arguments.getInt(
+ AccessibilityNodeInfo.ACTION_ARGUMENT_MOVE_WINDOW_X);
+ int newY = arguments.getInt(
+ AccessibilityNodeInfo.ACTION_ARGUMENT_MOVE_WINDOW_Y);
+ Rect pipBounds = new Rect();
+ pipBounds.set(mMotionHelper.getBounds());
+ mTmpBounds.offsetTo(newX, newY);
+ mMotionHelper.movePip(mTmpBounds);
+ result = true;
+ break;
+ case AccessibilityNodeInfo.ACTION_EXPAND:
+ mMotionHelper.expandPipToFullscreen();
+ result = true;
+ break;
+ default:
+ // Leave result as false
+ }
}
}
try {
@@ -115,6 +146,27 @@ public class PipAccessibilityInteractionConnection
}
}
+ private void setToExpandedBounds() {
+ float savedSnapFraction = mSnapAlgorithm.getSnapFraction(
+ new Rect(mTaskOrganizer.getLastReportedBounds()), mNormalMovementBounds);
+ mSnapAlgorithm.applySnapFraction(mExpandedBounds, mExpandedMovementBounds,
+ savedSnapFraction);
+ mTaskOrganizer.scheduleFinishResizePip(mExpandedBounds, (Rect bounds) -> {
+ mMotionHelper.synchronizePinnedStackBounds();
+ mUpdateMovementBoundCallback.run();
+ });
+ }
+
+ private void setToNormalBounds() {
+ float savedSnapFraction = mSnapAlgorithm.getSnapFraction(
+ new Rect(mTaskOrganizer.getLastReportedBounds()), mExpandedMovementBounds);
+ mSnapAlgorithm.applySnapFraction(mNormalBounds, mNormalMovementBounds, savedSnapFraction);
+ mTaskOrganizer.scheduleFinishResizePip(mNormalBounds, (Rect bounds) -> {
+ mMotionHelper.synchronizePinnedStackBounds();
+ mUpdateMovementBoundCallback.run();
+ });
+ }
+
@Override
public void findAccessibilityNodeInfosByViewId(long accessibilityNodeId,
String viewId, Region interactiveRegion, int interactionId,
@@ -175,7 +227,21 @@ public class PipAccessibilityInteractionConnection
// Do nothing.
}
- public static AccessibilityNodeInfo obtainRootAccessibilityNodeInfo() {
+ /**
+ * Update the normal and expanded bounds so they can be used for Resize.
+ */
+ void onMovementBoundsChanged(Rect normalBounds, Rect expandedBounds, Rect normalMovementBounds,
+ Rect expandedMovementBounds) {
+ mNormalBounds.set(normalBounds);
+ mExpandedBounds.set(expandedBounds);
+ mNormalMovementBounds.set(normalMovementBounds);
+ mExpandedMovementBounds.set(expandedMovementBounds);
+ }
+
+ /**
+ * Update the Root node with PIP Accessibility action items.
+ */
+ public static AccessibilityNodeInfo obtainRootAccessibilityNodeInfo(Context context) {
AccessibilityNodeInfo info = AccessibilityNodeInfo.obtain();
info.setSourceNodeId(AccessibilityNodeInfo.ROOT_NODE_ID,
AccessibilityWindowInfo.PICTURE_IN_PICTURE_ACTION_REPLACER_WINDOW_ID);
@@ -183,6 +249,8 @@ public class PipAccessibilityInteractionConnection
info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_DISMISS);
info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_MOVE_WINDOW);
info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_EXPAND);
+ info.addAction(new AccessibilityNodeInfo.AccessibilityAction(R.id.action_pip_resize,
+ context.getString(R.string.accessibility_action_pip_resize)));
info.setImportantForAccessibility(true);
info.setClickable(true);
info.setVisibleToUser(true);
@@ -193,7 +261,7 @@ public class PipAccessibilityInteractionConnection
if (mAccessibilityNodeInfoList == null) {
mAccessibilityNodeInfoList = new ArrayList<>(1);
}
- AccessibilityNodeInfo info = obtainRootAccessibilityNodeInfo();
+ AccessibilityNodeInfo info = obtainRootAccessibilityNodeInfo(mContext);
mAccessibilityNodeInfoList.clear();
mAccessibilityNodeInfoList.add(info);
return mAccessibilityNodeInfoList;
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
index e38bfb441a0b..7a18ec361860 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
@@ -41,6 +41,7 @@ import android.window.WindowContainerTransaction;
import com.android.systemui.Dependency;
import com.android.systemui.UiOffloadThread;
import com.android.systemui.broadcast.BroadcastDispatcher;
+import com.android.systemui.model.SysUiState;
import com.android.systemui.pip.BasePipManager;
import com.android.systemui.pip.PipBoundsHandler;
import com.android.systemui.pip.PipSnapAlgorithm;
@@ -81,12 +82,12 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio
private InputConsumerController mInputConsumerController;
private PipMediaController mMediaController;
private PipTouchHandler mTouchHandler;
+ private PipTaskOrganizer mPipTaskOrganizer;
private PipAppOpsListener mAppOpsListener;
private IPinnedStackAnimationListener mPinnedStackAnimationRecentsListener;
private boolean mIsInFixedRotation;
protected PipMenuActivityController mMenuController;
- protected PipTaskOrganizer mPipTaskOrganizer;
/**
* Handler for display rotation changes.
@@ -229,7 +230,8 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio
DeviceConfigProxy deviceConfig,
PipBoundsHandler pipBoundsHandler,
PipSnapAlgorithm pipSnapAlgorithm,
- PipTaskOrganizer pipTaskOrganizer) {
+ PipTaskOrganizer pipTaskOrganizer,
+ SysUiState sysUiState) {
mContext = context;
mActivityManager = ActivityManager.getService();
@@ -250,7 +252,7 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio
mInputConsumerController);
mTouchHandler = new PipTouchHandler(context, mActivityManager,
mMenuController, mInputConsumerController, mPipBoundsHandler, mPipTaskOrganizer,
- floatingContentCoordinator, deviceConfig, pipSnapAlgorithm);
+ floatingContentCoordinator, deviceConfig, pipSnapAlgorithm, sysUiState);
mAppOpsListener = new PipAppOpsListener(context, mActivityManager,
mTouchHandler.getMotionHelper());
displayController.addDisplayChangingController(mRotationController);
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
index 6ab73fcce399..204354645e10 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
@@ -110,6 +110,8 @@ public class PipMenuActivity extends Activity {
private static final float DISABLED_ACTION_ALPHA = 0.54f;
+ private static final boolean ENABLE_RESIZE_HANDLE = false;
+
private int mMenuState;
private boolean mResize = true;
private boolean mAllowMenuTimeout = true;
@@ -388,7 +390,8 @@ public class PipMenuActivity extends Activity {
ObjectAnimator dismissAnim = ObjectAnimator.ofFloat(mDismissButton, View.ALPHA,
mDismissButton.getAlpha(), 1f);
ObjectAnimator resizeAnim = ObjectAnimator.ofFloat(mResizeHandle, View.ALPHA,
- mResizeHandle.getAlpha(), menuState == MENU_STATE_CLOSE && showResizeHandle
+ mResizeHandle.getAlpha(),
+ ENABLE_RESIZE_HANDLE && menuState == MENU_STATE_CLOSE && showResizeHandle
? 1f : 0f);
if (menuState == MENU_STATE_FULL) {
mMenuContainerAnimator.playTogether(menuAnim, settingsAnim, dismissAnim,
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
index d077666f8184..26805050e841 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
@@ -20,6 +20,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.ComponentName;
import android.content.Context;
+import android.graphics.PointF;
import android.graphics.Rect;
import android.os.Debug;
import android.util.Log;
@@ -38,6 +39,9 @@ import com.android.systemui.util.magnetictarget.MagnetizedObject;
import java.io.PrintWriter;
import java.util.function.Consumer;
+import kotlin.Unit;
+import kotlin.jvm.functions.Function0;
+
/**
* A helper to animate and manipulate the PiP.
*/
@@ -74,9 +78,15 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
new SfVsyncFrameCallbackProvider();
/**
- * Bounds that are animated using the physics animator.
+ * Temporary bounds used when PIP is being dragged or animated. These bounds are applied to PIP
+ * using {@link PipTaskOrganizer#scheduleUserResizePip}, so that we can animate shrinking into
+ * and expanding out of the magnetic dismiss target.
+ *
+ * Once PIP is done being dragged or animated, we set {@link #mBounds} equal to these temporary
+ * bounds, and call {@link PipTaskOrganizer#scheduleFinishResizePip} to 'officially' move PIP to
+ * its new bounds.
*/
- private final Rect mAnimatedBounds = new Rect();
+ private final Rect mTemporaryBounds = new Rect();
/** The destination bounds to which PIP is animating. */
private final Rect mAnimatingToBounds = new Rect();
@@ -85,20 +95,20 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
private FloatingContentCoordinator mFloatingContentCoordinator;
/** Callback that re-sizes PIP to the animated bounds. */
- private final Choreographer.FrameCallback mResizePipVsyncCallback =
- l -> resizePipUnchecked(mAnimatedBounds);
+ private final Choreographer.FrameCallback mResizePipVsyncCallback;
/**
- * PhysicsAnimator instance for animating {@link #mAnimatedBounds} using physics animations.
+ * PhysicsAnimator instance for animating {@link #mTemporaryBounds} using physics animations.
*/
- private PhysicsAnimator<Rect> mAnimatedBoundsPhysicsAnimator = PhysicsAnimator.getInstance(
- mAnimatedBounds);
+ private PhysicsAnimator<Rect> mTemporaryBoundsPhysicsAnimator = PhysicsAnimator.getInstance(
+ mTemporaryBounds);
+
+ private MagnetizedObject<Rect> mMagnetizedPip;
/**
- * Update listener that resizes the PIP to {@link #mAnimatedBounds}.
+ * Update listener that resizes the PIP to {@link #mTemporaryBounds}.
*/
- final PhysicsAnimator.UpdateListener<Rect> mResizePipUpdateListener =
- (target, values) -> mSfVsyncFrameProvider.postFrameCallback(mResizePipVsyncCallback);
+ private final PhysicsAnimator.UpdateListener<Rect> mResizePipUpdateListener;
/** FlingConfig instances provided to PhysicsAnimator for fling gestures. */
private PhysicsAnimator.FlingConfig mFlingConfigX;
@@ -124,6 +134,12 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
private boolean mSpringingToTouch = false;
/**
+ * Whether PIP was released in the dismiss target, and will be animated out and dismissed
+ * shortly.
+ */
+ private boolean mDismissalPending = false;
+
+ /**
* Gets set in {@link #animateToExpandedState(Rect, Rect, Rect, Runnable)}, this callback is
* used to show menu activity when the expand animation is completed.
*/
@@ -155,6 +171,16 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
mSnapAlgorithm = snapAlgorithm;
mFloatingContentCoordinator = floatingContentCoordinator;
mPipTaskOrganizer.registerPipTransitionCallback(mPipTransitionCallback);
+
+ mResizePipVsyncCallback = l -> {
+ if (!mTemporaryBounds.isEmpty()) {
+ mPipTaskOrganizer.scheduleUserResizePip(
+ mBounds, mTemporaryBounds, null);
+ }
+ };
+
+ mResizePipUpdateListener = (target, values) ->
+ mSfVsyncFrameProvider.postFrameCallback(mResizePipVsyncCallback);
}
@NonNull
@@ -180,25 +206,15 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
void synchronizePinnedStackBounds() {
cancelAnimations();
mBounds.set(mPipTaskOrganizer.getLastReportedBounds());
+ mTemporaryBounds.setEmpty();
if (mPipTaskOrganizer.isInPip()) {
mFloatingContentCoordinator.onContentMoved(this);
}
}
- /**
- * Synchronizes the current bounds with either the pinned stack, or the ongoing animation. This
- * is done to prepare for a touch gesture.
- */
- void synchronizePinnedStackBoundsForTouchGesture() {
- if (mAnimatingToBounds.isEmpty()) {
- // If we're not animating anywhere, sync normally.
- synchronizePinnedStackBounds();
- } else {
- // If we're animating, set the current bounds to the animated bounds. That way, the
- // touch gesture will begin at the most recent animated location of the bounds.
- mBounds.set(mAnimatedBounds);
- }
+ boolean isAnimating() {
+ return mTemporaryBoundsPhysicsAnimator.isRunning();
}
/**
@@ -224,32 +240,59 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
// If we are moving PIP directly to the touch event locations, cancel any animations and
// move PIP to the given bounds.
cancelAnimations();
- resizePipUnchecked(toBounds);
- mBounds.set(toBounds);
+
+ if (!isDragging) {
+ resizePipUnchecked(toBounds);
+ mBounds.set(toBounds);
+ } else {
+ mTemporaryBounds.set(toBounds);
+ mPipTaskOrganizer.scheduleUserResizePip(mBounds, mTemporaryBounds, null);
+ }
} else {
// If PIP is 'catching up' after being stuck in the dismiss target, update the animation
// to spring towards the new touch location.
- mAnimatedBoundsPhysicsAnimator
+ mTemporaryBoundsPhysicsAnimator
+ .spring(FloatProperties.RECT_WIDTH, mBounds.width(), mSpringConfig)
+ .spring(FloatProperties.RECT_HEIGHT, mBounds.height(), mSpringConfig)
.spring(FloatProperties.RECT_X, toBounds.left, mSpringConfig)
- .spring(FloatProperties.RECT_Y, toBounds.top, mSpringConfig)
- .withEndActions(() -> mSpringingToTouch = false);
+ .spring(FloatProperties.RECT_Y, toBounds.top, mSpringConfig);
startBoundsAnimator(toBounds.left /* toX */, toBounds.top /* toY */,
false /* dismiss */);
}
}
- /** Set whether we're springing-to-touch to catch up after being stuck in the dismiss target. */
- void setSpringingToTouch(boolean springingToTouch) {
- if (springingToTouch) {
- mAnimatedBounds.set(mBounds);
- }
+ /** Animates the PIP into the dismiss target, scaling it down. */
+ void animateIntoDismissTarget(
+ MagnetizedObject.MagneticTarget target,
+ float velX, float velY,
+ boolean flung, Function0<Unit> after) {
+ final PointF targetCenter = target.getCenterOnScreen();
- mSpringingToTouch = springingToTouch;
+ final float desiredWidth = mBounds.width() / 2;
+ final float desiredHeight = mBounds.height() / 2;
+
+ final float destinationX = targetCenter.x - (desiredWidth / 2f);
+ final float destinationY = targetCenter.y - (desiredHeight / 2f);
+
+ // If we're already in the dismiss target area, then there won't be a move to set the
+ // temporary bounds, so just initialize it to the current bounds
+ if (mTemporaryBounds.isEmpty()) {
+ mTemporaryBounds.set(mBounds);
+ }
+ mTemporaryBoundsPhysicsAnimator
+ .spring(FloatProperties.RECT_X, destinationX, velX, mSpringConfig)
+ .spring(FloatProperties.RECT_Y, destinationY, velY, mSpringConfig)
+ .spring(FloatProperties.RECT_WIDTH, desiredWidth, mSpringConfig)
+ .spring(FloatProperties.RECT_HEIGHT, desiredHeight, mSpringConfig)
+ .withEndActions(after);
+
+ startBoundsAnimator(destinationX, destinationY, false);
}
- void prepareForAnimation() {
- mAnimatedBounds.set(mBounds);
+ /** Set whether we're springing-to-touch to catch up after being stuck in the dismiss target. */
+ void setSpringingToTouch(boolean springingToTouch) {
+ mSpringingToTouch = springingToTouch;
}
/**
@@ -309,13 +352,22 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
}
/**
+ * Returns the PIP bounds if we're not animating, or the current, temporary animating bounds
+ * otherwise.
+ */
+ Rect getPossiblyAnimatingBounds() {
+ return mTemporaryBounds.isEmpty() ? mBounds : mTemporaryBounds;
+ }
+
+ /**
* Flings the PiP to the closest snap target.
*/
void flingToSnapTarget(
float velocityX, float velocityY,
@Nullable Runnable updateAction, @Nullable Runnable endAction) {
- mAnimatedBounds.set(mBounds);
- mAnimatedBoundsPhysicsAnimator
+ mTemporaryBoundsPhysicsAnimator
+ .spring(FloatProperties.RECT_WIDTH, mBounds.width(), mSpringConfig)
+ .spring(FloatProperties.RECT_HEIGHT, mBounds.height(), mSpringConfig)
.flingThenSpring(
FloatProperties.RECT_X, velocityX, mFlingConfigX, mSpringConfig,
true /* flingMustReachMinOrMax */)
@@ -324,13 +376,14 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
.withEndActions(endAction);
if (updateAction != null) {
- mAnimatedBoundsPhysicsAnimator.addUpdateListener(
+ mTemporaryBoundsPhysicsAnimator.addUpdateListener(
(target, values) -> updateAction.run());
}
final float xEndValue = velocityX < 0 ? mMovementBounds.left : mMovementBounds.right;
final float estimatedFlingYEndValue =
- PhysicsAnimator.estimateFlingEndValue(mBounds.top, velocityY, mFlingConfigY);
+ PhysicsAnimator.estimateFlingEndValue(
+ mTemporaryBounds.top, velocityY, mFlingConfigY);
startBoundsAnimator(xEndValue /* toX */, estimatedFlingYEndValue /* toY */,
false /* dismiss */);
@@ -341,8 +394,12 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
* configuration
*/
void animateToBounds(Rect bounds, PhysicsAnimator.SpringConfig springConfig) {
- mAnimatedBounds.set(mBounds);
- mAnimatedBoundsPhysicsAnimator
+ if (!mTemporaryBoundsPhysicsAnimator.isRunning()) {
+ // Animate from the current bounds if we're not already animating.
+ mTemporaryBounds.set(mBounds);
+ }
+
+ mTemporaryBoundsPhysicsAnimator
.spring(FloatProperties.RECT_X, bounds.left, springConfig)
.spring(FloatProperties.RECT_Y, bounds.top, springConfig);
startBoundsAnimator(bounds.left /* toX */, bounds.top /* toY */,
@@ -353,18 +410,19 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
* Animates the dismissal of the PiP off the edge of the screen.
*/
void animateDismiss() {
- mAnimatedBounds.set(mBounds);
-
// Animate off the bottom of the screen, then dismiss PIP.
- mAnimatedBoundsPhysicsAnimator
+ mTemporaryBoundsPhysicsAnimator
.spring(FloatProperties.RECT_Y,
- mBounds.bottom + mBounds.height(),
+ mMovementBounds.bottom + mBounds.height() * 2,
0,
mSpringConfig)
.withEndActions(this::dismissPip);
- startBoundsAnimator(mBounds.left /* toX */, mBounds.bottom + mBounds.height() /* toY */,
+ startBoundsAnimator(
+ mBounds.left /* toX */, mBounds.bottom + mBounds.height() /* toY */,
true /* dismiss */);
+
+ mDismissalPending = false;
}
/**
@@ -415,7 +473,7 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
* Cancels all existing animations.
*/
private void cancelAnimations() {
- mAnimatedBoundsPhysicsAnimator.cancel();
+ mTemporaryBoundsPhysicsAnimator.cancel();
mAnimatingToBounds.setEmpty();
mSpringingToTouch = false;
}
@@ -449,15 +507,36 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
(int) toY + mBounds.height());
setAnimatingToBounds(mAnimatingToBounds);
- mAnimatedBoundsPhysicsAnimator
- .withEndActions(() -> {
- if (!dismiss) {
- mPipTaskOrganizer.scheduleFinishResizePip(mAnimatedBounds);
- }
- mAnimatingToBounds.setEmpty();
- })
- .addUpdateListener(mResizePipUpdateListener)
- .start();
+ if (!mTemporaryBoundsPhysicsAnimator.isRunning()) {
+ mTemporaryBoundsPhysicsAnimator
+ .addUpdateListener(mResizePipUpdateListener)
+ .withEndActions(this::onBoundsAnimationEnd);
+ }
+
+ mTemporaryBoundsPhysicsAnimator.start();
+ }
+
+ /**
+ * Notify that PIP was released in the dismiss target and will be animated out and dismissed
+ * shortly.
+ */
+ void notifyDismissalPending() {
+ mDismissalPending = true;
+ }
+
+ private void onBoundsAnimationEnd() {
+ if (!mDismissalPending
+ && !mSpringingToTouch
+ && !mMagnetizedPip.getObjectStuckToTarget()) {
+ mBounds.set(mTemporaryBounds);
+ mPipTaskOrganizer.scheduleFinishResizePip(mBounds);
+
+ mTemporaryBounds.setEmpty();
+ }
+
+ mAnimatingToBounds.setEmpty();
+ mSpringingToTouch = false;
+ mDismissalPending = false;
}
/**
@@ -491,10 +570,11 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
Log.d(TAG, "resizeAndAnimatePipUnchecked: toBounds=" + toBounds
+ " duration=" + duration + " callers=\n" + Debug.getCallers(5, " "));
}
- if (!toBounds.equals(mBounds)) {
- mPipTaskOrganizer.scheduleAnimateResizePip(toBounds, duration, mUpdateBoundsCallback);
- setAnimatingToBounds(toBounds);
- }
+
+ // Intentionally resize here even if the current bounds match the destination bounds.
+ // This is so all the proper callbacks are performed.
+ mPipTaskOrganizer.scheduleAnimateResizePip(toBounds, duration, mUpdateBoundsCallback);
+ setAnimatingToBounds(toBounds);
}
/**
@@ -502,25 +582,29 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
* magnetic dismiss target so it can calculate PIP's size and position.
*/
MagnetizedObject<Rect> getMagnetizedPip() {
- return new MagnetizedObject<Rect>(
- mContext, mAnimatedBounds, FloatProperties.RECT_X, FloatProperties.RECT_Y) {
- @Override
- public float getWidth(@NonNull Rect animatedPipBounds) {
- return animatedPipBounds.width();
- }
-
- @Override
- public float getHeight(@NonNull Rect animatedPipBounds) {
- return animatedPipBounds.height();
- }
+ if (mMagnetizedPip == null) {
+ mMagnetizedPip = new MagnetizedObject<Rect>(
+ mContext, mTemporaryBounds, FloatProperties.RECT_X, FloatProperties.RECT_Y) {
+ @Override
+ public float getWidth(@NonNull Rect animatedPipBounds) {
+ return animatedPipBounds.width();
+ }
+
+ @Override
+ public float getHeight(@NonNull Rect animatedPipBounds) {
+ return animatedPipBounds.height();
+ }
+
+ @Override
+ public void getLocationOnScreen(
+ @NonNull Rect animatedPipBounds, @NonNull int[] loc) {
+ loc[0] = animatedPipBounds.left;
+ loc[1] = animatedPipBounds.top;
+ }
+ };
+ }
- @Override
- public void getLocationOnScreen(
- @NonNull Rect animatedPipBounds, @NonNull int[] loc) {
- loc[0] = animatedPipBounds.left;
- loc[1] = animatedPipBounds.top;
- }
- };
+ return mMagnetizedPip;
}
public void dump(PrintWriter pw, String prefix) {
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipResizeGestureHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipResizeGestureHandler.java
index f6b212c6f19f..a4edacecfd91 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipResizeGestureHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipResizeGestureHandler.java
@@ -21,6 +21,13 @@ import static com.android.internal.policy.TaskResizingAlgorithm.CTRL_LEFT;
import static com.android.internal.policy.TaskResizingAlgorithm.CTRL_NONE;
import static com.android.internal.policy.TaskResizingAlgorithm.CTRL_RIGHT;
import static com.android.internal.policy.TaskResizingAlgorithm.CTRL_TOP;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BOUNCER_SHOWING;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BUBBLES_EXPANDED;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_GLOBAL_ACTIONS_SHOWING;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_QUICK_SETTINGS_EXPANDED;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED;
import android.content.Context;
import android.content.res.Resources;
@@ -43,6 +50,7 @@ import android.view.ViewConfiguration;
import com.android.internal.policy.TaskResizingAlgorithm;
import com.android.systemui.R;
+import com.android.systemui.model.SysUiState;
import com.android.systemui.pip.PipBoundsHandler;
import com.android.systemui.pip.PipTaskOrganizer;
import com.android.systemui.util.DeviceConfigProxy;
@@ -58,11 +66,21 @@ public class PipResizeGestureHandler {
private static final String TAG = "PipResizeGestureHandler";
+ private static final int INVALID_SYSUI_STATE_MASK =
+ SYSUI_STATE_GLOBAL_ACTIONS_SHOWING
+ | SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING
+ | SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED
+ | SYSUI_STATE_BOUNCER_SHOWING
+ | SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED
+ | SYSUI_STATE_BUBBLES_EXPANDED
+ | SYSUI_STATE_QUICK_SETTINGS_EXPANDED;
+
private final Context mContext;
private final PipBoundsHandler mPipBoundsHandler;
private final PipMotionHelper mMotionHelper;
private final int mDisplayId;
private final Executor mMainExecutor;
+ private final SysUiState mSysUiState;
private final Region mTmpRegion = new Region();
private final PointF mDownPoint = new PointF();
@@ -96,7 +114,7 @@ public class PipResizeGestureHandler {
public PipResizeGestureHandler(Context context, PipBoundsHandler pipBoundsHandler,
PipMotionHelper motionHelper, DeviceConfigProxy deviceConfig,
PipTaskOrganizer pipTaskOrganizer, Supplier<Rect> movementBoundsSupplier,
- Runnable updateMovementBoundsRunnable) {
+ Runnable updateMovementBoundsRunnable, SysUiState sysUiState) {
mContext = context;
mDisplayId = context.getDisplayId();
mMainExecutor = context.getMainExecutor();
@@ -105,6 +123,7 @@ public class PipResizeGestureHandler {
mPipTaskOrganizer = pipTaskOrganizer;
mMovementBoundsSupplier = movementBoundsSupplier;
mUpdateMovementBoundsRunnable = updateMovementBoundsRunnable;
+ mSysUiState = sysUiState;
context.getDisplay().getRealSize(mMaxSize);
reloadResources();
@@ -258,14 +277,20 @@ public class PipResizeGestureHandler {
}
}
+ private boolean isInValidSysUiState() {
+ return (mSysUiState.getFlags() & INVALID_SYSUI_STATE_MASK) == 0;
+ }
+
private void onMotionEvent(MotionEvent ev) {
int action = ev.getActionMasked();
+ float x = ev.getX();
+ float y = ev.getY();
if (action == MotionEvent.ACTION_DOWN) {
mLastResizeBounds.setEmpty();
- mAllowGesture = isWithinTouchRegion((int) ev.getX(), (int) ev.getY());
+ mAllowGesture = isInValidSysUiState() && isWithinTouchRegion((int) x, (int) y);
if (mAllowGesture) {
- setCtrlType((int) ev.getX(), (int) ev.getY());
- mDownPoint.set(ev.getX(), ev.getY());
+ setCtrlType((int) x, (int) y);
+ mDownPoint.set(x, y);
mLastDownBounds.set(mMotionHelper.getBounds());
}
@@ -277,20 +302,23 @@ public class PipResizeGestureHandler {
break;
case MotionEvent.ACTION_MOVE:
// Capture inputs
- float dx = Math.abs(ev.getX() - mDownPoint.x);
- float dy = Math.abs(ev.getY() - mDownPoint.y);
- if (!mThresholdCrossed && dx > mTouchSlop && dy > mTouchSlop) {
+ if (!mThresholdCrossed
+ && Math.hypot(x - mDownPoint.x, y - mDownPoint.y) > mTouchSlop) {
mThresholdCrossed = true;
+ // Reset the down to begin resizing from this point
+ mDownPoint.set(x, y);
mInputMonitor.pilferPointers();
}
- final Rect currentPipBounds = mMotionHelper.getBounds();
- mLastResizeBounds.set(TaskResizingAlgorithm.resizeDrag(ev.getX(), ev.getY(),
- mDownPoint.x, mDownPoint.y, currentPipBounds, mCtrlType, mMinSize.x,
- mMinSize.y, mMaxSize, true,
- mLastDownBounds.width() > mLastDownBounds.height()));
- mPipBoundsHandler.transformBoundsToAspectRatio(mLastResizeBounds);
- mPipTaskOrganizer.scheduleUserResizePip(mLastDownBounds, mLastResizeBounds,
- null);
+ if (mThresholdCrossed) {
+ final Rect currentPipBounds = mMotionHelper.getBounds();
+ mLastResizeBounds.set(TaskResizingAlgorithm.resizeDrag(x, y,
+ mDownPoint.x, mDownPoint.y, currentPipBounds, mCtrlType, mMinSize.x,
+ mMinSize.y, mMaxSize, true,
+ mLastDownBounds.width() > mLastDownBounds.height()));
+ mPipBoundsHandler.transformBoundsToAspectRatio(mLastResizeBounds);
+ mPipTaskOrganizer.scheduleUserResizePip(mLastDownBounds, mLastResizeBounds,
+ null);
+ }
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
index 3cc9127068bf..a4d7bad2891f 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
@@ -57,6 +57,7 @@ import androidx.dynamicanimation.animation.SpringForce;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.os.logging.MetricsLoggerWrapper;
import com.android.systemui.R;
+import com.android.systemui.model.SysUiState;
import com.android.systemui.pip.PipAnimationController;
import com.android.systemui.pip.PipBoundsHandler;
import com.android.systemui.pip.PipSnapAlgorithm;
@@ -70,6 +71,8 @@ import com.android.systemui.util.magnetictarget.MagnetizedObject;
import java.io.PrintWriter;
+import kotlin.Unit;
+
/**
* Manages all the touch handling for PIP on the Phone, including moving, dismissing and expanding
* the PIP.
@@ -80,6 +83,9 @@ public class PipTouchHandler {
/** Duration of the dismiss scrim fading in/out. */
private static final int DISMISS_TRANSITION_DURATION_MS = 200;
+ /* The multiplier to apply scale the target size by when applying the magnetic field radius */
+ private static final float MAGNETIC_FIELD_RADIUS_MULTIPLIER = 1.25f;
+
// Allow dragging the PIP to a location to close it
private final boolean mEnableDismissDragToEdge;
// Allow PIP to resize to a slightly bigger state upon touch
@@ -122,7 +128,7 @@ public class PipTouchHandler {
/** Default configuration to use for springing the dismiss target in/out. */
private final PhysicsAnimator.SpringConfig mTargetSpringConfig =
new PhysicsAnimator.SpringConfig(
- SpringForce.STIFFNESS_MEDIUM, SpringForce.DAMPING_RATIO_NO_BOUNCY);
+ SpringForce.STIFFNESS_LOW, SpringForce.DAMPING_RATIO_LOW_BOUNCY);
// The current movement bounds
private Rect mMovementBounds = new Rect();
@@ -217,7 +223,8 @@ public class PipTouchHandler {
PipTaskOrganizer pipTaskOrganizer,
FloatingContentCoordinator floatingContentCoordinator,
DeviceConfigProxy deviceConfig,
- PipSnapAlgorithm pipSnapAlgorithm) {
+ PipSnapAlgorithm pipSnapAlgorithm,
+ SysUiState sysUiState) {
// Initialize the Pip input consumer
mContext = context;
mActivityManager = activityManager;
@@ -232,7 +239,7 @@ public class PipTouchHandler {
mPipResizeGestureHandler =
new PipResizeGestureHandler(context, pipBoundsHandler, mMotionHelper,
deviceConfig, pipTaskOrganizer, this::getMovementBounds,
- this::updateMovementBounds);
+ this::updateMovementBounds, sysUiState);
mTouchState = new PipTouchState(ViewConfiguration.get(context), mHandler,
() -> mMenuController.showMenuWithDelay(MENU_STATE_FULL, mMotionHelper.getBounds(),
true /* allowMenuTimeout */, willResizeMenu(), shouldShowResizeHandle()));
@@ -248,8 +255,9 @@ public class PipTouchHandler {
mPipBoundsHandler = pipBoundsHandler;
mFloatingContentCoordinator = floatingContentCoordinator;
- mConnection = new PipAccessibilityInteractionConnection(mMotionHelper,
- this::onAccessibilityShowMenu, mHandler);
+ mConnection = new PipAccessibilityInteractionConnection(mContext, mMotionHelper,
+ pipTaskOrganizer, pipSnapAlgorithm, this::onAccessibilityShowMenu,
+ this::updateMovementBounds, mHandler);
mTargetView = new DismissCircleView(context);
mTargetViewContainer = new FrameLayout(context);
@@ -262,12 +270,14 @@ public class PipTouchHandler {
mMagneticTarget = mMagnetizedPip.addTarget(mTargetView, 0);
updateMagneticTargetSize();
- mMagnetizedPip.setPhysicsAnimatorUpdateListener(mMotionHelper.mResizePipUpdateListener);
+ mMagnetizedPip.setAnimateStuckToTarget(
+ (target, velX, velY, flung, after) -> {
+ mMotionHelper.animateIntoDismissTarget(target, velX, velY, flung, after);
+ return Unit.INSTANCE;
+ });
mMagnetizedPip.setMagnetListener(new MagnetizedObject.MagnetListener() {
@Override
public void onStuckToTarget(@NonNull MagnetizedObject.MagneticTarget target) {
- mMotionHelper.prepareForAnimation();
-
// Show the dismiss target, in case the initial touch event occurred within the
// magnetic field radius.
showDismissTargetMaybe();
@@ -286,12 +296,13 @@ public class PipTouchHandler {
@Override
public void onReleasedInTarget(@NonNull MagnetizedObject.MagneticTarget target) {
+ mMotionHelper.notifyDismissalPending();
+
mHandler.post(() -> {
mMotionHelper.animateDismiss();
hideDismissTarget();
});
-
MetricsLoggerWrapper.logPictureInPictureDismissByDrag(mContext,
PipUtils.getTopPipActivity(mContext, mActivityManager));
}
@@ -319,11 +330,14 @@ public class PipTouchHandler {
final int targetSize = res.getDimensionPixelSize(R.dimen.dismiss_circle_size);
final FrameLayout.LayoutParams newParams =
new FrameLayout.LayoutParams(targetSize, targetSize);
- newParams.gravity = Gravity.CENTER;
+ newParams.gravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
+ newParams.bottomMargin = mContext.getResources().getDimensionPixelSize(
+ R.dimen.floating_dismiss_bottom_margin);
mTargetView.setLayoutParams(newParams);
- // Set the magnetic field radius equal to twice the size of the target.
- mMagneticTarget.setMagneticFieldRadiusPx(targetSize * 2);
+ // Set the magnetic field radius equal to the target size from the center of the target
+ mMagneticTarget.setMagneticFieldRadiusPx(
+ (int) (targetSize * MAGNETIC_FIELD_RADIUS_MULTIPLIER));
}
private boolean shouldShowResizeHandle() {
@@ -462,9 +476,9 @@ public class PipTouchHandler {
// touching the screen
} else {
final boolean isExpanded = mMenuState == MENU_STATE_FULL && willResizeMenu();
- final Rect toMovementBounds = isExpanded
- ? new Rect(expandedMovementBounds)
- : new Rect(normalMovementBounds);
+ final Rect toMovementBounds = new Rect();
+ mSnapAlgorithm.getMovementBounds(curBounds, insetBounds,
+ toMovementBounds, mIsImeShowing ? mImeHeight : 0);
final int prevBottom = mMovementBounds.bottom - mMovementBoundsExtraOffsets;
final int toBottom = toMovementBounds.bottom < toMovementBounds.top
? toMovementBounds.bottom
@@ -492,6 +506,8 @@ public class PipTouchHandler {
mInsetBounds.set(insetBounds);
updateMovementBounds();
mMovementBoundsExtraOffsets = extraOffset;
+ mConnection.onMovementBoundsChanged(mNormalBounds, mExpandedBounds, mNormalMovementBounds,
+ mExpandedMovementBounds);
// If we have a deferred resize, apply it now
if (mDeferResizeToNormalBoundsUntilRotation == displayRotation) {
@@ -617,11 +633,17 @@ public class PipTouchHandler {
}
MotionEvent ev = (MotionEvent) inputEvent;
-
- if (mPipResizeGestureHandler.isWithinTouchRegion((int) ev.getRawX(), (int) ev.getRawY())) {
+ if (!mTouchState.isDragging()
+ && !mMagnetizedPip.getObjectStuckToTarget()
+ && !mMotionHelper.isAnimating()
+ && mPipResizeGestureHandler.isWithinTouchRegion(
+ (int) ev.getRawX(), (int) ev.getRawY())) {
+ mTouchState.onTouchEvent(ev);
return true;
}
- if (mMagnetizedPip.maybeConsumeMotionEvent(ev)) {
+
+ if ((ev.getAction() == MotionEvent.ACTION_DOWN || mTouchState.isUserInteracting())
+ && mMagnetizedPip.maybeConsumeMotionEvent(ev)) {
// If the first touch event occurs within the magnetic field, pass the ACTION_DOWN event
// to the touch state. Touch state needs a DOWN event in order to later process MOVE
// events it'll receive if the object is dragged out of the magnetic field.
@@ -643,7 +665,6 @@ public class PipTouchHandler {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN: {
- mMotionHelper.synchronizePinnedStackBoundsForTouchGesture();
mGesture.onDown(mTouchState);
break;
}
@@ -688,11 +709,11 @@ public class PipTouchHandler {
break;
}
case MotionEvent.ACTION_HOVER_EXIT: {
- mHideMenuAfterShown = true;
// If Touch Exploration is enabled, some a11y services (e.g. Talkback) is probably
// on and changing MotionEvents into HoverEvents.
// Let's not enable menu show/hide for a11y services.
if (!mAccessibilityManager.isTouchExplorationEnabled()) {
+ mHideMenuAfterShown = true;
mMenuController.hideMenu();
}
if (!shouldDeliverToMenu && mSendingHoverAccessibilityEvents) {
@@ -872,7 +893,7 @@ public class PipTouchHandler {
return;
}
- Rect bounds = mMotionHelper.getBounds();
+ Rect bounds = mMotionHelper.getPossiblyAnimatingBounds();
mDelta.set(0f, 0f);
mStartPosition.set(bounds.left, bounds.top);
mMovementWithinDismiss = touchState.getDownTouchPosition().y >= mMovementBounds.bottom;
@@ -914,7 +935,7 @@ public class PipTouchHandler {
mDelta.x += left - lastX;
mDelta.y += top - lastY;
- mTmpBounds.set(mMotionHelper.getBounds());
+ mTmpBounds.set(mMotionHelper.getPossiblyAnimatingBounds());
mTmpBounds.offsetTo((int) left, (int) top);
mMotionHelper.movePip(mTmpBounds, true /* isDragging */);
@@ -939,7 +960,6 @@ public class PipTouchHandler {
}
final PointF vel = touchState.getVelocity();
- final float velocity = PointF.length(vel.x, vel.y);
if (touchState.isDragging()) {
if (mMenuState != MENU_STATE_NONE) {
@@ -1030,6 +1050,7 @@ public class PipTouchHandler {
pw.println(innerPrefix + "mShelfHeight=" + mShelfHeight);
pw.println(innerPrefix + "mSavedSnapFraction=" + mSavedSnapFraction);
pw.println(innerPrefix + "mEnableDragToEdgeDismiss=" + mEnableDismissDragToEdge);
+ pw.println(innerPrefix + "mMovementBoundsExtraOffsets=" + mMovementBoundsExtraOffsets);
mTouchState.dump(pw, innerPrefix);
mMotionHelper.dump(pw, innerPrefix);
}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchState.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchState.java
index 4be0c157de8e..132c04d381dd 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchState.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchState.java
@@ -31,7 +31,7 @@ import java.io.PrintWriter;
* This keeps track of the touch state throughout the current touch gesture.
*/
public class PipTouchState {
- private static final String TAG = "PipTouchHandler";
+ private static final String TAG = "PipTouchState";
private static final boolean DEBUG = false;
@VisibleForTesting
diff --git a/packages/SystemUI/src/com/android/systemui/qs/NonInterceptingScrollView.java b/packages/SystemUI/src/com/android/systemui/qs/NonInterceptingScrollView.java
index aa17c4aa79b1..309b32fc85d2 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/NonInterceptingScrollView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/NonInterceptingScrollView.java
@@ -46,6 +46,11 @@ public class NonInterceptingScrollView extends ScrollView {
if (parent != null) {
parent.requestDisallowInterceptTouchEvent(true);
}
+ } else if (!canScrollVertically(-1)) {
+ // Don't pass on the touch to the view, because scrolling will unconditionally
+ // disallow interception even if we can't scroll.
+ // if a user can't scroll at all, we should never listen to the touch.
+ return false;
}
break;
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
index 28369925367a..3eed8ad89075 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
@@ -291,15 +291,7 @@ public class PagedTileLayout extends ViewPager implements QSTileLayout {
}
private void emptyAndInflateOrRemovePages() {
- final int nTiles = mTiles.size();
- // We should always have at least one page, even if it's empty.
- int numPages = Math.max(nTiles / mPages.get(0).maxTiles(), 1);
-
- // Add one more not full page if needed
- if (nTiles > numPages * mPages.get(0).maxTiles()) {
- numPages++;
- }
-
+ final int numPages = getNumPages();
final int NP = mPages.size();
for (int i = 0; i < NP; i++) {
mPages.get(i).removeAllViews();
@@ -431,6 +423,22 @@ public class PagedTileLayout extends ViewPager implements QSTileLayout {
return mPages.get(0).mColumns;
}
+ /**
+ * Gets the number of pages in this paged tile layout
+ */
+ public int getNumPages() {
+ final int nTiles = mTiles.size();
+ // We should always have at least one page, even if it's empty.
+ int numPages = Math.max(nTiles / mPages.get(0).maxTiles(), 1);
+
+ // Add one more not full page if needed
+ if (nTiles > numPages * mPages.get(0).maxTiles()) {
+ numPages++;
+ }
+
+ return numPages;
+ }
+
public int getNumVisibleTiles() {
if (mPages.size() == 0) return 0;
TilePage currentPage = mPages.get(getCurrentPageNumber());
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
index bc8f5a8fb652..e66b33c660d6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
@@ -18,7 +18,6 @@ import android.util.Log;
import android.view.View;
import android.view.View.OnAttachStateChangeListener;
import android.view.View.OnLayoutChangeListener;
-import android.widget.ScrollView;
import com.android.systemui.Dependency;
import com.android.systemui.plugins.qs.QS;
@@ -300,10 +299,16 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha
if (mQsPanel.getSecurityFooter() != null) {
builder.addFloat(mQsPanel.getSecurityFooter().getView(), "alpha", 0, 1);
}
+ if (mQsPanel.getDivider() != null) {
+ builder.addFloat(mQsPanel.getDivider(), "alpha", 0, 1);
+ }
mFirstPageDelayedAnimator = builder.build();
if (mQsPanel.getSecurityFooter() != null) {
mAllViews.add(mQsPanel.getSecurityFooter().getView());
}
+ if (mQsPanel.getDivider() != null) {
+ mAllViews.add(mQsPanel.getDivider());
+ }
float px = 0;
float py = 1;
if (tiles.size() <= 3) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
index 0332bc3e0618..6b12e478f627 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
@@ -26,8 +26,12 @@ import android.util.AttributeSet;
import android.view.View;
import android.widget.FrameLayout;
+import androidx.dynamicanimation.animation.FloatPropertyCompat;
+import androidx.dynamicanimation.animation.SpringForce;
+
import com.android.systemui.R;
import com.android.systemui.qs.customize.QSCustomizer;
+import com.android.systemui.util.animation.PhysicsAnimator;
/**
* Wrapper view with background which contains {@link QSPanel} and {@link BaseStatusBarHeader}
@@ -35,7 +39,22 @@ import com.android.systemui.qs.customize.QSCustomizer;
public class QSContainerImpl extends FrameLayout {
private final Point mSizePoint = new Point();
+ private static final FloatPropertyCompat<QSContainerImpl> BACKGROUND_BOTTOM =
+ new FloatPropertyCompat<QSContainerImpl>("backgroundBottom") {
+ @Override
+ public float getValue(QSContainerImpl qsImpl) {
+ return qsImpl.getBackgroundBottom();
+ }
+ @Override
+ public void setValue(QSContainerImpl background, float value) {
+ background.setBackgroundBottom((int) value);
+ }
+ };
+ private static final PhysicsAnimator.SpringConfig BACKGROUND_SPRING
+ = new PhysicsAnimator.SpringConfig(SpringForce.STIFFNESS_MEDIUM,
+ SpringForce.DAMPING_RATIO_LOW_BOUNCY);
+ private int mBackgroundBottom = -1;
private int mHeightOverride = -1;
private QSPanel mQSPanel;
private View mQSDetail;
@@ -53,6 +72,7 @@ public class QSContainerImpl extends FrameLayout {
private boolean mQsDisabled;
private int mContentPaddingStart = -1;
private int mContentPaddingEnd = -1;
+ private boolean mAnimateBottomOnNextLayout;
public QSContainerImpl(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -71,10 +91,30 @@ public class QSContainerImpl extends FrameLayout {
mStatusBarBackground = findViewById(R.id.quick_settings_status_bar_background);
mBackgroundGradient = findViewById(R.id.quick_settings_gradient_view);
updateResources();
+ mHeader.getHeaderQsPanel().setMediaVisibilityChangedListener((visible) -> {
+ if (mHeader.getHeaderQsPanel().isShown()) {
+ mAnimateBottomOnNextLayout = true;
+ }
+ });
+
setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO);
}
+ private void setBackgroundBottom(int value) {
+ // We're saving the bottom separately since otherwise the bottom would be overridden in
+ // the layout and the animation wouldn't properly start at the old position.
+ mBackgroundBottom = value;
+ mBackground.setBottom(value);
+ }
+
+ private float getBackgroundBottom() {
+ if (mBackgroundBottom == -1) {
+ return mBackground.getBottom();
+ }
+ return mBackgroundBottom;
+ }
+
@Override
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
@@ -140,7 +180,8 @@ public class QSContainerImpl extends FrameLayout {
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
- updateExpansion();
+ updateExpansion(mAnimateBottomOnNextLayout /* animate */);
+ mAnimateBottomOnNextLayout = false;
}
public void disable(int state1, int state2, boolean animate) {
@@ -181,13 +222,31 @@ public class QSContainerImpl extends FrameLayout {
}
public void updateExpansion() {
+ updateExpansion(false /* animate */);
+ }
+
+ public void updateExpansion(boolean animate) {
int height = calculateContainerHeight();
setBottom(getTop() + height);
mQSDetail.setBottom(getTop() + height);
// Pin the drag handle to the bottom of the panel.
mDragHandle.setTranslationY(height - mDragHandle.getHeight());
mBackground.setTop(mQSPanelContainer.getTop());
- mBackground.setBottom(height);
+ updateBackgroundBottom(height, animate);
+ }
+
+ private void updateBackgroundBottom(int height, boolean animated) {
+ PhysicsAnimator<QSContainerImpl> physicsAnimator = PhysicsAnimator.getInstance(this);
+ if (physicsAnimator.isPropertyAnimating(BACKGROUND_BOTTOM) || animated) {
+ // An animation is running or we want to animate
+ // Let's make sure to set the currentValue again, since the call below might only
+ // start in the next frame and otherwise we'd flicker
+ BACKGROUND_BOTTOM.setValue(this, BACKGROUND_BOTTOM.getValue(this));
+ physicsAnimator.spring(BACKGROUND_BOTTOM, height, BACKGROUND_SPRING).start();
+ } else {
+ BACKGROUND_BOTTOM.setValue(this, height);
+ }
+
}
protected int calculateContainerHeight() {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java b/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java
index ee3b499edfb7..2be8a9704e1c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java
@@ -25,13 +25,10 @@ import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.drawable.Animatable;
import android.util.AttributeSet;
-import android.util.Pair;
import android.util.SparseArray;
-import android.view.DisplayCutout;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewStub;
-import android.view.WindowInsets;
import android.view.accessibility.AccessibilityEvent;
import android.widget.ImageView;
import android.widget.LinearLayout;
@@ -46,7 +43,6 @@ import com.android.systemui.R;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.qs.DetailAdapter;
import com.android.systemui.statusbar.CommandQueue;
-import com.android.systemui.statusbar.phone.StatusBarWindowView;
public class QSDetail extends LinearLayout {
@@ -283,32 +279,6 @@ public class QSDetail extends LinearLayout {
}
}
- @Override
- public WindowInsets onApplyWindowInsets(WindowInsets insets) {
- DisplayCutout cutout = insets.getDisplayCutout();
-
- Pair<Integer, Integer> padding = StatusBarWindowView.cornerCutoutMargins(
- cutout, getDisplay());
-
- if (padding == null) {
- mQsDetailHeader.setPaddingRelative(
- getResources().getDimensionPixelSize(R.dimen.qs_detail_header_padding),
- getPaddingTop(),
- getResources().getDimensionPixelSize(R.dimen.qs_detail_header_padding),
- getPaddingBottom()
- );
- } else {
- mQsDetailHeader.setPadding(
- padding.first,
- getPaddingTop(),
- padding.second,
- getPaddingBottom()
- );
- }
-
- return super.onApplyWindowInsets(insets);
- }
-
private void handleToggleStateChanged(boolean state, boolean toggleEnabled) {
mSwitchState = state;
if (mAnimatingOpen) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java
index fc8e36ff22cf..c4bb4e86e41e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java
@@ -218,7 +218,7 @@ public class QSFooterImpl extends FrameLayout implements QSFooter,
.addFloat(mActionsContainer, "alpha", 0, 1)
.addFloat(mEditContainer, "alpha", 0, 1)
.addFloat(mPageIndicator, "alpha", 0, 1)
- .setStartDelay(0.15f)
+ .setStartDelay(0.9f)
.build();
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index ecdb2c91ca48..c8a34f010ae4 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -65,6 +65,7 @@ import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.function.Consumer;
import java.util.stream.Collectors;
import javax.inject.Inject;
@@ -117,6 +118,8 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
@Nullable
protected View mFooter;
+ @Nullable
+ protected View mDivider;
@Nullable
private ViewGroup mHeaderContainer;
@@ -141,6 +144,7 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
private int mLastOrientation = -1;
private int mMediaTotalBottomMargin;
private int mFooterMarginStartHorizontal;
+ private Consumer<Boolean> mMediaVisibilityChangedListener;
@Inject
@@ -158,8 +162,8 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
mMediaTotalBottomMargin = getResources().getDimensionPixelSize(
R.dimen.quick_settings_bottom_margin_media);
mMediaHost = mediaHost;
- mMediaHost.setVisibleChangedListener((visible) -> {
- switchTileLayout();
+ mMediaHost.addVisibilityChangeListener((visible) -> {
+ onMediaVisibilityChanged(visible);
return null;
});
mContext = context;
@@ -207,6 +211,13 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
updateResources();
}
+ protected void onMediaVisibilityChanged(Boolean visible) {
+ switchTileLayout();
+ if (mMediaVisibilityChangedListener != null) {
+ mMediaVisibilityChangedListener.accept(visible);
+ }
+ }
+
protected void addSecurityFooter() {
mSecurityFooter = new QSSecurityFooter(this, mContext);
}
@@ -235,13 +246,20 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
protected void initMediaHostState() {
mMediaHost.setExpansion(1.0f);
mMediaHost.setShowsOnlyActiveMedia(false);
+ // Reveal player with some parallax (1.0f would also work)
+ mMediaHost.setGonePivot(0.0f, 0.8f);
mMediaHost.init(MediaHierarchyManager.LOCATION_QS);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-
if (mTileLayout instanceof PagedTileLayout) {
+ // Since PageIndicator gets measured before PagedTileLayout, we preemptively set the
+ // # of pages before the measurement pass so PageIndicator is measured appropriately
+ if (mFooterPageIndicator != null) {
+ mFooterPageIndicator.setNumPages(((PagedTileLayout) mTileLayout).getNumPages());
+ }
+
// Allow the UI to be as big as it want's to, we're in a scroll view
int newHeight = 10000;
int availableHeight = MeasureSpec.getSize(heightMeasureSpec);
@@ -472,6 +490,7 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
protected void onFinishInflate() {
super.onFinishInflate();
mFooter = findViewById(R.id.qs_footer);
+ mDivider = findViewById(R.id.divider);
switchTileLayout(true /* force */);
}
@@ -482,6 +501,13 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
private boolean switchTileLayout(boolean force) {
/** Whether or not the QuickQSPanel currently contains a media player. */
boolean horizontal = shouldUseHorizontalLayout();
+ if (mDivider != null) {
+ if (!horizontal && mUsingMediaPlayer && mMediaHost.getVisible()) {
+ mDivider.setVisibility(View.VISIBLE);
+ } else {
+ mDivider.setVisibility(View.GONE);
+ }
+ }
if (horizontal != mUsingHorizontalLayout || force) {
mUsingHorizontalLayout = horizontal;
View visibleView = horizontal ? mHorizontalLinearLayout : (View) mRegularTileLayout;
@@ -515,6 +541,7 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
}
updateTileLayoutMargins();
updateFooterMargin();
+ updateDividerMargin();
updateMediaHostContentMargins();
updateHorizontalLinearLayoutMargins();
updatePadding();
@@ -964,6 +991,11 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
return mSecurityFooter;
}
+ @Nullable
+ public View getDivider() {
+ return mDivider;
+ }
+
public void showDeviceMonitoringDialog() {
if (mSecurityFooter != null) {
mSecurityFooter.showDeviceMonitoringDialog();
@@ -979,6 +1011,7 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
mContentMarginEnd - mVisualTilePadding);
updateMediaHostContentMargins();
updateFooterMargin();
+ updateDividerMargin();
}
private void updateFooterMargin() {
@@ -1020,6 +1053,11 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
updateMargins((View) mTileLayout, mVisualMarginStart, marginEnd);
}
+ private void updateDividerMargin() {
+ if (mDivider == null) return;
+ updateMargins(mDivider, mContentMarginStart, mContentMarginEnd);
+ }
+
/**
* Update the margins of the media hosts
*/
@@ -1058,6 +1096,10 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
mHeaderContainer = headerContainer;
}
+ public void setMediaVisibilityChangedListener(Consumer<Boolean> visibilityChangedListener) {
+ mMediaVisibilityChangedListener = visibilityChangedListener;
+ }
+
private class H extends Handler {
private static final int SHOW_DETAIL = 1;
private static final int SET_TILE_VISIBILITY = 2;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java b/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java
index 7bcaa7263cc4..51eca67e02f9 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java
@@ -148,14 +148,19 @@ public class QSSecurityFooter implements OnClickListener, DialogInterface.OnClic
final String vpnName = mSecurityController.getPrimaryVpnName();
final String vpnNameWorkProfile = mSecurityController.getWorkProfileVpnName();
final CharSequence organizationName = mSecurityController.getDeviceOwnerOrganizationName();
- final CharSequence workProfileName = mSecurityController.getWorkProfileOrganizationName();
+ final CharSequence workProfileOrganizationName =
+ mSecurityController.getWorkProfileOrganizationName();
+ final boolean isProfileOwnerOfOrganizationOwnedDevice =
+ mSecurityController.isProfileOwnerOfOrganizationOwnedDevice();
// Update visibility of footer
- mIsVisible = (isDeviceManaged && !isDemoDevice) || hasCACerts || hasCACertsInWorkProfile ||
- vpnName != null || vpnNameWorkProfile != null;
+ mIsVisible = (isDeviceManaged && !isDemoDevice) || hasCACerts || hasCACertsInWorkProfile
+ || vpnName != null || vpnNameWorkProfile != null
+ || isProfileOwnerOfOrganizationOwnedDevice;
// Update the string
mFooterTextContent = getFooterText(isDeviceManaged, hasWorkProfile,
hasCACerts, hasCACertsInWorkProfile, isNetworkLoggingEnabled, vpnName,
- vpnNameWorkProfile, organizationName, workProfileName);
+ vpnNameWorkProfile, organizationName, workProfileOrganizationName,
+ isProfileOwnerOfOrganizationOwnedDevice);
// Update the icon
int footerIconId = R.drawable.ic_info_outline;
if (vpnName != null || vpnNameWorkProfile != null) {
@@ -175,7 +180,8 @@ public class QSSecurityFooter implements OnClickListener, DialogInterface.OnClic
protected CharSequence getFooterText(boolean isDeviceManaged, boolean hasWorkProfile,
boolean hasCACerts, boolean hasCACertsInWorkProfile, boolean isNetworkLoggingEnabled,
String vpnName, String vpnNameWorkProfile, CharSequence organizationName,
- CharSequence workProfileName) {
+ CharSequence workProfileOrganizationName,
+ boolean isProfileOwnerOfOrganizationOwnedDevice) {
if (isDeviceManaged || DEBUG_FORCE_VISIBLE) {
if (hasCACerts || hasCACertsInWorkProfile || isNetworkLoggingEnabled) {
if (organizationName == null) {
@@ -211,13 +217,13 @@ public class QSSecurityFooter implements OnClickListener, DialogInterface.OnClic
organizationName);
} // end if(isDeviceManaged)
if (hasCACertsInWorkProfile) {
- if (workProfileName == null) {
+ if (workProfileOrganizationName == null) {
return mContext.getString(
R.string.quick_settings_disclosure_managed_profile_monitoring);
}
return mContext.getString(
R.string.quick_settings_disclosure_named_managed_profile_monitoring,
- workProfileName);
+ workProfileOrganizationName);
}
if (hasCACerts) {
return mContext.getString(R.string.quick_settings_disclosure_monitoring);
@@ -238,6 +244,13 @@ public class QSSecurityFooter implements OnClickListener, DialogInterface.OnClic
return mContext.getString(R.string.quick_settings_disclosure_named_vpn,
vpnName);
}
+ if (isProfileOwnerOfOrganizationOwnedDevice) {
+ if (workProfileOrganizationName == null) {
+ return mContext.getString(R.string.quick_settings_disclosure_management);
+ }
+ return mContext.getString(R.string.quick_settings_disclosure_named_management,
+ workProfileOrganizationName);
+ }
return null;
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
index 858a7e2e30e0..1f3967c03a41 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
@@ -477,7 +477,7 @@ public class QSTileHost implements QSHost, Tunable, PluginListener<QSFactory>, D
tiles.addAll(Arrays.asList(defaultTileList.split(",")));
if (Build.IS_DEBUGGABLE
- && GarbageMonitor.MemoryTile.ADD_TO_DEFAULT_ON_DEBUGGABLE_BUILDS) {
+ && GarbageMonitor.ADD_MEMORY_TILE_TO_DEFAULT_ON_DEBUGGABLE_BUILDS) {
tiles.add(GarbageMonitor.MemoryTile.TILE_SPEC);
}
return tiles;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
index 311eda2f4ad8..b5afe771926c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
@@ -15,6 +15,7 @@
package com.android.systemui.qs;
import static android.app.StatusBarManager.DISABLE2_QUICK_SETTINGS;
+import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
import static com.android.systemui.util.InjectionInflationController.VIEW_CONTEXT;
@@ -41,6 +42,7 @@ import android.util.Pair;
import android.view.ContextThemeWrapper;
import android.view.DisplayCutout;
import android.view.View;
+import android.view.ViewGroup;
import android.view.WindowInsets;
import android.widget.ImageView;
import android.widget.RelativeLayout;
@@ -347,6 +349,15 @@ public class QuickStatusBarHeader extends RelativeLayout implements
com.android.internal.R.dimen.quick_qs_offset_height);
mSystemIconsView.setLayoutParams(mSystemIconsView.getLayoutParams());
+ ViewGroup.LayoutParams lp = getLayoutParams();
+ if (mQsDisabled) {
+ lp.height = resources.getDimensionPixelSize(
+ com.android.internal.R.dimen.quick_qs_offset_height);
+ } else {
+ lp.height = WRAP_CONTENT;
+ }
+ setLayoutParams(lp);
+
updateStatusIconAlphaAnimator();
updateHeaderTextContainerAlphaAnimator();
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
index 87faaccf2063..795d0627c447 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
@@ -14,8 +14,8 @@
package com.android.systemui.qs.tileimpl;
-import static androidx.lifecycle.Lifecycle.State.DESTROYED;
import static androidx.lifecycle.Lifecycle.State.RESUMED;
+import static androidx.lifecycle.Lifecycle.State.STARTED;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_QS_CLICK;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_QS_LONG_PRESS;
@@ -432,17 +432,19 @@ public abstract class QSTileImpl<TState extends State> implements QSTile, Lifecy
}
private void handleSetListeningInternal(Object listener, boolean listening) {
+ // This should be used to go from resumed to paused. Listening for ON_RESUME and ON_PAUSE
+ // in this lifecycle will determine the listening window.
if (listening) {
if (mListeners.add(listener) && mListeners.size() == 1) {
if (DEBUG) Log.d(TAG, "handleSetListening true");
- mLifecycle.markState(RESUMED);
+ mLifecycle.setCurrentState(RESUMED);
handleSetListening(listening);
refreshState(); // Ensure we get at least one refresh after listening.
}
} else {
if (mListeners.remove(listener) && mListeners.size() == 0) {
if (DEBUG) Log.d(TAG, "handleSetListening false");
- mLifecycle.markState(DESTROYED);
+ mLifecycle.setCurrentState(STARTED);
handleSetListening(listening);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java
index f3e2f104621e..f89185e3efa9 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java
@@ -118,6 +118,7 @@ public class OverviewProxyRecentsImpl implements RecentsImplementation {
try {
if (mOverviewProxyService.getProxy() != null) {
mOverviewProxyService.getProxy().onOverviewToggle();
+ mOverviewProxyService.notifyToggleRecentApps();
}
} catch (RemoteException e) {
Log.e(TAG, "Cannot send toggle recents through proxy service.", e);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
index 8a012b8b06f1..790b2585190d 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
@@ -200,11 +200,13 @@ public class OverviewProxyService extends CurrentUserTracker implements
mInputFocusTransferStartY = event.getY();
mInputFocusTransferStartMillis = event.getEventTime();
statusBar.onInputFocusTransfer(
- mInputFocusTransferStarted, 0 /* velocity */);
+ mInputFocusTransferStarted, false /* cancel */,
+ 0 /* velocity */);
}
if (action == ACTION_UP || action == ACTION_CANCEL) {
mInputFocusTransferStarted = false;
statusBar.onInputFocusTransfer(mInputFocusTransferStarted,
+ action == ACTION_CANCEL,
(event.getY() - mInputFocusTransferStartY)
/ (event.getEventTime() - mInputFocusTransferStartMillis));
}
@@ -692,7 +694,8 @@ public class OverviewProxyService extends CurrentUserTracker implements
mHandler.post(()-> {
mStatusBarOptionalLazy.ifPresent(statusBarLazy -> {
mInputFocusTransferStarted = false;
- statusBarLazy.get().onInputFocusTransfer(false, 0 /* velocity */);
+ statusBarLazy.get().onInputFocusTransfer(false, true /* cancel */,
+ 0 /* velocity */);
});
});
}
@@ -871,6 +874,12 @@ public class OverviewProxyService extends CurrentUserTracker implements
}
}
+ void notifyToggleRecentApps() {
+ for (int i = mConnectionCallbacks.size() - 1; i >= 0; --i) {
+ mConnectionCallbacks.get(i).onToggleRecentApps();
+ }
+ }
+
private void updateEnabledState() {
mIsEnabled = mContext.getPackageManager().resolveServiceAsUser(mQuickStepIntent,
MATCH_SYSTEM_ONLY,
@@ -901,6 +910,8 @@ public class OverviewProxyService extends CurrentUserTracker implements
default void onQuickSwitchToNewTask(@Surface.Rotation int rotation) {}
default void onOverviewShown(boolean fromHome) {}
default void onQuickScrubStarted() {}
+ /** Notify the recents app (overview) is started by 3-button navigation. */
+ default void onToggleRecentApps() {}
/** Notify changes in the nav bar button alpha */
default void onNavBarButtonAlphaChanged(float alpha, boolean animate) {}
default void onSystemUiStateChanged(int sysuiStateFlags) {}
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
index f2e8599536ca..87597263168a 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
@@ -311,7 +311,7 @@ public class RecordingService extends Service implements MediaRecorder.OnInfoLis
this,
REQUEST_CODE,
viewIntent,
- Intent.FLAG_GRANT_READ_URI_PERMISSION))
+ PendingIntent.FLAG_IMMUTABLE))
.addAction(shareAction)
.addAction(deleteAction)
.setAutoCancel(true)
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordDialog.java b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordDialog.java
index d057a8a43c43..8347def2d430 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordDialog.java
@@ -97,6 +97,9 @@ public class ScreenRecordDialog extends Activity {
mModes);
a.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mOptions.setAdapter(a);
+ mOptions.setOnItemClickListenerInt((parent, view, position, id) -> {
+ mAudioSwitch.setChecked(true);
+ });
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index 7babe2f4f2db..9bbc4ddcc62c 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -18,10 +18,8 @@ package com.android.systemui.screenshot;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
-import static android.provider.DeviceConfig.NAMESPACE_SYSTEMUI;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
-import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.SCREENSHOT_SCROLLING_ENABLED;
import static com.android.systemui.statusbar.phone.StatusBar.SYSTEM_DIALOG_REASON_SCREENSHOT;
import android.animation.Animator;
@@ -51,7 +49,6 @@ import android.graphics.Region;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
-import android.graphics.drawable.Icon;
import android.graphics.drawable.InsetDrawable;
import android.graphics.drawable.LayerDrawable;
import android.media.MediaActionSound;
@@ -62,13 +59,13 @@ import android.os.Message;
import android.os.PowerManager;
import android.os.RemoteException;
import android.os.UserHandle;
-import android.provider.DeviceConfig;
import android.provider.Settings;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.MathUtils;
import android.util.Slog;
import android.view.Display;
+import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.SurfaceControl;
@@ -215,7 +212,6 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
private Animator mScreenshotAnimation;
private Runnable mOnCompleteRunnable;
private Animator mDismissAnimation;
- private SavedImageData mImageData;
private boolean mInDarkMode = false;
private boolean mDirectionLTR = true;
private boolean mOrientationPortrait = true;
@@ -234,9 +230,6 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
switch (msg.what) {
case MESSAGE_CORNER_TIMEOUT:
mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_INTERACTION_TIMEOUT);
- if (mImageData != null) {
- mNotificationsController.showSilentScreenshotNotification(mImageData);
- }
GlobalScreenshot.this.dismissScreenshot("timeout", false);
mOnCompleteRunnable.run();
break;
@@ -378,6 +371,20 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
// Inflate the screenshot layout
mScreenshotLayout = LayoutInflater.from(mContext).inflate(R.layout.global_screenshot, null);
+ mScreenshotLayout.setOnKeyListener(new View.OnKeyListener() {
+ @Override
+ public boolean onKey(View v, int keyCode, KeyEvent event) {
+ if (keyCode == KeyEvent.KEYCODE_BACK) {
+ dismissScreenshot("back pressed", true);
+ return true;
+ }
+ return false;
+ }
+ });
+ // Get focus so that the key events go to the layout.
+ mScreenshotLayout.setFocusableInTouchMode(true);
+ mScreenshotLayout.requestFocus();
+
mScreenshotAnimatedView =
mScreenshotLayout.findViewById(R.id.global_screenshot_animated_view);
mScreenshotAnimatedView.setClipToOutline(true);
@@ -408,9 +415,6 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
mDismissButton = mScreenshotLayout.findViewById(R.id.global_screenshot_dismiss_button);
mDismissButton.setOnClickListener(view -> {
mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_EXPLICIT_DISMISSAL);
- if (mImageData != null) {
- mNotificationsController.showSilentScreenshotNotification(mImageData);
- }
dismissScreenshot("dismiss_button", false);
mOnCompleteRunnable.run();
});
@@ -450,10 +454,6 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
});
}
- mImageData = null; // make sure we clear the current stored data
- mNotificationsController.reset();
- mNotificationsController.setImage(mScreenBitmap);
-
mSaveInBgTask = new SaveImageInBackgroundTask(mContext, data);
mSaveInBgTask.execute();
}
@@ -622,7 +622,7 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
/**
* Clears current screenshot
*/
- private void dismissScreenshot(String reason, boolean immediate) {
+ void dismissScreenshot(String reason, boolean immediate) {
Log.v(TAG, "clearing screenshot: " + reason);
mScreenshotHandler.removeMessages(MESSAGE_CORNER_TIMEOUT);
mScreenshotLayout.getViewTreeObserver().removeOnComputeInternalInsetsListener(this);
@@ -670,7 +670,6 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
*/
private void showUiOnActionsReady(SavedImageData imageData) {
logSuccessOnActionsReady(imageData);
- mImageData = imageData;
AccessibilityManager accessibilityManager = (AccessibilityManager)
mContext.getSystemService(Context.ACCESSIBILITY_SERVICE);
@@ -952,22 +951,6 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
});
mScreenshotPreview.setContentDescription(imageData.editAction.title);
- if (DeviceConfig.getBoolean(NAMESPACE_SYSTEMUI, SCREENSHOT_SCROLLING_ENABLED, false)) {
- ScreenshotActionChip scrollChip = (ScreenshotActionChip) inflater.inflate(
- R.layout.global_screenshot_action_chip, mActionsView, false);
- Toast scrollNotImplemented = Toast.makeText(
- mContext, "Not implemented", Toast.LENGTH_SHORT);
- scrollChip.setText("Extend"); // TODO: add resource and translate
- scrollChip.setIcon(
- Icon.createWithResource(mContext, R.drawable.ic_arrow_downward), true);
- scrollChip.setOnClickListener(v -> {
- mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_SCROLL_TAPPED);
- scrollNotImplemented.show();
- });
- mActionsView.addView(scrollChip);
- chips.add(scrollChip);
- }
-
// remove the margin from the last chip so that it's correctly aligned with the end
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams)
mActionsView.getChildAt(mActionsView.getChildCount() - 1).getLayoutParams();
@@ -1122,14 +1105,19 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
return;
}
- Intent actionIntent = intent.getParcelableExtra(EXTRA_ACTION_INTENT);
+ PendingIntent actionIntent = intent.getParcelableExtra(EXTRA_ACTION_INTENT);
if (intent.getBooleanExtra(EXTRA_CANCEL_NOTIFICATION, false)) {
ScreenshotNotificationsController.cancelScreenshotNotification(context);
}
ActivityOptions opts = ActivityOptions.makeBasic();
opts.setDisallowEnterPictureInPictureWhileLaunching(
intent.getBooleanExtra(EXTRA_DISALLOW_ENTER_PIP, false));
- context.startActivityAsUser(actionIntent, opts.toBundle(), UserHandle.CURRENT);
+ try {
+ actionIntent.send(context, 0, null, null, null, null, opts.toBundle());
+ } catch (PendingIntent.CanceledException e) {
+ Log.e(TAG, "Pending intent canceled", e);
+ }
+
};
if (mStatusBar != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java b/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java
index 10e6902f139e..e3fbdbc7c30d 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java
@@ -281,11 +281,13 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> {
Intent.createChooser(sharingIntent, null, chooserAction.getIntentSender())
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK)
.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ PendingIntent pendingIntent = PendingIntent.getActivityAsUser(context, requestCode,
+ sharingChooserIntent, 0, null, UserHandle.CURRENT);
// Create a share action for the notification
PendingIntent shareAction = PendingIntent.getBroadcastAsUser(context, requestCode,
new Intent(context, GlobalScreenshot.ActionProxyReceiver.class)
- .putExtra(GlobalScreenshot.EXTRA_ACTION_INTENT, sharingChooserIntent)
+ .putExtra(GlobalScreenshot.EXTRA_ACTION_INTENT, pendingIntent)
.putExtra(GlobalScreenshot.EXTRA_DISALLOW_ENTER_PIP, true)
.putExtra(GlobalScreenshot.EXTRA_ID, mScreenshotId)
.putExtra(GlobalScreenshot.EXTRA_SMART_ACTIONS_ENABLED,
@@ -320,14 +322,17 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> {
editIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
editIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ PendingIntent pendingIntent = PendingIntent.getActivityAsUser(context, 0,
+ editIntent, 0, null, UserHandle.CURRENT);
+
// Make sure pending intents for the system user are still unique across users
// by setting the (otherwise unused) request code to the current user id.
int requestCode = mContext.getUserId();
// Create a edit action
- PendingIntent editAction = PendingIntent.getBroadcast(context, requestCode,
+ PendingIntent editAction = PendingIntent.getBroadcastAsUser(context, requestCode,
new Intent(context, GlobalScreenshot.ActionProxyReceiver.class)
- .putExtra(GlobalScreenshot.EXTRA_ACTION_INTENT, editIntent)
+ .putExtra(GlobalScreenshot.EXTRA_ACTION_INTENT, pendingIntent)
.putExtra(GlobalScreenshot.EXTRA_CANCEL_NOTIFICATION,
editIntent.getComponent() != null)
.putExtra(GlobalScreenshot.EXTRA_ID, mScreenshotId)
@@ -335,7 +340,7 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> {
mSmartActionsEnabled)
.setAction(Intent.ACTION_EDIT)
.addFlags(Intent.FLAG_RECEIVER_FOREGROUND),
- PendingIntent.FLAG_CANCEL_CURRENT);
+ PendingIntent.FLAG_CANCEL_CURRENT, UserHandle.SYSTEM);
Notification.Action.Builder editActionBuilder = new Notification.Action.Builder(
Icon.createWithResource(r, R.drawable.ic_screenshot_edit),
r.getString(com.android.internal.R.string.screenshot_edit), editAction);
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotNotificationsController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotNotificationsController.java
index e4e253e71fb3..fbcd6ba0ff47 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotNotificationsController.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotNotificationsController.java
@@ -148,11 +148,43 @@ public class ScreenshotNotificationsController {
}
/**
- * Shows a silent notification with the saved screenshot and actions that can be taken with it.
+ * Shows a notification to inform the user that a screenshot is currently being saved.
+ */
+ public void showSavingScreenshotNotification() {
+ final long now = System.currentTimeMillis();
+
+ mPublicNotificationBuilder
+ .setContentTitle(mResources.getString(R.string.screenshot_saving_title))
+ .setSmallIcon(R.drawable.stat_notify_image)
+ .setCategory(Notification.CATEGORY_PROGRESS)
+ .setWhen(now)
+ .setShowWhen(true)
+ .setColor(mResources.getColor(
+ com.android.internal.R.color.system_notification_accent_color));
+ SystemUI.overrideNotificationAppName(mContext, mPublicNotificationBuilder, true);
+
+ mNotificationBuilder
+ .setContentTitle(mResources.getString(R.string.screenshot_saving_title))
+ .setSmallIcon(R.drawable.stat_notify_image)
+ .setWhen(now)
+ .setShowWhen(true)
+ .setColor(mResources.getColor(
+ com.android.internal.R.color.system_notification_accent_color))
+ .setStyle(mNotificationStyle)
+ .setPublicVersion(mPublicNotificationBuilder.build());
+ mNotificationBuilder.setFlag(Notification.FLAG_NO_CLEAR, true);
+ SystemUI.overrideNotificationAppName(mContext, mNotificationBuilder, true);
+
+ mNotificationManager.notify(SystemMessageProto.SystemMessage.NOTE_GLOBAL_SCREENSHOT,
+ mNotificationBuilder.build());
+ }
+
+ /**
+ * Shows a notification with the saved screenshot and actions that can be taken with it.
*
* @param actionData SavedImageData struct with image URI and actions
*/
- public void showSilentScreenshotNotification(
+ public void showScreenshotActionsNotification(
GlobalScreenshot.SavedImageData actionData) {
mNotificationBuilder.addAction(actionData.shareAction);
mNotificationBuilder.addAction(actionData.editAction);
@@ -174,34 +206,20 @@ public class ScreenshotNotificationsController {
.setContentTitle(mResources.getString(R.string.screenshot_saved_title))
.setContentText(mResources.getString(R.string.screenshot_saved_text))
.setContentIntent(PendingIntent.getActivity(mContext, 0, launchIntent, 0))
- .setSmallIcon(R.drawable.stat_notify_image)
- .setCategory(Notification.CATEGORY_PROGRESS)
.setWhen(now)
- .setShowWhen(true)
.setAutoCancel(true)
.setColor(mContext.getColor(
- com.android.internal.R.color.system_notification_accent_color))
- .setGroup("silent")
- .setGroupAlertBehavior(Notification.GROUP_ALERT_SUMMARY);
+ com.android.internal.R.color.system_notification_accent_color));
mNotificationBuilder
.setContentTitle(mResources.getString(R.string.screenshot_saved_title))
.setContentText(mResources.getString(R.string.screenshot_saved_text))
.setContentIntent(PendingIntent.getActivity(mContext, 0, launchIntent, 0))
- .setSmallIcon(R.drawable.stat_notify_image)
- .setCategory(Notification.CATEGORY_PROGRESS)
.setWhen(now)
- .setShowWhen(true)
.setAutoCancel(true)
.setColor(mContext.getColor(
com.android.internal.R.color.system_notification_accent_color))
.setPublicVersion(mPublicNotificationBuilder.build())
- .setStyle(mNotificationStyle)
- .setFlag(Notification.FLAG_NO_CLEAR, false)
- .setGroup("silent")
- .setGroupAlertBehavior(Notification.GROUP_ALERT_SUMMARY);
-
- SystemUI.overrideNotificationAppName(mContext, mPublicNotificationBuilder, true);
- SystemUI.overrideNotificationAppName(mContext, mNotificationBuilder, true);
+ .setFlag(Notification.FLAG_NO_CLEAR, false);
mNotificationManager.notify(SystemMessageProto.SystemMessage.NOTE_GLOBAL_SCREENSHOT,
mNotificationBuilder.build());
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java
index c05c8236def0..9f8a9bb4a432 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java
@@ -16,12 +16,17 @@
package com.android.systemui.screenshot;
+import static android.content.Intent.ACTION_CLOSE_SYSTEM_DIALOGS;
+
import static com.android.internal.util.ScreenshotHelper.SCREENSHOT_MSG_PROCESS_COMPLETE;
import static com.android.internal.util.ScreenshotHelper.SCREENSHOT_MSG_URI;
import android.app.Service;
+import android.content.BroadcastReceiver;
import android.content.ComponentName;
+import android.content.Context;
import android.content.Intent;
+import android.content.IntentFilter;
import android.graphics.Bitmap;
import android.graphics.Insets;
import android.graphics.Rect;
@@ -51,6 +56,16 @@ public class TakeScreenshotService extends Service {
private final UserManager mUserManager;
private final UiEventLogger mUiEventLogger;
+ private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (ACTION_CLOSE_SYSTEM_DIALOGS.equals(intent.getAction()) && mScreenshot != null) {
+ mScreenshot.dismissScreenshot("close system dialogs", true);
+ }
+ }
+ };
+
private Handler mHandler = new Handler(Looper.myLooper()) {
@Override
public void handleMessage(Message msg) {
@@ -119,12 +134,18 @@ public class TakeScreenshotService extends Service {
@Override
public IBinder onBind(Intent intent) {
+ // register broadcast receiver
+ IntentFilter filter = new IntentFilter(ACTION_CLOSE_SYSTEM_DIALOGS);
+ registerReceiver(mBroadcastReceiver, filter);
+
return new Messenger(mHandler).getBinder();
+
}
@Override
public boolean onUnbind(Intent intent) {
if (mScreenshot != null) mScreenshot.stopScreenshot();
+ unregisterReceiver(mBroadcastReceiver);
return true;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java b/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java
index 821144a7f12d..71e788375d5e 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java
@@ -443,14 +443,10 @@ public class BrightnessController implements ToggleSlider.Listener {
max = mMaximumBacklight;
}
// convertGammaToLinearFloat returns 0-1
- if (BrightnessSynchronizer.brightnessFloatToInt(mContext, brightnessValue)
- == BrightnessSynchronizer.brightnessFloatToInt(mContext,
+ if (BrightnessSynchronizer.floatEquals(brightnessValue,
convertGammaToLinearFloat(mControl.getValue(), min, max))) {
- // If we have more resolution on the slider than we do in the actual setting, then
- // multiple slider positions will map to the same setting value. Thus, if we see a
- // setting value here that maps to the current slider position, we don't bother to
- // calculate the new slider position since it may differ and look like a brightness
- // change to the user even though it isn't one.
+ // If the value in the slider is equal to the value on the current brightness
+ // then the slider does not need to animate, since the brightness will not change.
return;
}
// Returns GAMMA_SPACE_MIN - GAMMA_SPACE_MAX
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
index 166934599aeb..8a3819925f30 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
@@ -127,7 +127,7 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks,
snap.calculateNonDismissingSnapTarget(position);
sdl.resizeSplits(target.position, t);
- if (isSplitActive()) {
+ if (isSplitActive() && mHomeStackResizable) {
WindowManagerProxy.applyHomeTasksMinimized(sdl, mSplits.mSecondary.token, t);
}
if (mWindowManagerProxy.queueSyncTransactionIfWaiting(t)) {
@@ -384,6 +384,7 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks,
}
// Always set this because we could be entering split when mMinimized is already true
wct.setFocusable(mSplits.mPrimary.token, !mMinimized);
+ boolean onlyFocusable = true;
// Update home-stack resizability
final boolean homeResizableChanged = mHomeStackResizable != homeStackResizable;
@@ -392,6 +393,7 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks,
if (isDividerVisible()) {
WindowManagerProxy.applyHomeTasksMinimized(
mSplitLayout, mSplits.mSecondary.token, wct);
+ onlyFocusable = false;
}
}
@@ -413,7 +415,15 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks,
}
}
updateTouchable();
- mWindowManagerProxy.applySyncTransaction(wct);
+ if (onlyFocusable) {
+ // If we are only setting focusability, a sync transaction isn't necessary (in fact it
+ // can interrupt other animations), so see if it can be submitted on pending instead.
+ if (!mSplits.mDivider.getWmProxy().queueSyncTransactionIfWaiting(wct)) {
+ WindowOrganizer.applyTransaction(wct);
+ }
+ } else {
+ mWindowManagerProxy.applySyncTransaction(wct);
+ }
}
void setAdjustedForIme(boolean adjustedForIme) {
@@ -425,7 +435,7 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks,
}
private void updateTouchable() {
- mWindowManager.setTouchable((mHomeStackResizable || !mMinimized) && !mAdjustedForIme);
+ mWindowManager.setTouchable(!mAdjustedForIme);
}
/**
@@ -520,7 +530,7 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks,
}
void ensureMinimizedSplit() {
- setHomeMinimized(true /* minimized */, mSplits.mSecondary.isResizable());
+ setHomeMinimized(true /* minimized */, mHomeStackResizable);
if (mView != null && !isDividerVisible()) {
// Wasn't in split-mode yet, so enter now.
if (DEBUG) {
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerImeController.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerImeController.java
index aea87f2d1971..47c8c0ad8a4e 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerImeController.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerImeController.java
@@ -29,6 +29,7 @@ import android.view.SurfaceControl;
import android.window.TaskOrganizer;
import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction;
+import android.window.WindowOrganizer;
import androidx.annotation.Nullable;
@@ -126,16 +127,16 @@ class DividerImeController implements DisplayImeController.ImePositionProcessor
@Override
public void onImeStartPositioning(int displayId, int hiddenTop, int shownTop,
boolean imeShouldShow, SurfaceControl.Transaction t) {
+ mHiddenTop = hiddenTop;
+ mShownTop = shownTop;
+ mTargetShown = imeShouldShow;
if (!isDividerVisible()) {
return;
}
final boolean splitIsVisible = !getView().isHidden();
mSecondaryHasFocus = getSecondaryHasFocus(displayId);
final boolean targetAdjusted = splitIsVisible && imeShouldShow && mSecondaryHasFocus
- && !getLayout().mDisplayLayout.isLandscape();
- mHiddenTop = hiddenTop;
- mShownTop = shownTop;
- mTargetShown = imeShouldShow;
+ && !getLayout().mDisplayLayout.isLandscape() && !mSplits.mDivider.isMinimized();
if (mLastAdjustTop < 0) {
mLastAdjustTop = imeShouldShow ? hiddenTop : shownTop;
} else if (mLastAdjustTop != (imeShouldShow ? mShownTop : mHiddenTop)) {
@@ -173,46 +174,50 @@ class DividerImeController implements DisplayImeController.ImePositionProcessor
}
private void updateImeAdjustState() {
- // Reposition the server's secondary split position so that it evaluates
- // insets properly.
- WindowContainerTransaction wct = new WindowContainerTransaction();
- final SplitDisplayLayout splitLayout = getLayout();
- if (mTargetAdjusted) {
- splitLayout.updateAdjustedBounds(mShownTop, mHiddenTop, mShownTop);
- wct.setBounds(mSplits.mSecondary.token, splitLayout.mAdjustedSecondary);
- // "Freeze" the configuration size so that the app doesn't get a config
- // or relaunch. This is required because normally nav-bar contributes
- // to configuration bounds (via nondecorframe).
- Rect adjustAppBounds = new Rect(mSplits.mSecondary.configuration
- .windowConfiguration.getAppBounds());
- adjustAppBounds.offset(0, splitLayout.mAdjustedSecondary.top
- - splitLayout.mSecondary.top);
- wct.setAppBounds(mSplits.mSecondary.token, adjustAppBounds);
- wct.setScreenSizeDp(mSplits.mSecondary.token,
- mSplits.mSecondary.configuration.screenWidthDp,
- mSplits.mSecondary.configuration.screenHeightDp);
-
- wct.setBounds(mSplits.mPrimary.token, splitLayout.mAdjustedPrimary);
- adjustAppBounds = new Rect(mSplits.mPrimary.configuration
- .windowConfiguration.getAppBounds());
- adjustAppBounds.offset(0, splitLayout.mAdjustedPrimary.top
- - splitLayout.mPrimary.top);
- wct.setAppBounds(mSplits.mPrimary.token, adjustAppBounds);
- wct.setScreenSizeDp(mSplits.mPrimary.token,
- mSplits.mPrimary.configuration.screenWidthDp,
- mSplits.mPrimary.configuration.screenHeightDp);
- } else {
- wct.setBounds(mSplits.mSecondary.token, splitLayout.mSecondary);
- wct.setAppBounds(mSplits.mSecondary.token, null);
- wct.setScreenSizeDp(mSplits.mSecondary.token,
- SCREEN_WIDTH_DP_UNDEFINED, SCREEN_HEIGHT_DP_UNDEFINED);
- wct.setBounds(mSplits.mPrimary.token, splitLayout.mPrimary);
- wct.setAppBounds(mSplits.mPrimary.token, null);
- wct.setScreenSizeDp(mSplits.mPrimary.token,
- SCREEN_WIDTH_DP_UNDEFINED, SCREEN_HEIGHT_DP_UNDEFINED);
- }
+ if (mAdjusted != mTargetAdjusted) {
+ // Reposition the server's secondary split position so that it evaluates
+ // insets properly.
+ WindowContainerTransaction wct = new WindowContainerTransaction();
+ final SplitDisplayLayout splitLayout = getLayout();
+ if (mTargetAdjusted) {
+ splitLayout.updateAdjustedBounds(mShownTop, mHiddenTop, mShownTop);
+ wct.setBounds(mSplits.mSecondary.token, splitLayout.mAdjustedSecondary);
+ // "Freeze" the configuration size so that the app doesn't get a config
+ // or relaunch. This is required because normally nav-bar contributes
+ // to configuration bounds (via nondecorframe).
+ Rect adjustAppBounds = new Rect(mSplits.mSecondary.configuration
+ .windowConfiguration.getAppBounds());
+ adjustAppBounds.offset(0, splitLayout.mAdjustedSecondary.top
+ - splitLayout.mSecondary.top);
+ wct.setAppBounds(mSplits.mSecondary.token, adjustAppBounds);
+ wct.setScreenSizeDp(mSplits.mSecondary.token,
+ mSplits.mSecondary.configuration.screenWidthDp,
+ mSplits.mSecondary.configuration.screenHeightDp);
+
+ wct.setBounds(mSplits.mPrimary.token, splitLayout.mAdjustedPrimary);
+ adjustAppBounds = new Rect(mSplits.mPrimary.configuration
+ .windowConfiguration.getAppBounds());
+ adjustAppBounds.offset(0, splitLayout.mAdjustedPrimary.top
+ - splitLayout.mPrimary.top);
+ wct.setAppBounds(mSplits.mPrimary.token, adjustAppBounds);
+ wct.setScreenSizeDp(mSplits.mPrimary.token,
+ mSplits.mPrimary.configuration.screenWidthDp,
+ mSplits.mPrimary.configuration.screenHeightDp);
+ } else {
+ wct.setBounds(mSplits.mSecondary.token, splitLayout.mSecondary);
+ wct.setAppBounds(mSplits.mSecondary.token, null);
+ wct.setScreenSizeDp(mSplits.mSecondary.token,
+ SCREEN_WIDTH_DP_UNDEFINED, SCREEN_HEIGHT_DP_UNDEFINED);
+ wct.setBounds(mSplits.mPrimary.token, splitLayout.mPrimary);
+ wct.setAppBounds(mSplits.mPrimary.token, null);
+ wct.setScreenSizeDp(mSplits.mPrimary.token,
+ SCREEN_WIDTH_DP_UNDEFINED, SCREEN_HEIGHT_DP_UNDEFINED);
+ }
- mSplits.mDivider.getWmProxy().applySyncTransaction(wct);
+ if (!mSplits.mDivider.getWmProxy().queueSyncTransactionIfWaiting(wct)) {
+ WindowOrganizer.applyTransaction(wct);
+ }
+ }
// Update all the adjusted-for-ime states
if (!mPaused) {
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
index 2271f6de194f..6f554e698c58 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
@@ -320,8 +320,7 @@ public class DividerView extends FrameLayout implements OnTouchListener,
super.onAttachedToWindow();
// Save the current target if not minimized once attached to window
- if (mHomeStackResizable && mDockSide != WindowManager.DOCKED_INVALID
- && !mIsInMinimizeInteraction) {
+ if (mDockSide != WindowManager.DOCKED_INVALID && !mIsInMinimizeInteraction) {
saveSnapTargetBeforeMinimized(mSnapTargetBeforeMinimized);
}
mFirstLayout = true;
@@ -353,8 +352,6 @@ public class DividerView extends FrameLayout implements OnTouchListener,
minimizeLeft + mMinimizedShadow.getMeasuredWidth(),
minimizeTop + mMinimizedShadow.getMeasuredHeight());
if (changed) {
- mWindowManagerProxy.setTouchRegion(new Rect(mHandle.getLeft(), mHandle.getTop(),
- mHandle.getRight(), mHandle.getBottom()));
notifySplitScreenBoundsChanged();
}
}
@@ -470,8 +467,7 @@ public class DividerView extends FrameLayout implements OnTouchListener,
}
public DividerSnapAlgorithm getSnapAlgorithm() {
- return mDockedStackMinimized
- && mHomeStackResizable ? mSplitLayout.getMinimizedSnapAlgorithm()
+ return mDockedStackMinimized ? mSplitLayout.getMinimizedSnapAlgorithm(mHomeStackResizable)
: mSplitLayout.getSnapAlgorithm();
}
@@ -629,7 +625,7 @@ public class DividerView extends FrameLayout implements OnTouchListener,
}
// Record last snap target the divider moved to
- if (mHomeStackResizable && !mIsInMinimizeInteraction) {
+ if (!mIsInMinimizeInteraction) {
// The last snapTarget position can be negative when the last divider position was
// offscreen. In that case, save the middle (default) SnapTarget so calculating next
// position isn't negative.
@@ -681,6 +677,14 @@ public class DividerView extends FrameLayout implements OnTouchListener,
private void notifySplitScreenBoundsChanged() {
mOtherTaskRect.set(mSplitLayout.mSecondary);
+ mTmpRect.set(mHandle.getLeft(), mHandle.getTop(), mHandle.getRight(), mHandle.getBottom());
+ if (isHorizontalDivision()) {
+ mTmpRect.offsetTo(0, mDividerPositionY);
+ } else {
+ mTmpRect.offsetTo(mDividerPositionX, 0);
+ }
+ mWindowManagerProxy.setTouchRegion(mTmpRect);
+
mTmpRect.set(mSplitLayout.mDisplayLayout.stableInsets());
switch (mSplitLayout.getPrimarySplitSide()) {
case WindowManager.DOCKED_LEFT:
@@ -774,7 +778,8 @@ public class DividerView extends FrameLayout implements OnTouchListener,
mSplitLayout.resizeSplits(midPos);
Transaction t = mTiles.getTransaction();
if (mDockedStackMinimized) {
- int position = mSplitLayout.getMinimizedSnapAlgorithm().getMiddleTarget().position;
+ int position = mSplitLayout.getMinimizedSnapAlgorithm(mHomeStackResizable)
+ .getMiddleTarget().position;
calculateBoundsForPosition(position, mDockSide, mDockedRect);
calculateBoundsForPosition(position, DockedDividerUtils.invertDockSide(mDockSide),
mOtherRect);
@@ -811,23 +816,9 @@ public class DividerView extends FrameLayout implements OnTouchListener,
updateDockSide();
if (!minimized) {
resetBackground();
- } else if (!isHomeStackResizable) {
- if (mDockSide == WindowManager.DOCKED_TOP) {
- mBackground.setPivotY(0);
- mBackground.setScaleY(MINIMIZE_DOCK_SCALE);
- } else if (mDockSide == WindowManager.DOCKED_LEFT
- || mDockSide == WindowManager.DOCKED_RIGHT) {
- mBackground.setPivotX(mDockSide == WindowManager.DOCKED_LEFT
- ? 0
- : mBackground.getWidth());
- mBackground.setScaleX(MINIMIZE_DOCK_SCALE);
- }
}
mMinimizedShadow.setAlpha(minimized ? 1f : 0f);
- if (!isHomeStackResizable) {
- mHandle.setAlpha(minimized ? 0f : 1f);
- mDockedStackMinimized = minimized;
- } else if (mDockedStackMinimized != minimized) {
+ if (mDockedStackMinimized != minimized) {
mDockedStackMinimized = minimized;
if (mSplitLayout.mDisplayLayout.rotation() != mDefaultDisplay.getRotation()) {
// Splitscreen to minimize is about to starts after rotating landscape to seascape,
@@ -840,8 +831,8 @@ public class DividerView extends FrameLayout implements OnTouchListener,
// Relayout to recalculate the divider shadow when minimizing
requestLayout();
mIsInMinimizeInteraction = true;
- resizeStackSurfaces(
- mSplitLayout.getMinimizedSnapAlgorithm().getMiddleTarget(), t);
+ resizeStackSurfaces(mSplitLayout.getMinimizedSnapAlgorithm(mHomeStackResizable)
+ .getMiddleTarget(), t);
} else {
resizeStackSurfaces(mSnapTargetBeforeMinimized, t);
mIsInMinimizeInteraction = false;
@@ -860,11 +851,11 @@ public class DividerView extends FrameLayout implements OnTouchListener,
t.show(sc).apply();
mTiles.releaseTransaction(t);
});
- if (isHomeStackResizable) {
- SnapTarget miniMid = mSplitLayout.getMinimizedSnapAlgorithm().getMiddleTarget();
- if (mDockedStackMinimized) {
- mDividerPositionY = mDividerPositionX = miniMid.position;
- }
+
+ SnapTarget miniMid =
+ mSplitLayout.getMinimizedSnapAlgorithm(isHomeStackResizable).getMiddleTarget();
+ if (mDockedStackMinimized) {
+ mDividerPositionY = mDividerPositionX = miniMid.position;
}
}
@@ -903,38 +894,15 @@ public class DividerView extends FrameLayout implements OnTouchListener,
if (DEBUG) Slog.d(TAG, "setMinDock: " + mDockedStackMinimized + "->" + minimized);
mHomeStackResizable = isHomeStackResizable;
updateDockSide();
- if (!isHomeStackResizable) {
- mMinimizedShadow.animate()
- .alpha(minimized ? 1f : 0f)
- .setInterpolator(Interpolators.ALPHA_IN)
- .setDuration(animDuration)
- .start();
- mHandle.animate()
- .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
- .setDuration(animDuration)
- .alpha(minimized ? 0f : 1f)
- .start();
- if (mDockSide == WindowManager.DOCKED_TOP) {
- mBackground.setPivotY(0);
- mBackground.animate()
- .scaleY(minimized ? MINIMIZE_DOCK_SCALE : 1f);
- } else if (mDockSide == WindowManager.DOCKED_LEFT
- || mDockSide == WindowManager.DOCKED_RIGHT) {
- mBackground.setPivotX(mDockSide == WindowManager.DOCKED_LEFT
- ? 0
- : mBackground.getWidth());
- mBackground.animate()
- .scaleX(minimized ? MINIMIZE_DOCK_SCALE : 1f);
- }
- mDockedStackMinimized = minimized;
- } else if (mDockedStackMinimized != minimized) {
+ if (mDockedStackMinimized != minimized) {
mIsInMinimizeInteraction = true;
mDockedStackMinimized = minimized;
stopDragging(minimized
? mSnapTargetBeforeMinimized.position
: getCurrentPosition(),
minimized
- ? mSplitLayout.getMinimizedSnapAlgorithm().getMiddleTarget()
+ ? mSplitLayout.getMinimizedSnapAlgorithm(mHomeStackResizable)
+ .getMiddleTarget()
: mSnapTargetBeforeMinimized,
animDuration, Interpolators.FAST_OUT_SLOW_IN, 0);
setAdjustedForIme(false, animDuration);
@@ -1127,7 +1095,7 @@ public class DividerView extends FrameLayout implements OnTouchListener,
final boolean ownTransaction = transaction == null;
final Transaction t = ownTransaction ? mTiles.getTransaction() : transaction;
mLastResizeRect.set(mDockedRect);
- if (mHomeStackResizable && mIsInMinimizeInteraction) {
+ if (mIsInMinimizeInteraction) {
calculateBoundsForPosition(mSnapTargetBeforeMinimized.position, mDockSide,
mDockedTaskRect);
calculateBoundsForPosition(mSnapTargetBeforeMinimized.position,
@@ -1138,8 +1106,7 @@ public class DividerView extends FrameLayout implements OnTouchListener,
mDockedTaskRect.offset(Math.max(position, -mDividerSize)
- mDockedTaskRect.left + mDividerSize, 0);
}
- resizeSplitSurfaces(t, mDockedRect, mDockedTaskRect, mOtherRect,
- mOtherTaskRect);
+ resizeSplitSurfaces(t, mDockedRect, mDockedTaskRect, mOtherRect, mOtherTaskRect);
if (ownTransaction) {
t.apply();
mTiles.releaseTransaction(t);
@@ -1420,7 +1387,7 @@ public class DividerView extends FrameLayout implements OnTouchListener,
void onUndockingTask() {
int dockSide = mSplitLayout.getPrimarySplitSide();
- if (inSplitMode() && (mHomeStackResizable || !mDockedStackMinimized)) {
+ if (inSplitMode()) {
startDragging(false /* animate */, false /* touching */);
SnapTarget target = dockSideTopLeft(dockSide)
? mSplitLayout.getSnapAlgorithm().getDismissEndTarget()
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/SplitDisplayLayout.java b/packages/SystemUI/src/com/android/systemui/stackdivider/SplitDisplayLayout.java
index 92f6b4a2d8c4..69095f7538c5 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/SplitDisplayLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/SplitDisplayLayout.java
@@ -16,8 +16,6 @@
package com.android.systemui.stackdivider;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
import static android.view.WindowManager.DOCKED_BOTTOM;
@@ -113,11 +111,6 @@ public class SplitDisplayLayout {
}
}
- boolean isMinimized() {
- return mTiles.mSecondary.topActivityType == ACTIVITY_TYPE_HOME
- || mTiles.mSecondary.topActivityType == ACTIVITY_TYPE_RECENTS;
- }
-
DividerSnapAlgorithm getSnapAlgorithm() {
if (mSnapAlgorithm == null) {
updateResources();
@@ -129,14 +122,14 @@ public class SplitDisplayLayout {
return mSnapAlgorithm;
}
- DividerSnapAlgorithm getMinimizedSnapAlgorithm() {
+ DividerSnapAlgorithm getMinimizedSnapAlgorithm(boolean homeStackResizable) {
if (mMinimizedSnapAlgorithm == null) {
updateResources();
boolean isHorizontalDivision = !mDisplayLayout.isLandscape();
mMinimizedSnapAlgorithm = new DividerSnapAlgorithm(mContext.getResources(),
mDisplayLayout.width(), mDisplayLayout.height(), mDividerSize,
isHorizontalDivision, mDisplayLayout.stableInsets(), getPrimarySplitSide(),
- true /* isMinimized */);
+ true /* isMinimized */, homeStackResizable);
}
return mMinimizedSnapAlgorithm;
}
@@ -168,8 +161,9 @@ public class SplitDisplayLayout {
mDisplayLayout.height(), mDividerSize);
}
- Rect calcMinimizedHomeStackBounds() {
- DividerSnapAlgorithm.SnapTarget miniMid = getMinimizedSnapAlgorithm().getMiddleTarget();
+ Rect calcResizableMinimizedHomeStackBounds() {
+ DividerSnapAlgorithm.SnapTarget miniMid =
+ getMinimizedSnapAlgorithm(true /* resizable */).getMiddleTarget();
Rect homeBounds = new Rect();
DockedDividerUtils.calculateBoundsForPosition(miniMid.position,
DockedDividerUtils.invertDockSide(getPrimarySplitSide()), homeBounds,
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java b/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java
index 44674df3b865..4a2cad705c17 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java
@@ -163,8 +163,9 @@ class SplitScreenTaskOrganizer extends TaskOrganizer {
Log.e(TAG, "Got handleTaskInfoChanged when not initialized: " + info);
return;
}
- final boolean secondaryWasHomeOrRecents = mSecondary.topActivityType == ACTIVITY_TYPE_HOME
- || mSecondary.topActivityType == ACTIVITY_TYPE_RECENTS;
+ final boolean secondaryImpliedMinimize = mSecondary.topActivityType == ACTIVITY_TYPE_HOME
+ || (mSecondary.topActivityType == ACTIVITY_TYPE_RECENTS
+ && mDivider.isHomeStackResizable());
final boolean primaryWasEmpty = mPrimary.topActivityType == ACTIVITY_TYPE_UNDEFINED;
final boolean secondaryWasEmpty = mSecondary.topActivityType == ACTIVITY_TYPE_UNDEFINED;
if (info.token.asBinder() == mPrimary.token.asBinder()) {
@@ -174,13 +175,14 @@ class SplitScreenTaskOrganizer extends TaskOrganizer {
}
final boolean primaryIsEmpty = mPrimary.topActivityType == ACTIVITY_TYPE_UNDEFINED;
final boolean secondaryIsEmpty = mSecondary.topActivityType == ACTIVITY_TYPE_UNDEFINED;
- final boolean secondaryIsHomeOrRecents = mSecondary.topActivityType == ACTIVITY_TYPE_HOME
- || mSecondary.topActivityType == ACTIVITY_TYPE_RECENTS;
+ final boolean secondaryImpliesMinimize = mSecondary.topActivityType == ACTIVITY_TYPE_HOME
+ || (mSecondary.topActivityType == ACTIVITY_TYPE_RECENTS
+ && mDivider.isHomeStackResizable());
if (DEBUG) {
Log.d(TAG, "onTaskInfoChanged " + mPrimary + " " + mSecondary);
}
if (primaryIsEmpty == primaryWasEmpty && secondaryWasEmpty == secondaryIsEmpty
- && secondaryWasHomeOrRecents == secondaryIsHomeOrRecents) {
+ && secondaryImpliedMinimize == secondaryImpliesMinimize) {
// No relevant changes
return;
}
@@ -209,7 +211,7 @@ class SplitScreenTaskOrganizer extends TaskOrganizer {
}
mDivider.startEnterSplit();
}
- } else if (secondaryIsHomeOrRecents) {
+ } else if (secondaryImpliesMinimize) {
// Both splits are populated but the secondary split has a home/recents stack on top,
// so enter minimized mode.
mDivider.ensureMinimizedSplit();
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java b/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java
index 853a22505542..410e3dd39a0b 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java
@@ -19,6 +19,9 @@ package com.android.systemui.stackdivider;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
+import static android.content.res.Configuration.ORIENTATION_UNDEFINED;
import static android.view.Display.DEFAULT_DISPLAY;
import android.annotation.NonNull;
@@ -115,7 +118,7 @@ public class WindowManagerProxy {
WindowOrganizer.applyTransaction(t);
}
- private static boolean getHomeAndRecentsTasks(List<WindowContainerToken> out,
+ private static boolean getHomeAndRecentsTasks(List<ActivityManager.RunningTaskInfo> out,
WindowContainerToken parent) {
boolean resizable = false;
List<ActivityManager.RunningTaskInfo> rootTasks = parent == null
@@ -123,9 +126,9 @@ public class WindowManagerProxy {
: TaskOrganizer.getChildTasks(parent, HOME_AND_RECENTS);
for (int i = 0, n = rootTasks.size(); i < n; ++i) {
final ActivityManager.RunningTaskInfo ti = rootTasks.get(i);
- out.add(ti.token);
+ out.add(ti);
if (ti.topActivityType == ACTIVITY_TYPE_HOME) {
- resizable = ti.isResizable();
+ resizable = ti.isResizeable;
}
}
return resizable;
@@ -140,16 +143,37 @@ public class WindowManagerProxy {
@NonNull WindowContainerTransaction wct) {
// Resize the home/recents stacks to the larger minimized-state size
final Rect homeBounds;
- final ArrayList<WindowContainerToken> homeStacks = new ArrayList<>();
+ final ArrayList<ActivityManager.RunningTaskInfo> homeStacks = new ArrayList<>();
boolean isHomeResizable = getHomeAndRecentsTasks(homeStacks, parent);
if (isHomeResizable) {
- homeBounds = layout.calcMinimizedHomeStackBounds();
+ homeBounds = layout.calcResizableMinimizedHomeStackBounds();
} else {
- homeBounds = new Rect(0, 0, layout.mDisplayLayout.width(),
- layout.mDisplayLayout.height());
+ // home is not resizable, so lock it to its inherent orientation size.
+ homeBounds = new Rect(0, 0, 0, 0);
+ for (int i = homeStacks.size() - 1; i >= 0; --i) {
+ if (homeStacks.get(i).topActivityType == ACTIVITY_TYPE_HOME) {
+ final int orient = homeStacks.get(i).configuration.orientation;
+ final boolean displayLandscape = layout.mDisplayLayout.isLandscape();
+ final boolean isLandscape = orient == ORIENTATION_LANDSCAPE
+ || (orient == ORIENTATION_UNDEFINED && displayLandscape);
+ homeBounds.right = isLandscape == displayLandscape
+ ? layout.mDisplayLayout.width() : layout.mDisplayLayout.height();
+ homeBounds.bottom = isLandscape == displayLandscape
+ ? layout.mDisplayLayout.height() : layout.mDisplayLayout.width();
+ break;
+ }
+ }
}
for (int i = homeStacks.size() - 1; i >= 0; --i) {
- wct.setBounds(homeStacks.get(i), homeBounds);
+ // For non-resizable homes, the minimized size is actually the fullscreen-size. As a
+ // result, we don't minimize for recents since it only shows half-size screenshots.
+ if (!isHomeResizable) {
+ if (homeStacks.get(i).topActivityType == ACTIVITY_TYPE_RECENTS) {
+ continue;
+ }
+ wct.setWindowingMode(homeStacks.get(i).token, WINDOWING_MODE_FULLSCREEN);
+ }
+ wct.setBounds(homeStacks.get(i).token, homeBounds);
}
layout.mTiles.mHomeBounds.set(homeBounds);
return isHomeResizable;
@@ -175,11 +199,13 @@ public class WindowManagerProxy {
return false;
}
ActivityManager.RunningTaskInfo topHomeTask = null;
- boolean homeIsTop = false;
for (int i = rootTasks.size() - 1; i >= 0; --i) {
final ActivityManager.RunningTaskInfo rootTask = rootTasks.get(i);
- // Only move resizeable task to split secondary. WM will just ignore this anyways...
- if (!rootTask.isResizable()) continue;
+ // Only move resizeable task to split secondary. However, we have an exception
+ // for non-resizable home because we will minimize to show it.
+ if (!rootTask.isResizeable && rootTask.topActivityType != ACTIVITY_TYPE_HOME) {
+ continue;
+ }
// Only move fullscreen tasks to split secondary.
if (rootTask.configuration.windowConfiguration.getWindowingMode()
!= WINDOWING_MODE_FULLSCREEN) {
@@ -193,7 +219,7 @@ public class WindowManagerProxy {
// Move the secondary split-forward.
wct.reorder(tiles.mSecondary.token, true /* onTop */);
boolean isHomeResizable = applyHomeTasksMinimized(layout, null /* parent */, wct);
- if (isHomeResizable && topHomeTask != null) {
+ if (topHomeTask != null) {
// Translate/update-crop of secondary out-of-band with sync transaction -- Until BALST
// is enabled, this temporarily syncs the home surface position with offset until
// sync transaction finishes.
@@ -253,6 +279,7 @@ public class WindowManagerProxy {
wct.reparent(ti.token, null /* parent */, true /* onTop */);
if (isHomeOrRecentTask(ti)) {
wct.setBounds(ti.token, null);
+ wct.setWindowingMode(ti.token, WINDOWING_MODE_UNDEFINED);
if (i == 0) {
homeOnTop = true;
}
@@ -293,8 +320,9 @@ public class WindowManagerProxy {
final ActivityManager.RunningTaskInfo ti = secondaryChildren.get(i);
if (isHomeOrRecentTask(ti)) {
wct.reparent(ti.token, null /* parent */, true /* onTop */);
- // reset bounds too
+ // reset bounds and mode too
wct.setBounds(ti.token, null);
+ wct.setWindowingMode(ti.token, WINDOWING_MODE_UNDEFINED);
}
}
for (int i = primaryChildren.size() - 1; i >= 0; --i) {
@@ -304,6 +332,7 @@ public class WindowManagerProxy {
}
for (int i = freeHomeAndRecents.size() - 1; i >= 0; --i) {
wct.setBounds(freeHomeAndRecents.get(i).token, null);
+ wct.setWindowingMode(freeHomeAndRecents.get(i).token, WINDOWING_MODE_UNDEFINED);
}
// Reset focusable to true
wct.setFocusable(tiles.mPrimary.token, true /* focusable */);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index 43b47232d27d..a1444532bd5e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -16,9 +16,16 @@
package com.android.systemui.statusbar;
+import static com.android.systemui.DejankUtils.whitelistIpcs;
+
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
+import android.app.admin.DevicePolicyManager;
+import android.content.BroadcastReceiver;
import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.UserInfo;
import android.content.res.ColorStateList;
import android.graphics.Color;
import android.hardware.biometrics.BiometricSourceType;
@@ -28,12 +35,16 @@ import android.os.BatteryManager;
import android.os.Handler;
import android.os.Message;
import android.os.RemoteException;
+import android.os.UserHandle;
+import android.os.UserManager;
import android.text.TextUtils;
import android.text.format.Formatter;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
+import androidx.annotation.Nullable;
+
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.IBatteryStats;
import com.android.internal.widget.ViewClippingUtil;
@@ -43,6 +54,7 @@ import com.android.settingslib.Utils;
import com.android.settingslib.fuelgauge.BatteryStatus;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dock.DockManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
@@ -78,15 +90,20 @@ public class KeyguardIndicationController implements StateListener,
private static final float BOUNCE_ANIMATION_FINAL_Y = 0f;
private final Context mContext;
+ private final BroadcastDispatcher mBroadcastDispatcher;
private final KeyguardStateController mKeyguardStateController;
private final StatusBarStateController mStatusBarStateController;
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
private ViewGroup mIndicationArea;
private KeyguardIndicationTextView mTextView;
+ private KeyguardIndicationTextView mDisclosure;
private final IBatteryStats mBatteryInfo;
private final SettableWakeLock mWakeLock;
private final DockManager mDockManager;
+ private final DevicePolicyManager mDevicePolicyManager;
+ private final UserManager mUserManager;
+ private BroadcastReceiver mBroadcastReceiver;
private LockscreenLockIconController mLockIconController;
private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
@@ -105,6 +122,7 @@ public class KeyguardIndicationController implements StateListener,
private int mChargingWattage;
private int mBatteryLevel;
private long mChargingTimeRemaining;
+ private float mDisclosureMaxAlpha;
private String mMessageToShowOnScreenOn;
private KeyguardUpdateMonitorCallback mUpdateMonitorCallback;
@@ -128,8 +146,13 @@ public class KeyguardIndicationController implements StateListener,
StatusBarStateController statusBarStateController,
KeyguardUpdateMonitor keyguardUpdateMonitor,
DockManager dockManager,
- IBatteryStats iBatteryStats) {
+ BroadcastDispatcher broadcastDispatcher,
+ DevicePolicyManager devicePolicyManager,
+ IBatteryStats iBatteryStats,
+ UserManager userManager) {
mContext = context;
+ mBroadcastDispatcher = broadcastDispatcher;
+ mDevicePolicyManager = devicePolicyManager;
mKeyguardStateController = keyguardStateController;
mStatusBarStateController = statusBarStateController;
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
@@ -139,6 +162,7 @@ public class KeyguardIndicationController implements StateListener,
mWakeLock = new SettableWakeLock(
wakeLockBuilder.setTag("Doze:KeyguardIndication").build(), TAG);
mBatteryInfo = iBatteryStats;
+ mUserManager = userManager;
mKeyguardUpdateMonitor.registerCallback(getKeyguardCallback());
mKeyguardUpdateMonitor.registerCallback(mTickReceiver);
@@ -151,7 +175,24 @@ public class KeyguardIndicationController implements StateListener,
mTextView = indicationArea.findViewById(R.id.keyguard_indication_text);
mInitialTextColorState = mTextView != null ?
mTextView.getTextColors() : ColorStateList.valueOf(Color.WHITE);
+ mDisclosure = indicationArea.findViewById(R.id.keyguard_indication_enterprise_disclosure);
+ mDisclosureMaxAlpha = mDisclosure.getAlpha();
updateIndication(false /* animate */);
+ updateDisclosure();
+
+ if (mBroadcastReceiver == null) {
+ // Update the disclosure proactively to avoid IPC on the critical path.
+ mBroadcastReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ updateDisclosure();
+ }
+ };
+ IntentFilter intentFilter = new IntentFilter();
+ intentFilter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
+ intentFilter.addAction(Intent.ACTION_USER_REMOVED);
+ mBroadcastDispatcher.registerReceiver(mBroadcastReceiver, intentFilter);
+ }
}
public void setLockIconController(LockscreenLockIconController lockIconController) {
@@ -190,6 +231,54 @@ public class KeyguardIndicationController implements StateListener,
return mUpdateMonitorCallback;
}
+ private void updateDisclosure() {
+ // NOTE: Because this uses IPC, avoid calling updateDisclosure() on a critical path.
+ if (whitelistIpcs(this::isOrganizationOwnedDevice)) {
+ CharSequence organizationName = getOrganizationOwnedDeviceOrganizationName();
+ if (organizationName != null) {
+ mDisclosure.switchIndication(mContext.getResources().getString(
+ R.string.do_disclosure_with_name, organizationName));
+ } else {
+ mDisclosure.switchIndication(R.string.do_disclosure_generic);
+ }
+ mDisclosure.setVisibility(View.VISIBLE);
+ } else {
+ mDisclosure.setVisibility(View.GONE);
+ }
+ }
+
+ private boolean isOrganizationOwnedDevice() {
+ return mDevicePolicyManager.isDeviceManaged()
+ || mDevicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile();
+ }
+
+ @Nullable
+ private CharSequence getOrganizationOwnedDeviceOrganizationName() {
+ if (mDevicePolicyManager.isDeviceManaged()) {
+ return mDevicePolicyManager.getDeviceOwnerOrganizationName();
+ } else if (mDevicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile()) {
+ return getWorkProfileOrganizationName();
+ }
+ return null;
+ }
+
+ private CharSequence getWorkProfileOrganizationName() {
+ final int profileId = getWorkProfileUserId(UserHandle.myUserId());
+ if (profileId == UserHandle.USER_NULL) {
+ return null;
+ }
+ return mDevicePolicyManager.getOrganizationNameForUser(profileId);
+ }
+
+ private int getWorkProfileUserId(int userId) {
+ for (final UserInfo userInfo : mUserManager.getProfiles(userId)) {
+ if (userInfo.isManagedProfile()) {
+ return userInfo.id;
+ }
+ }
+ return UserHandle.USER_NULL;
+ }
+
public void setVisible(boolean visible) {
mVisible = visible;
mIndicationArea.setVisibility(visible ? View.VISIBLE : View.GONE);
@@ -574,6 +663,11 @@ public class KeyguardIndicationController implements StateListener,
}
@Override
+ public void onDozeAmountChanged(float linear, float eased) {
+ mDisclosure.setAlpha((1 - linear) * mDisclosureMaxAlpha);
+ }
+
+ @Override
public void onUnlockedChanged() {
updateIndication(!mDozing);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt b/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt
index 6d2cc6b08bc4..7b2585324b9f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt
@@ -27,7 +27,6 @@ import android.os.SystemClock
import android.view.MotionEvent
import android.view.VelocityTracker
import android.view.ViewConfiguration
-
import com.android.systemui.Gefingerpoken
import com.android.systemui.Interpolators
import com.android.systemui.R
@@ -41,7 +40,6 @@ import com.android.systemui.statusbar.notification.stack.NotificationStackScroll
import com.android.systemui.statusbar.phone.HeadsUpManagerPhone
import com.android.systemui.statusbar.phone.KeyguardBypassController
import com.android.systemui.statusbar.phone.ShadeController
-
import javax.inject.Inject
import javax.inject.Singleton
import kotlin.math.max
@@ -162,10 +160,12 @@ constructor(
MotionEvent.ACTION_UP -> {
recycleVelocityTracker()
+ isExpanding = false
}
MotionEvent.ACTION_CANCEL -> {
recycleVelocityTracker()
+ isExpanding = false
}
}
return false
@@ -181,7 +181,8 @@ constructor(
return false
}
- if (!isExpanding || event.actionMasked == MotionEvent.ACTION_DOWN) {
+ if (velocityTracker == null || !isExpanding ||
+ event.actionMasked == MotionEvent.ACTION_DOWN) {
return startExpansion(event)
}
velocityTracker!!.addMovement(event)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java
index 6a3302473e63..382715a3fb77 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java
@@ -293,7 +293,7 @@ public class ActivityLaunchAnimator {
.withCornerRadius(mCornerRadius)
.withVisibility(true)
.build();
- mSyncRtTransactionApplier.scheduleApply(true /* earlyWakeup */, params);
+ mSyncRtTransactionApplier.scheduleApply(params);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/MessagingLayoutTransformState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/MessagingLayoutTransformState.java
index 5ee4693a32bf..e0532c3e2b28 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/MessagingLayoutTransformState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/MessagingLayoutTransformState.java
@@ -17,9 +17,11 @@
package com.android.systemui.statusbar.notification;
import android.content.res.Resources;
+import android.text.Layout;
import android.util.Pools;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.TextView;
import com.android.internal.widget.IMessagingLayout;
import com.android.internal.widget.MessagingGroup;
@@ -229,6 +231,15 @@ public class MessagingLayoutTransformState extends TransformState {
return result;
}
+ private boolean hasEllipses(TextView textView) {
+ Layout layout = textView.getLayout();
+ return layout != null && layout.getEllipsisCount(layout.getLineCount() - 1) > 0;
+ }
+
+ private boolean needsReflow(TextView own, TextView other) {
+ return hasEllipses(own) != hasEllipses(other);
+ }
+
/**
* Transform two groups towards each other.
*
@@ -238,13 +249,20 @@ public class MessagingLayoutTransformState extends TransformState {
float transformationAmount, boolean to) {
boolean useLinearTransformation =
otherGroup.getIsolatedMessage() == null && !mTransformInfo.isAnimating();
- transformView(transformationAmount, to, ownGroup.getSenderView(), otherGroup.getSenderView(),
- true /* sameAsAny */, useLinearTransformation);
+ TextView ownSenderView = ownGroup.getSenderView();
+ TextView otherSenderView = otherGroup.getSenderView();
+ transformView(transformationAmount, to, ownSenderView, otherSenderView,
+ // Normally this would be handled by the TextViewMessageState#sameAs check, but in
+ // this case it doesn't work because our text won't match, due to the appended colon
+ // in the collapsed view.
+ !needsReflow(ownSenderView, otherSenderView),
+ useLinearTransformation);
int totalAvatarTranslation = transformView(transformationAmount, to, ownGroup.getAvatar(),
otherGroup.getAvatar(), true /* sameAsAny */, useLinearTransformation);
List<MessagingMessage> ownMessages = ownGroup.getMessages();
List<MessagingMessage> otherMessages = otherGroup.getMessages();
float previousTranslation = 0;
+ boolean isLastView = true;
for (int i = 0; i < ownMessages.size(); i++) {
View child = ownMessages.get(ownMessages.size() - 1 - i).getView();
if (isGone(child)) {
@@ -278,6 +296,9 @@ public class MessagingLayoutTransformState extends TransformState {
mMessagingLayout.setMessagingClippingDisabled(true);
}
if (otherChild == null) {
+ if (isLastView) {
+ previousTranslation = ownSenderView.getTranslationY();
+ }
child.setTranslationY(previousTranslation);
setClippingDeactivated(child, true);
} else if (ownGroup.getIsolatedMessage() == child || otherIsIsolated) {
@@ -287,6 +308,7 @@ public class MessagingLayoutTransformState extends TransformState {
} else {
previousTranslation = child.getTranslationY();
}
+ isLastView = false;
}
ownGroup.updateClipRect();
return totalAvatarTranslation;
@@ -382,6 +404,9 @@ public class MessagingLayoutTransformState extends TransformState {
if (view.getParent() == null) {
return true;
}
+ if (view.getWidth() == 0) {
+ return true;
+ }
final ViewGroup.LayoutParams lp = view.getLayoutParams();
if (lp instanceof MessagingLinearLayout.LayoutParams
&& ((MessagingLinearLayout.LayoutParams) lp).hide) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
index 33771449abc9..423f85f2ddd0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
@@ -178,6 +178,7 @@ public final class NotificationEntry extends ListEntry {
private int mBucket = BUCKET_ALERTING;
@Nullable private Long mPendingAnimationDuration;
private boolean mIsMarkedForUserTriggeredMovement;
+ private boolean mShelfIconVisible;
/**
* @param sbn the StatusBarNotification from system server
@@ -431,6 +432,7 @@ public final class NotificationEntry extends ListEntry {
//TODO: This will go away when we have a way to bind an entry to a row
public void setRow(ExpandableNotificationRow row) {
this.row = row;
+ updateShelfIconVisibility();
}
public ExpandableNotificationRowController getRowController() {
@@ -951,6 +953,18 @@ public final class NotificationEntry extends ListEntry {
return mIsMarkedForUserTriggeredMovement;
}
+ /** Whether or not the icon for this notification is visible in the shelf. */
+ public void setShelfIconVisible(boolean shelfIconVisible) {
+ mShelfIconVisible = shelfIconVisible;
+ updateShelfIconVisibility();
+ }
+
+ private void updateShelfIconVisibility() {
+ if (row != null) {
+ row.setShelfIconVisible(mShelfIconVisible);
+ }
+ }
+
/**
* Mark this entry for movement triggered by a user action (ex: changing the priorirty of a
* conversation). This can then be used for custom animations.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ForegroundCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/AppOpsCoordinator.java
index b5b756d6ed9b..4b244bb18975 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ForegroundCoordinator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/AppOpsCoordinator.java
@@ -39,8 +39,8 @@ import javax.inject.Inject;
import javax.inject.Singleton;
/**
- * Handles ForegroundService interactions with notifications.
- * Tags notifications with appOps.
+ * Handles ForegroundService and AppOp interactions with notifications.
+ * Tags notifications with appOps
* Lifetime extends notifications associated with an ongoing ForegroundService.
* Filters out notifications that represent foreground services that are no longer running
*
@@ -48,12 +48,10 @@ import javax.inject.Singleton;
* frameworks/base/packages/SystemUI/src/com/android/systemui/ForegroundServiceController
* frameworks/base/packages/SystemUI/src/com/android/systemui/ForegroundServiceNotificationListener
* frameworks/base/packages/SystemUI/src/com/android/systemui/ForegroundServiceLifetimeExtender
- *
- * TODO: AppOps stuff should be spun off into its own coordinator
*/
@Singleton
-public class ForegroundCoordinator implements Coordinator {
- private static final String TAG = "ForegroundCoordinator";
+public class AppOpsCoordinator implements Coordinator {
+ private static final String TAG = "AppOpsCoordinator";
private final ForegroundServiceController mForegroundServiceController;
private final AppOpsController mAppOpsController;
@@ -62,7 +60,7 @@ public class ForegroundCoordinator implements Coordinator {
private NotifPipeline mNotifPipeline;
@Inject
- public ForegroundCoordinator(
+ public AppOpsCoordinator(
ForegroundServiceController foregroundServiceController,
AppOpsController appOpsController,
@Main DelayableExecutor mainExecutor) {
@@ -89,18 +87,22 @@ public class ForegroundCoordinator implements Coordinator {
}
/**
- * Filters out notifications that represent foreground services that are no longer running.
+ * Filters out notifications that represent foreground services that are no longer running or
+ * that already have an app notification with the appOps tagged to
*/
private final NotifFilter mNotifFilter = new NotifFilter(TAG) {
@Override
public boolean shouldFilterOut(NotificationEntry entry, long now) {
StatusBarNotification sbn = entry.getSbn();
+
+ // Filters out system-posted disclosure notifications when unneeded
if (mForegroundServiceController.isDisclosureNotification(sbn)
&& !mForegroundServiceController.isDisclosureNeededForUser(
sbn.getUser().getIdentifier())) {
return true;
}
+ // Filters out system alert notifications when unneeded
if (mForegroundServiceController.isSystemAlertNotification(sbn)) {
final String[] apps = sbn.getNotification().extras.getStringArray(
Notification.EXTRA_FOREGROUND_APPS);
@@ -179,23 +181,24 @@ public class ForegroundCoordinator implements Coordinator {
private NotifCollectionListener mNotifCollectionListener = new NotifCollectionListener() {
@Override
public void onEntryAdded(NotificationEntry entry) {
- tagForeground(entry);
+ tagAppOps(entry);
}
@Override
public void onEntryUpdated(NotificationEntry entry) {
- tagForeground(entry);
+ tagAppOps(entry);
}
- private void tagForeground(NotificationEntry entry) {
+ private void tagAppOps(NotificationEntry entry) {
final StatusBarNotification sbn = entry.getSbn();
// note: requires that the ForegroundServiceController is updating their appOps first
ArraySet<Integer> activeOps =
mForegroundServiceController.getAppOps(
sbn.getUser().getIdentifier(),
sbn.getPackageName());
+
+ entry.mActiveAppOps.clear();
if (activeOps != null) {
- entry.mActiveAppOps.clear();
entry.mActiveAppOps.addAll(activeOps);
}
}
@@ -218,24 +221,26 @@ public class ForegroundCoordinator implements Coordinator {
int userId = UserHandle.getUserId(uid);
- // Update appOp if there's an associated posted notification:
- final String foregroundKey = mForegroundServiceController.getStandardLayoutKey(userId,
- packageName);
- if (foregroundKey != null) {
- final NotificationEntry entry = findNotificationEntryWithKey(foregroundKey);
- if (entry != null
- && uid == entry.getSbn().getUid()
- && packageName.equals(entry.getSbn().getPackageName())) {
- boolean changed;
- if (active) {
- changed = entry.mActiveAppOps.add(code);
- } else {
- changed = entry.mActiveAppOps.remove(code);
- }
- if (changed) {
- mNotifFilter.invalidateList();
+ // Update appOps of the app's posted notifications with standard layouts
+ final ArraySet<String> notifKeys =
+ mForegroundServiceController.getStandardLayoutKeys(userId, packageName);
+ if (notifKeys != null) {
+ boolean changed = false;
+ for (int i = 0; i < notifKeys.size(); i++) {
+ final NotificationEntry entry = findNotificationEntryWithKey(notifKeys.valueAt(i));
+ if (entry != null
+ && uid == entry.getSbn().getUid()
+ && packageName.equals(entry.getSbn().getPackageName())) {
+ if (active) {
+ changed |= entry.mActiveAppOps.add(code);
+ } else {
+ changed |= entry.mActiveAppOps.remove(code);
+ }
}
}
+ if (changed) {
+ mNotifFilter.invalidateList();
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HideNotifsForOtherUsersCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HideNotifsForOtherUsersCoordinator.java
index 261ae079a2c8..e595dd4a2f71 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HideNotifsForOtherUsersCoordinator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HideNotifsForOtherUsersCoordinator.java
@@ -39,11 +39,14 @@ import javax.inject.Inject;
*/
public class HideNotifsForOtherUsersCoordinator implements Coordinator {
private final NotificationLockscreenUserManager mLockscreenUserManager;
+ private final SharedCoordinatorLogger mLogger;
@Inject
public HideNotifsForOtherUsersCoordinator(
- NotificationLockscreenUserManager lockscreenUserManager) {
+ NotificationLockscreenUserManager lockscreenUserManager,
+ SharedCoordinatorLogger logger) {
mLockscreenUserManager = lockscreenUserManager;
+ mLogger = logger;
}
@Override
@@ -61,9 +64,27 @@ public class HideNotifsForOtherUsersCoordinator implements Coordinator {
};
private final UserChangedListener mUserChangedListener = new UserChangedListener() {
+ // This listener is fired both when the list of profiles changes and when the current user
+ // changes
@Override
public void onCurrentProfilesChanged(SparseArray<UserInfo> currentProfiles) {
+ mLogger.logUserOrProfileChanged(
+ mLockscreenUserManager.getCurrentUserId(),
+ profileIdsToStr(currentProfiles));
mFilter.invalidateList();
}
};
+
+ private String profileIdsToStr(SparseArray<UserInfo> currentProfiles) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("{");
+ for (int i = 0; i < currentProfiles.size(); i++) {
+ sb.append(currentProfiles.keyAt(i));
+ if (i < currentProfiles.size() - 1) {
+ sb.append(",");
+ }
+ }
+ sb.append("}");
+ return sb.toString();
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.java
index ac4296439507..99e822c66a8f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.java
@@ -52,7 +52,7 @@ public class NotifCoordinators implements Dumpable {
HideNotifsForOtherUsersCoordinator hideNotifsForOtherUsersCoordinator,
KeyguardCoordinator keyguardCoordinator,
RankingCoordinator rankingCoordinator,
- ForegroundCoordinator foregroundCoordinator,
+ AppOpsCoordinator appOpsCoordinator,
DeviceProvisionedCoordinator deviceProvisionedCoordinator,
BubbleCoordinator bubbleCoordinator,
HeadsUpCoordinator headsUpCoordinator,
@@ -64,7 +64,7 @@ public class NotifCoordinators implements Dumpable {
mCoordinators.add(hideNotifsForOtherUsersCoordinator);
mCoordinators.add(keyguardCoordinator);
mCoordinators.add(rankingCoordinator);
- mCoordinators.add(foregroundCoordinator);
+ mCoordinators.add(appOpsCoordinator);
mCoordinators.add(deviceProvisionedCoordinator);
mCoordinators.add(bubbleCoordinator);
if (featureFlags.isNewNotifPipelineRenderingEnabled()) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/SharedCoordinatorLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/SharedCoordinatorLogger.kt
new file mode 100644
index 000000000000..c85fc1efee95
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/SharedCoordinatorLogger.kt
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.collection.coordinator
+
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.LogLevel
+import com.android.systemui.log.dagger.NotificationLog
+import javax.inject.Inject
+
+/**
+ * Shared logging class for coordinators that don't log enough to merit their own logger.
+ */
+class SharedCoordinatorLogger @Inject constructor(
+ @NotificationLog private val buffer: LogBuffer
+) {
+ fun logUserOrProfileChanged(userId: Int, profiles: String) {
+ buffer.log("NotCurrentUserFilter", LogLevel.INFO, {
+ int1 = userId
+ str1 = profiles
+ }, {
+ "Current user or profiles changed. Current user is $int1; profiles are $str1"
+ })
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
index 033a638bdd73..df1de63b65a0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
@@ -24,7 +24,9 @@ import android.os.Handler;
import android.view.accessibility.AccessibilityManager;
import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.UiEventLogger;
import com.android.systemui.R;
+import com.android.systemui.bubbles.BubbleController;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dagger.qualifiers.UiBackground;
@@ -114,7 +116,9 @@ public interface NotificationsModule {
ShortcutManager shortcutManager,
ChannelEditorDialogController channelEditorDialogController,
CurrentUserContextTracker contextTracker,
- Provider<PriorityOnboardingDialogController.Builder> builderProvider) {
+ Provider<PriorityOnboardingDialogController.Builder> builderProvider,
+ BubbleController bubbleController,
+ UiEventLogger uiEventLogger) {
return new NotificationGutsManager(
context,
visualStabilityManager,
@@ -128,7 +132,9 @@ public interface NotificationsModule {
shortcutManager,
channelEditorDialogController,
contextTracker,
- builderProvider);
+ builderProvider,
+ bubbleController,
+ uiEventLogger);
}
/** Provides an instance of {@link VisualStabilityManager} */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconManager.kt
index 011ad19b41db..13f7a53f5e54 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconManager.kt
@@ -96,13 +96,11 @@ class IconManager @Inject constructor(
val shelfIcon = iconBuilder.createIconView(entry)
shelfIcon.scaleType = ImageView.ScaleType.CENTER_INSIDE
- shelfIcon.visibility = View.INVISIBLE
// TODO: This doesn't belong here
shelfIcon.setOnVisibilityChangedListener { newVisibility: Int ->
- if (entry.row != null) {
- entry.row.setShelfIconVisible(newVisibility == View.VISIBLE)
- }
+ entry.setShelfIconVisible(newVisibility == View.VISIBLE)
}
+ shelfIcon.visibility = View.INVISIBLE
// Construct the aod icon view.
val aodIcon = iconBuilder.createIconView(entry)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java
index ad047889f29f..bd0d0b31e4dc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java
@@ -29,6 +29,7 @@ import android.util.Log;
import androidx.annotation.Nullable;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.statusbar.NotificationVisibility;
@@ -36,6 +37,7 @@ import com.android.systemui.dagger.qualifiers.UiBackground;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
import com.android.systemui.statusbar.NotificationListener;
+import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.notification.NotificationEntryListener;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -58,6 +60,7 @@ import javax.inject.Inject;
*/
public class NotificationLogger implements StateListener {
private static final String TAG = "NotificationLogger";
+ private static final boolean DEBUG = false;
/** The minimum delay in ms between reports of notification visibility. */
private static final int VISIBILITY_REPORT_MIN_DELAY_MS = 500;
@@ -79,7 +82,12 @@ public class NotificationLogger implements StateListener {
private long mLastVisibilityReportUptimeMs;
private NotificationListContainer mListContainer;
private final Object mDozingLock = new Object();
- private boolean mDozing;
+ @GuardedBy("mDozingLock")
+ private Boolean mDozing = null; // Use null to indicate state is not yet known
+ @GuardedBy("mDozingLock")
+ private Boolean mLockscreen = null; // Use null to indicate state is not yet known
+ private Boolean mPanelExpanded = null; // Use null to indicate state is not yet known
+ private boolean mLogging = false;
protected final OnChildLocationsChangedListener mNotificationLocationsChangedListener =
new OnChildLocationsChangedListener() {
@@ -247,33 +255,44 @@ public class NotificationLogger implements StateListener {
}
public void stopNotificationLogging() {
- // Report all notifications as invisible and turn down the
- // reporter.
- if (!mCurrentlyVisibleNotifications.isEmpty()) {
- logNotificationVisibilityChanges(
- Collections.emptyList(), mCurrentlyVisibleNotifications);
- recycleAllVisibilityObjects(mCurrentlyVisibleNotifications);
+ if (mLogging) {
+ mLogging = false;
+ if (DEBUG) {
+ Log.i(TAG, "stopNotificationLogging: log notifications invisible");
+ }
+ // Report all notifications as invisible and turn down the
+ // reporter.
+ if (!mCurrentlyVisibleNotifications.isEmpty()) {
+ logNotificationVisibilityChanges(
+ Collections.emptyList(), mCurrentlyVisibleNotifications);
+ recycleAllVisibilityObjects(mCurrentlyVisibleNotifications);
+ }
+ mHandler.removeCallbacks(mVisibilityReporter);
+ mListContainer.setChildLocationsChangedListener(null);
}
- mHandler.removeCallbacks(mVisibilityReporter);
- mListContainer.setChildLocationsChangedListener(null);
}
public void startNotificationLogging() {
- mListContainer.setChildLocationsChangedListener(mNotificationLocationsChangedListener);
- // Some transitions like mVisibleToUser=false -> mVisibleToUser=true don't
- // cause the scroller to emit child location events. Hence generate
- // one ourselves to guarantee that we're reporting visible
- // notifications.
- // (Note that in cases where the scroller does emit events, this
- // additional event doesn't break anything.)
- mNotificationLocationsChangedListener.onChildLocationsChanged();
- mNotificationPanelLogger.logPanelShown(mListContainer.hasPulsingNotifications(),
- mEntryManager.getVisibleNotifications());
+ if (!mLogging) {
+ mLogging = true;
+ if (DEBUG) {
+ Log.i(TAG, "startNotificationLogging");
+ }
+ mListContainer.setChildLocationsChangedListener(mNotificationLocationsChangedListener);
+ // Some transitions like mVisibleToUser=false -> mVisibleToUser=true don't
+ // cause the scroller to emit child location events. Hence generate
+ // one ourselves to guarantee that we're reporting visible
+ // notifications.
+ // (Note that in cases where the scroller does emit events, this
+ // additional event doesn't break anything.)
+ mNotificationLocationsChangedListener.onChildLocationsChanged();
+ }
}
private void setDozing(boolean dozing) {
synchronized (mDozingLock) {
mDozing = dozing;
+ maybeUpdateLoggingStatus();
}
}
@@ -343,19 +362,12 @@ public class NotificationLogger implements StateListener {
for (int i = 0; i < N; i++) {
newlyVisibleKeyAr[i] = newlyVisibleAr[i].key;
}
-
- synchronized (mDozingLock) {
- // setNotificationsShown should only be called if we are confident that
- // the user has seen the notification, aka not when ambient display is on
- if (!mDozing) {
- // TODO: Call NotificationEntryManager to do this, once it exists.
- // TODO: Consider not catching all runtime exceptions here.
- try {
- mNotificationListener.setNotificationsShown(newlyVisibleKeyAr);
- } catch (RuntimeException e) {
- Log.d(TAG, "failed setNotificationsShown: ", e);
- }
- }
+ // TODO: Call NotificationEntryManager to do this, once it exists.
+ // TODO: Consider not catching all runtime exceptions here.
+ try {
+ mNotificationListener.setNotificationsShown(newlyVisibleKeyAr);
+ } catch (RuntimeException e) {
+ Log.d(TAG, "failed setNotificationsShown: ", e);
}
}
recycleAllVisibilityObjects(newlyVisibleAr);
@@ -400,14 +412,64 @@ public class NotificationLogger implements StateListener {
@Override
public void onStateChanged(int newState) {
- // don't care about state change
+ if (DEBUG) {
+ Log.i(TAG, "onStateChanged: new=" + newState);
+ }
+ synchronized (mDozingLock) {
+ mLockscreen = (newState == StatusBarState.KEYGUARD
+ || newState == StatusBarState.SHADE_LOCKED);
+ }
}
@Override
public void onDozingChanged(boolean isDozing) {
+ if (DEBUG) {
+ Log.i(TAG, "onDozingChanged: new=" + isDozing);
+ }
setDozing(isDozing);
}
+ @GuardedBy("mDozingLock")
+ private void maybeUpdateLoggingStatus() {
+ if (mPanelExpanded == null || mDozing == null) {
+ if (DEBUG) {
+ Log.i(TAG, "Panel status unclear: panelExpandedKnown="
+ + (mPanelExpanded == null) + " dozingKnown=" + (mDozing == null));
+ }
+ return;
+ }
+ // Once we know panelExpanded and Dozing, turn logging on & off when appropriate
+ boolean lockscreen = mLockscreen == null ? false : mLockscreen;
+ if (mPanelExpanded && !mDozing) {
+ mNotificationPanelLogger.logPanelShown(lockscreen,
+ mEntryManager.getVisibleNotifications());
+ if (DEBUG) {
+ Log.i(TAG, "Notification panel shown, lockscreen=" + lockscreen);
+ }
+ startNotificationLogging();
+ } else {
+ if (DEBUG) {
+ Log.i(TAG, "Notification panel hidden, lockscreen=" + lockscreen);
+ }
+ stopNotificationLogging();
+ }
+ }
+
+ /**
+ * Called by StatusBar to notify the logger that the panel expansion has changed.
+ * The panel may be showing any of the normal notification panel, the AOD, or the bouncer.
+ * @param isExpanded True if the panel is expanded.
+ */
+ public void onPanelExpandedChanged(boolean isExpanded) {
+ if (DEBUG) {
+ Log.i(TAG, "onPanelExpandedChanged: new=" + isExpanded);
+ }
+ mPanelExpanded = isExpanded;
+ synchronized (mDozingLock) {
+ maybeUpdateLoggingStatus();
+ }
+ }
+
/**
* Called when the notification is expanded / collapsed.
*/
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationPanelLogger.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationPanelLogger.java
index 9a25c480dfe8..c147023edf8d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationPanelLogger.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationPanelLogger.java
@@ -16,6 +16,13 @@
package com.android.systemui.statusbar.notification.logging;
+import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManagerKt.BUCKET_ALERTING;
+import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManagerKt.BUCKET_FOREGROUND_SERVICE;
+import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManagerKt.BUCKET_HEADS_UP;
+import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManagerKt.BUCKET_MEDIA_CONTROLS;
+import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManagerKt.BUCKET_PEOPLE;
+import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManagerKt.BUCKET_SILENT;
+
import android.annotation.Nullable;
import android.service.notification.StatusBarNotification;
@@ -23,6 +30,7 @@ import com.android.internal.logging.UiEvent;
import com.android.internal.logging.UiEventLogger;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.logging.nano.Notifications;
+import com.android.systemui.statusbar.notification.stack.PriorityBucket;
import java.util.List;
/**
@@ -84,7 +92,7 @@ public interface NotificationPanelLogger {
if (n.getNotification() != null) {
proto.isGroupSummary = n.getNotification().isGroupSummary();
}
- proto.section = 1 + ne.getBucket(); // We want 0 to mean not set / unknown
+ proto.section = toNotificationSection(ne.getBucket());
proto_array[i] = proto;
}
++i;
@@ -92,4 +100,25 @@ public interface NotificationPanelLogger {
notificationList.notifications = proto_array;
return notificationList;
}
+
+ /**
+ * Maps PriorityBucket enum to Notification.SECTION constant. The two lists should generally
+ * use matching names, but the values may differ, because PriorityBucket order changes from
+ * time to time, while logs need to have stable meanings.
+ * @param bucket PriorityBucket constant
+ * @return Notification.SECTION constant
+ */
+ static int toNotificationSection(@PriorityBucket int bucket) {
+ switch(bucket) {
+ case BUCKET_MEDIA_CONTROLS : return Notifications.Notification.SECTION_MEDIA_CONTROLS;
+ case BUCKET_HEADS_UP: return Notifications.Notification.SECTION_HEADS_UP;
+ case BUCKET_FOREGROUND_SERVICE:
+ return Notifications.Notification.SECTION_FOREGROUND_SERVICE;
+ case BUCKET_PEOPLE: return Notifications.Notification.SECTION_PEOPLE;
+ case BUCKET_ALERTING: return Notifications.Notification.SECTION_ALERTING;
+ case BUCKET_SILENT: return Notifications.Notification.SECTION_SILENT;
+ }
+ return Notifications.Notification.SECTION_UNKNOWN;
+ }
+
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/Notifications.proto b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/Notifications.proto
index 552a5fb40a1c..c2ab2758dd74 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/Notifications.proto
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/Notifications.proto
@@ -33,13 +33,16 @@ message Notification {
optional bool is_group_summary = 5;
// The section of the shade that the notification is in.
- // See NotificationSectionsManager.PriorityBucket.
+ // Sections follow NotificationSectionsManager.PriorityBucket but enum constants do not,
+ // as PriorityBucket order changes from time to time, while logs need to have stable meanings.
enum NotificationSection {
SECTION_UNKNOWN = 0;
SECTION_HEADS_UP = 1;
- SECTION_PEOPLE = 2;
- SECTION_ALERTING = 3;
- SECTION_SILENT = 4;
+ SECTION_MEDIA_CONTROLS = 2;
+ SECTION_PEOPLE = 3;
+ SECTION_ALERTING = 4;
+ SECTION_SILENT = 5;
+ SECTION_FOREGROUND_SERVICE = 6;
}
optional NotificationSection section = 6;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/AppOpsInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/AppOpsInfo.java
index e445c9d73bbb..28c53dc6d9b2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/AppOpsInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/AppOpsInfo.java
@@ -31,6 +31,7 @@ import android.widget.LinearLayout;
import android.widget.TextView;
import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.systemui.R;
@@ -50,6 +51,7 @@ public class AppOpsInfo extends LinearLayout implements NotificationGuts.GutsCon
private MetricsLogger mMetricsLogger;
private OnSettingsClickListener mOnSettingsClickListener;
private NotificationGuts mGutsContainer;
+ private UiEventLogger mUiEventLogger;
private OnClickListener mOnOk = v -> {
mGutsContainer.closeControls(v, false);
@@ -66,6 +68,7 @@ public class AppOpsInfo extends LinearLayout implements NotificationGuts.GutsCon
public void bindGuts(final PackageManager pm,
final OnSettingsClickListener onSettingsClick,
final StatusBarNotification sbn,
+ final UiEventLogger uiEventLogger,
ArraySet<Integer> activeOps) {
mPkg = sbn.getPackageName();
mSbn = sbn;
@@ -73,11 +76,13 @@ public class AppOpsInfo extends LinearLayout implements NotificationGuts.GutsCon
mAppName = mPkg;
mOnSettingsClickListener = onSettingsClick;
mAppOps = activeOps;
+ mUiEventLogger = uiEventLogger;
bindHeader();
bindPrompt();
bindButtons();
+ logUiEvent(NotificationAppOpsEvent.NOTIFICATION_APP_OPS_OPEN);
mMetricsLogger = new MetricsLogger();
mMetricsLogger.visibility(MetricsEvent.APP_OPS_GUTS, true);
}
@@ -188,6 +193,7 @@ public class AppOpsInfo extends LinearLayout implements NotificationGuts.GutsCon
@Override
public boolean handleCloseControls(boolean save, boolean force) {
+ logUiEvent(NotificationAppOpsEvent.NOTIFICATION_APP_OPS_CLOSE);
if (mMetricsLogger != null) {
mMetricsLogger.visibility(MetricsEvent.APP_OPS_GUTS, false);
}
@@ -198,4 +204,11 @@ public class AppOpsInfo extends LinearLayout implements NotificationGuts.GutsCon
public int getActualHeight() {
return getHeight();
}
+
+ private void logUiEvent(NotificationAppOpsEvent event) {
+ if (mSbn != null) {
+ mUiEventLogger.logWithInstanceId(event,
+ mSbn.getUid(), mSbn.getPackageName(), mSbn.getInstanceId());
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
index 7ed8350249ec..ccfd8a329ffd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
@@ -769,10 +769,6 @@ public abstract class ExpandableView extends FrameLayout implements Dumpable {
return mContentTranslation;
}
- public boolean wantsAddAndRemoveAnimations() {
- return true;
- }
-
/** Sets whether this view is the first notification in a section. */
public void setFirstInSection(boolean firstInSection) {
mFirstInSection = firstInSection;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationAppOpsEvent.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationAppOpsEvent.java
new file mode 100644
index 000000000000..c856245ebe83
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationAppOpsEvent.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.row;
+
+import com.android.internal.logging.UiEvent;
+import com.android.internal.logging.UiEventLogger;
+
+enum NotificationAppOpsEvent implements UiEventLogger.UiEventEnum {
+ @UiEvent(doc = "User opened app ops controls on a notification (for active "
+ + "privacy-sensitive permissions usage)")
+ NOTIFICATION_APP_OPS_OPEN(597),
+
+ @UiEvent(doc = "User closed app ops controls")
+ NOTIFICATION_APP_OPS_CLOSE(598),
+
+ @UiEvent(doc = "User clicked through to settings in app ops controls")
+ NOTIFICATION_APP_OPS_SETTINGS_CLICK(599);
+
+ private final int mId;
+ NotificationAppOpsEvent(int id) {
+ mId = id;
+ }
+ @Override public int getId() {
+ return mId;
+ }
+}
+
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationControlsEvent.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationControlsEvent.java
new file mode 100644
index 000000000000..6833326d47e5
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationControlsEvent.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.row;
+
+import com.android.internal.logging.UiEvent;
+import com.android.internal.logging.UiEventLogger;
+
+enum NotificationControlsEvent implements UiEventLogger.UiEventEnum {
+ @UiEvent(doc = "The user opened the notification inline controls.")
+ NOTIFICATION_CONTROLS_OPEN(594),
+
+ @UiEvent(doc = "In notification inline controls, the user saved a notification channel "
+ + "importance change.")
+ NOTIFICATION_CONTROLS_SAVE_IMPORTANCE(595),
+
+ @UiEvent(doc = "The user closed the notification inline controls.")
+ NOTIFICATION_CONTROLS_CLOSE(596);
+
+ private final int mId;
+ NotificationControlsEvent(int id) {
+ mId = id;
+ }
+ @Override public int getId() {
+ return mId;
+ }
+}
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 bee2f7002823..f543db74d91a 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
@@ -65,6 +65,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.settingslib.notification.ConversationIconFactory;
import com.android.systemui.Prefs;
import com.android.systemui.R;
+import com.android.systemui.bubbles.BubbleController;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.statusbar.notification.NotificationChannelHelper;
@@ -91,7 +92,7 @@ public class NotificationConversationInfo extends LinearLayout implements
private VisualStabilityManager mVisualStabilityManager;
private Handler mMainHandler;
private Handler mBgHandler;
-
+ private BubbleController mBubbleController;
private String mPackageName;
private String mAppName;
private int mAppUid;
@@ -219,7 +220,8 @@ public class NotificationConversationInfo extends LinearLayout implements
boolean isDeviceProvisioned,
@Main Handler mainHandler,
@Background Handler bgHandler,
- OnConversationSettingsClickListener onConversationSettingsClickListener) {
+ OnConversationSettingsClickListener onConversationSettingsClickListener,
+ BubbleController bubbleController) {
mSelectedAction = -1;
mINotificationManager = iNotificationManager;
mVisualStabilityManager = visualStabilityManager;
@@ -238,6 +240,7 @@ public class NotificationConversationInfo extends LinearLayout implements
mIconFactory = conversationIconFactory;
mUserContext = userContext;
mBubbleMetadata = bubbleMetadata;
+ mBubbleController = bubbleController;
mBuilderProvider = builderProvider;
mMainHandler = mainHandler;
mBgHandler = bgHandler;
@@ -627,6 +630,9 @@ public class NotificationConversationInfo extends LinearLayout implements
mINotificationManager.setBubblesAllowed(mAppPkg, mAppUid,
BUBBLE_PREFERENCE_SELECTED);
}
+ post(() -> {
+ mBubbleController.onUserChangedImportance(mEntry);
+ });
}
mChannelToUpdate.setImportance(Math.max(
mChannelToUpdate.getOriginalImportance(), IMPORTANCE_DEFAULT));
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
index 1074adc3383d..24883f51a984 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
@@ -41,11 +41,13 @@ import android.view.accessibility.AccessibilityManager;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settingslib.notification.ConversationIconFactory;
import com.android.systemui.Dependency;
import com.android.systemui.Dumpable;
import com.android.systemui.R;
+import com.android.systemui.bubbles.BubbleController;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
@@ -113,12 +115,14 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx
private final Lazy<StatusBar> mStatusBarLazy;
private final Handler mMainHandler;
private final Handler mBgHandler;
+ private final BubbleController mBubbleController;
private Runnable mOpenRunnable;
private final INotificationManager mNotificationManager;
private final LauncherApps mLauncherApps;
private final ShortcutManager mShortcutManager;
private final CurrentUserContextTracker mContextTracker;
private final Provider<PriorityOnboardingDialogController.Builder> mBuilderProvider;
+ private final UiEventLogger mUiEventLogger;
/**
* Injected constructor. See {@link NotificationsModule}.
@@ -132,7 +136,9 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx
ShortcutManager shortcutManager,
ChannelEditorDialogController channelEditorDialogController,
CurrentUserContextTracker contextTracker,
- Provider<PriorityOnboardingDialogController.Builder> builderProvider) {
+ Provider<PriorityOnboardingDialogController.Builder> builderProvider,
+ BubbleController bubbleController,
+ UiEventLogger uiEventLogger) {
mContext = context;
mVisualStabilityManager = visualStabilityManager;
mStatusBarLazy = statusBarLazy;
@@ -146,6 +152,8 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx
mContextTracker = contextTracker;
mBuilderProvider = builderProvider;
mChannelEditorDialogController = channelEditorDialogController;
+ mBubbleController = bubbleController;
+ mUiEventLogger = uiEventLogger;
}
public void setUpWithPresenter(NotificationPresenter presenter,
@@ -311,12 +319,16 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx
AppOpsInfo.OnSettingsClickListener onSettingsClick =
(View v, String pkg, int uid, ArraySet<Integer> ops) -> {
- mMetricsLogger.action(MetricsProto.MetricsEvent.ACTION_OPS_GUTS_SETTINGS);
- guts.resetFalsingCheck();
- startAppOpsSettingsActivity(pkg, uid, ops, row);
+ mUiEventLogger.logWithInstanceId(
+ NotificationAppOpsEvent.NOTIFICATION_APP_OPS_SETTINGS_CLICK,
+ sbn.getUid(), sbn.getPackageName(), sbn.getInstanceId());
+ mMetricsLogger.action(MetricsProto.MetricsEvent.ACTION_OPS_GUTS_SETTINGS);
+ guts.resetFalsingCheck();
+ startAppOpsSettingsActivity(pkg, uid, ops, row);
};
if (!row.getEntry().mActiveAppOps.isEmpty()) {
- appOpsInfoView.bindGuts(pmUser, onSettingsClick, sbn, row.getEntry().mActiveAppOps);
+ appOpsInfoView.bindGuts(pmUser, onSettingsClick, sbn, mUiEventLogger,
+ row.getEntry().mActiveAppOps);
}
}
@@ -366,6 +378,7 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx
row.getEntry(),
onSettingsClick,
onAppSettingsClick,
+ mUiEventLogger,
mDeviceProvisionedController.isDeviceProvisioned(),
row.getIsNonblockable(),
mHighPriorityProvider.isHighPriority(row.getEntry()));
@@ -480,7 +493,8 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx
mDeviceProvisionedController.isDeviceProvisioned(),
mMainHandler,
mBgHandler,
- onConversationSettingsListener);
+ onConversationSettingsListener,
+ mBubbleController);
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java
index a131ebef77db..f0c93b10578c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java
@@ -56,6 +56,7 @@ import android.widget.TextView;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.systemui.Dependency;
import com.android.systemui.R;
@@ -122,6 +123,7 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
private OnAppSettingsClickListener mAppSettingsClickListener;
private NotificationGuts mGutsContainer;
private Drawable mPkgIcon;
+ private UiEventLogger mUiEventLogger;
@VisibleForTesting
boolean mSkipPost = false;
@@ -182,6 +184,7 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
NotificationEntry entry,
OnSettingsClickListener onSettingsClick,
OnAppSettingsClickListener onAppSettingsClick,
+ UiEventLogger uiEventLogger,
boolean isDeviceProvisioned,
boolean isNonblockable,
boolean wasShownHighPriority)
@@ -205,6 +208,7 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
mAppUid = mSbn.getUid();
mDelegatePkg = mSbn.getOpPkg();
mIsDeviceProvisioned = isDeviceProvisioned;
+ mUiEventLogger = uiEventLogger;
int numTotalChannels = mINotificationManager.getNumNotificationChannelsForPackage(
pkg, mAppUid, false /* includeDeleted */);
@@ -223,6 +227,7 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
bindInlineControls();
+ logUiEvent(NotificationControlsEvent.NOTIFICATION_CONTROLS_OPEN);
mMetricsLogger.write(notificationControlsLogMaker());
}
@@ -397,6 +402,7 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
*/
private void updateImportance() {
if (mChosenImportance != null) {
+ logUiEvent(NotificationControlsEvent.NOTIFICATION_CONTROLS_SAVE_IMPORTANCE);
mMetricsLogger.write(importanceChangeLogMaker());
int newImportance = mChosenImportance;
@@ -483,6 +489,7 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
bindInlineControls();
+ logUiEvent(NotificationControlsEvent.NOTIFICATION_CONTROLS_CLOSE);
mMetricsLogger.write(notificationControlsLogMaker().setType(MetricsEvent.TYPE_CLOSE));
}
@@ -627,6 +634,13 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
}
}
+ private void logUiEvent(NotificationControlsEvent event) {
+ if (mSbn != null) {
+ mUiEventLogger.logWithInstanceId(event,
+ mSbn.getUid(), mSbn.getPackageName(), mSbn.getInstanceId());
+ }
+ }
+
/**
* Returns a LogMaker with all available notification information.
* Caller should set category, type, and maybe subtype, before passing it to mMetricsLogger.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
index b4220f1da715..11e698b03823 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
@@ -83,6 +83,8 @@ public class AmbientState {
private float mDozeAmount = 0.0f;
private HeadsUpManager mHeadUpManager;
private Runnable mOnPulseHeightChangedListener;
+ private ExpandableNotificationRow mTrackedHeadsUpRow;
+ private float mAppearFraction;
public AmbientState(
Context context,
@@ -543,4 +545,27 @@ public class AmbientState {
public Runnable getOnPulseHeightChangedListener() {
return mOnPulseHeightChangedListener;
}
+
+ public void setTrackedHeadsUpRow(ExpandableNotificationRow row) {
+ mTrackedHeadsUpRow = row;
+ }
+
+ /**
+ * Returns the currently tracked heads up row, if there is one and it is currently above the
+ * shelf (still appearing).
+ */
+ public ExpandableNotificationRow getTrackedHeadsUpRow() {
+ if (mTrackedHeadsUpRow == null || !mTrackedHeadsUpRow.isAboveShelf()) {
+ return null;
+ }
+ return mTrackedHeadsUpRow;
+ }
+
+ public void setAppearFraction(float appearFraction) {
+ mAppearFraction = appearFraction;
+ }
+
+ public float getAppearFraction() {
+ return mAppearFraction;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MediaHeaderView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MediaHeaderView.java
index 383f2a2b0e9f..040f707e12f1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MediaHeaderView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MediaHeaderView.java
@@ -50,9 +50,4 @@ public class MediaHeaderView extends ExpandableView {
layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;
}
-
- @Override
- public boolean wantsAddAndRemoveAnimations() {
- return false;
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt
index 0bdac39f35e9..c87b9986ca55 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt
@@ -41,6 +41,7 @@ import com.android.systemui.statusbar.notification.row.StackScrollerDecorView
import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm.SectionProvider
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.util.children
+import com.android.systemui.util.takeUntil
import com.android.systemui.util.foldToSparseArray
import javax.inject.Inject
@@ -197,7 +198,7 @@ class NotificationSectionsManager @Inject internal constructor(
else -> null
}
- private fun logShadeContents() = parent.children.forEachIndexed { i, child ->
+ private fun logShadeChild(i: Int, child: View) {
when {
child === incomingHeaderView -> logger.logIncomingHeader(i)
child === mediaControlsView -> logger.logMediaControls(i)
@@ -216,6 +217,7 @@ class NotificationSectionsManager @Inject internal constructor(
}
}
}
+ private fun logShadeContents() = parent.children.forEachIndexed(::logShadeChild)
private val isUsingMultipleSections: Boolean
get() = sectionsFeatureManager.getNumberOfBuckets() > 1
@@ -223,6 +225,57 @@ class NotificationSectionsManager @Inject internal constructor(
@VisibleForTesting
fun updateSectionBoundaries() = updateSectionBoundaries("test")
+ private interface SectionUpdateState<out T : ExpandableView> {
+ val header: T
+ var currentPosition: Int?
+ var targetPosition: Int?
+ fun adjustViewPosition()
+ }
+
+ private fun <T : ExpandableView> expandableViewHeaderState(header: T): SectionUpdateState<T> =
+ object : SectionUpdateState<T> {
+ override val header = header
+ override var currentPosition: Int? = null
+ override var targetPosition: Int? = null
+
+ override fun adjustViewPosition() {
+ val target = targetPosition
+ val current = currentPosition
+ if (target == null) {
+ if (current != null) {
+ parent.removeView(header)
+ }
+ } else {
+ if (current == null) {
+ // If the header is animating away, it will still have a parent, so
+ // detach it first
+ // TODO: We should really cancel the active animations here. This will
+ // happen automatically when the view's intro animation starts, but
+ // it's a fragile link.
+ header.transientContainer?.removeTransientView(header)
+ header.transientContainer = null
+ parent.addView(header, target)
+ } else {
+ parent.changeViewPosition(header, target)
+ }
+ }
+ }
+ }
+
+ private fun <T : StackScrollerDecorView> decorViewHeaderState(
+ header: T
+ ): SectionUpdateState<T> {
+ val inner = expandableViewHeaderState(header)
+ return object : SectionUpdateState<T> by inner {
+ override fun adjustViewPosition() {
+ inner.adjustViewPosition()
+ if (targetPosition != null && currentPosition == null) {
+ header.isContentVisible = true
+ }
+ }
+ }
+ }
+
/**
* Should be called whenever notifs are added, removed, or updated. Updates section boundary
* bookkeeping and adds/moves/removes section headers if appropriate.
@@ -238,233 +291,136 @@ class NotificationSectionsManager @Inject internal constructor(
// Then, once we find the start of a new section, we track that position as the "target" for
// the section header, adjusted for the case where existing headers are in front of that
// target, but won't be once they are moved / removed after the pass has completed.
+
val showHeaders = statusBarStateController.state != StatusBarState.KEYGUARD
val usingPeopleFiltering = sectionsFeatureManager.isFilteringEnabled()
val usingMediaControls = sectionsFeatureManager.isMediaControlsEnabled()
- var peopleNotifsPresent = false
- var currentMediaControlsIdx = -1
- val mediaControlsTarget = if (usingMediaControls) 0 else -1
- var currentIncomingHeaderIdx = -1
- var incomingHeaderTarget = -1
- var currentPeopleHeaderIdx = -1
- var peopleHeaderTarget = -1
- var currentAlertingHeaderIdx = -1
- var alertingHeaderTarget = -1
- var currentGentleHeaderIdx = -1
- var gentleHeaderTarget = -1
+ val mediaState = mediaControlsView?.let(::expandableViewHeaderState)
+ val incomingState = incomingHeaderView?.let(::decorViewHeaderState)
+ val peopleState = peopleHeaderView?.let(::decorViewHeaderState)
+ val alertingState = alertingHeaderView?.let(::decorViewHeaderState)
+ val gentleState = silentHeaderView?.let(::decorViewHeaderState)
+
+ fun getSectionState(view: View): SectionUpdateState<ExpandableView>? = when {
+ view === mediaControlsView -> mediaState
+ view === incomingHeaderView -> incomingState
+ view === peopleHeaderView -> peopleState
+ view === alertingHeaderView -> alertingState
+ view === silentHeaderView -> gentleState
+ else -> null
+ }
+ val headersOrdered = sequenceOf(
+ mediaState, incomingState, peopleState, alertingState, gentleState
+ ).filterNotNull()
+
+ var peopleNotifsPresent = false
var lastNotifIndex = 0
- var lastIncomingIndex = -1
- var prev: ExpandableNotificationRow? = null
-
- for ((i, child) in parent.children.withIndex()) {
- when {
- // Track the existing positions of the headers
- child === incomingHeaderView -> {
- logger.logIncomingHeader(i)
- currentIncomingHeaderIdx = i
- }
- child === mediaControlsView -> {
- logger.logMediaControls(i)
- currentMediaControlsIdx = i
- }
- child === peopleHeaderView -> {
- logger.logConversationsHeader(i)
- currentPeopleHeaderIdx = i
- }
- child === alertingHeaderView -> {
- logger.logAlertingHeader(i)
- currentAlertingHeaderIdx = i
+ var nextBucket: Int? = null
+ var inIncomingSection = false
+
+ // Iterating backwards allows for easier construction of the Incoming section, as opposed
+ // to backtracking when a discontinuity in the sections is discovered.
+ // Iterating to -1 in order to support the case where a header is at the very top of the
+ // shade.
+ for (i in parent.childCount - 1 downTo -1) {
+ val child: View? = parent.getChildAt(i)
+ child?.let {
+ logShadeChild(i, child)
+ // If this child is a header, update the tracked positions
+ getSectionState(child)?.let { state ->
+ state.currentPosition = i
+ // If headers that should appear above this one in the shade already have a
+ // target index, then we need to decrement them in order to account for this one
+ // being either removed, or moved below them.
+ headersOrdered.takeUntil { it === state }
+ .forEach { it.targetPosition = it.targetPosition?.minus(1) }
}
- child === silentHeaderView -> {
- logger.logSilentHeader(i)
- currentGentleHeaderIdx = i
- }
- child !is ExpandableNotificationRow -> logger.logOther(i, child.javaClass)
- else -> {
- lastNotifIndex = i
- // Is there a section discontinuity? This usually occurs due to HUNs
- if (prev?.entry?.bucket?.let { it > child.entry.bucket } == true) {
- // Remove existing headers, and move the Incoming header if necessary
- incomingHeaderTarget = when {
- !showHeaders -> -1
- incomingHeaderTarget != -1 -> incomingHeaderTarget
- peopleHeaderTarget != -1 -> peopleHeaderTarget
- alertingHeaderTarget != -1 -> alertingHeaderTarget
- gentleHeaderTarget != -1 -> gentleHeaderTarget
- else -> 0
- }
- peopleHeaderTarget = -1
- alertingHeaderTarget = -1
- gentleHeaderTarget = -1
- // Walk backwards changing all previous notifications to the Incoming
- // section
- for (j in i - 1 downTo lastIncomingIndex + 1) {
- val prevChild = parent.getChildAt(j)
- if (prevChild is ExpandableNotificationRow) {
- prevChild.entry.bucket = BUCKET_HEADS_UP
- }
- }
- // Track the new bottom of the Incoming section
- lastIncomingIndex = i - 1
- }
- val isHeadsUp = child.isHeadsUp
- when (child.entry.bucket) {
- BUCKET_FOREGROUND_SERVICE -> logger.logForegroundService(i, isHeadsUp)
- BUCKET_PEOPLE -> {
- logger.logConversation(i, isHeadsUp)
- peopleNotifsPresent = true
- if (showHeaders && peopleHeaderTarget == -1) {
- peopleHeaderTarget = i
- // Offset the target if there are other headers before this that
- // will be moved.
- if (currentIncomingHeaderIdx != -1 && incomingHeaderTarget == -1) {
- peopleHeaderTarget--
- }
- if (currentPeopleHeaderIdx != -1) {
- peopleHeaderTarget--
- }
- if (currentAlertingHeaderIdx != -1) {
- peopleHeaderTarget--
- }
- if (currentGentleHeaderIdx != -1) {
- peopleHeaderTarget--
- }
- }
- }
- BUCKET_ALERTING -> {
- logger.logAlerting(i, isHeadsUp)
- if (showHeaders && usingPeopleFiltering && alertingHeaderTarget == -1) {
- alertingHeaderTarget = i
- // Offset the target if there are other headers before this that
- // will be moved.
- if (currentIncomingHeaderIdx != -1 && incomingHeaderTarget == -1) {
- alertingHeaderTarget--
- }
- if (currentPeopleHeaderIdx != -1 && peopleHeaderTarget == -1) {
- // People header will be removed
- alertingHeaderTarget--
- }
- if (currentAlertingHeaderIdx != -1) {
- alertingHeaderTarget--
- }
- if (currentGentleHeaderIdx != -1) {
- alertingHeaderTarget--
- }
- }
- }
- BUCKET_SILENT -> {
- logger.logSilent(i, isHeadsUp)
- if (showHeaders && gentleHeaderTarget == -1) {
- gentleHeaderTarget = i
- // Offset the target if there are other headers before this that
- // will be moved.
- if (currentIncomingHeaderIdx != -1 && incomingHeaderTarget == -1) {
- gentleHeaderTarget--
- }
- if (currentPeopleHeaderIdx != -1 && peopleHeaderTarget == -1) {
- // People header will be removed
- gentleHeaderTarget--
- }
- if (currentAlertingHeaderIdx != -1 && alertingHeaderTarget == -1) {
- // Alerting header will be removed
- gentleHeaderTarget--
- }
- if (currentGentleHeaderIdx != -1) {
- gentleHeaderTarget--
- }
- }
- }
- }
+ }
+
+ val row = child as? ExpandableNotificationRow
+
+ // Is there a section discontinuity? This usually occurs due to HUNs
+ inIncomingSection = inIncomingSection || nextBucket?.let { next ->
+ row?.entry?.bucket?.let { curr -> next < curr }
+ } == true
- prev = child
+ if (inIncomingSection) {
+ // Update the bucket to reflect that it's being placed in the Incoming section
+ row?.entry?.bucket = BUCKET_HEADS_UP
+ }
+
+ // Insert a header in front of the next row, if there's a boundary between it and this
+ // row, or if it is the topmost row.
+ val isSectionBoundary = nextBucket != null &&
+ (child == null || row != null && nextBucket != row.entry.bucket)
+ if (isSectionBoundary && showHeaders) {
+ when (nextBucket) {
+ BUCKET_HEADS_UP -> incomingState?.targetPosition = i + 1
+ BUCKET_PEOPLE -> peopleState?.targetPosition = i + 1
+ BUCKET_ALERTING -> alertingState?.targetPosition = i + 1
+ BUCKET_SILENT -> gentleState?.targetPosition = i + 1
}
}
- }
- if (showHeaders && usingPeopleFiltering && peopleHubVisible && peopleHeaderTarget == -1) {
- // Insert the people header even if there are no people visible, in order to show
- // the hub. Put it directly above the next header.
- peopleHeaderTarget = when {
- alertingHeaderTarget != -1 -> alertingHeaderTarget
- gentleHeaderTarget != -1 -> gentleHeaderTarget
- else -> lastNotifIndex // Put it at the end of the list.
+ row ?: continue
+
+ // Check if there are any people notifications
+ peopleNotifsPresent = peopleNotifsPresent || row.entry.bucket == BUCKET_PEOPLE
+
+ if (nextBucket == null) {
+ lastNotifIndex = i
}
+ nextBucket = row.entry.bucket
+ }
+
+ if (showHeaders && usingPeopleFiltering && peopleHubVisible) {
+ peopleState?.targetPosition = peopleState?.targetPosition
+ // Insert the people header even if there are no people visible, in order to
+ // show the hub. Put it directly above the next header.
+ ?: alertingState?.targetPosition
+ ?: gentleState?.targetPosition
+ // Put it at the end of the list.
+ ?: lastNotifIndex
+
// Offset the target to account for the current position of the people header.
- if (currentPeopleHeaderIdx != -1 && currentPeopleHeaderIdx < peopleHeaderTarget) {
- peopleHeaderTarget--
+ peopleState?.targetPosition = peopleState?.currentPosition?.let { current ->
+ peopleState?.targetPosition?.let { target ->
+ if (current < target) target - 1 else target
+ }
}
}
+ mediaState?.targetPosition = if (usingMediaControls) 0 else null
+
logger.logStr("New header target positions:")
- logger.logIncomingHeader(incomingHeaderTarget)
- logger.logMediaControls(mediaControlsTarget)
- logger.logConversationsHeader(peopleHeaderTarget)
- logger.logAlertingHeader(alertingHeaderTarget)
- logger.logSilentHeader(gentleHeaderTarget)
-
- // Add headers in reverse order to preserve indices
- silentHeaderView?.let {
- adjustHeaderVisibilityAndPosition(gentleHeaderTarget, it, currentGentleHeaderIdx)
- }
- alertingHeaderView?.let {
- adjustHeaderVisibilityAndPosition(alertingHeaderTarget, it, currentAlertingHeaderIdx)
- }
- peopleHeaderView?.let {
- adjustHeaderVisibilityAndPosition(peopleHeaderTarget, it, currentPeopleHeaderIdx)
- }
- incomingHeaderView?.let {
- adjustHeaderVisibilityAndPosition(incomingHeaderTarget, it, currentIncomingHeaderIdx)
- }
- mediaControlsView?.let {
- adjustViewPosition(mediaControlsTarget, it, currentMediaControlsIdx)
- }
+ logger.logMediaControls(mediaState?.targetPosition ?: -1)
+ logger.logIncomingHeader(incomingState?.targetPosition ?: -1)
+ logger.logConversationsHeader(peopleState?.targetPosition ?: -1)
+ logger.logAlertingHeader(alertingState?.targetPosition ?: -1)
+ logger.logSilentHeader(gentleState?.targetPosition ?: -1)
+
+ // Update headers in reverse order to preserve indices, otherwise movements earlier in the
+ // list will affect the target indices of the headers later in the list.
+ headersOrdered.asIterable().reversed().forEach { it.adjustViewPosition() }
logger.logStr("Final order:")
logShadeContents()
logger.logStr("Section boundary update complete")
// Update headers to reflect state of section contents
- silentHeaderView?.setAreThereDismissableGentleNotifs(
- parent.hasActiveClearableNotifications(NotificationStackScrollLayout.ROWS_GENTLE)
- )
- peopleHeaderView?.canSwipe = showHeaders && peopleHubVisible && !peopleNotifsPresent
- if (peopleHeaderTarget != currentPeopleHeaderIdx) {
- peopleHeaderView?.resetTranslation()
- }
- }
-
- private fun adjustHeaderVisibilityAndPosition(
- targetPosition: Int,
- header: StackScrollerDecorView,
- currentPosition: Int
- ) {
- adjustViewPosition(targetPosition, header, currentPosition)
- if (targetPosition != -1 && currentPosition == -1) {
- header.isContentVisible = true
+ silentHeaderView?.run {
+ val hasActiveClearableNotifications = this@NotificationSectionsManager.parent
+ .hasActiveClearableNotifications(NotificationStackScrollLayout.ROWS_GENTLE)
+ setAreThereDismissableGentleNotifs(hasActiveClearableNotifications)
}
- }
-
- private fun adjustViewPosition(
- targetPosition: Int,
- view: ExpandableView,
- currentPosition: Int
- ) {
- if (targetPosition == -1) {
- if (currentPosition != -1) {
- parent.removeView(view)
- }
- } else {
- if (currentPosition == -1) {
- // If the header is animating away, it will still have a parent, so detach it first
- // TODO: We should really cancel the active animations here. This will happen
- // automatically when the view's intro animation starts, but it's a fragile link.
- view.transientContainer?.removeTransientView(view)
- view.transientContainer = null
- parent.addView(view, targetPosition)
- } else {
- parent.changeViewPosition(view, targetPosition)
+ peopleHeaderView?.run {
+ canSwipe = showHeaders && peopleHubVisible && !peopleNotifsPresent
+ peopleState?.targetPosition?.let { targetPosition ->
+ if (targetPosition != peopleState.currentPosition) {
+ resetTranslation()
+ }
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index 684bf1958154..b9d31a93f408 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -97,6 +97,7 @@ import com.android.systemui.Interpolators;
import com.android.systemui.R;
import com.android.systemui.SwipeHelper;
import com.android.systemui.colorextraction.SysuiColorExtractor;
+import com.android.systemui.media.KeyguardMediaController;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin.MenuItem;
@@ -200,6 +201,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
private final KeyguardBypassController mKeyguardBypassController;
private final DynamicPrivacyController mDynamicPrivacyController;
private final SysuiStatusBarStateController mStatusbarStateController;
+ private final KeyguardMediaController mKeyguardMediaController;
private ExpandHelper mExpandHelper;
private final NotificationSwipeHelper mSwipeHelper;
@@ -533,6 +535,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
private float mLastSentAppear;
private float mLastSentExpandedHeight;
private boolean mWillExpand;
+ private int mGapHeight;
private int mWaterfallTopInset;
@@ -552,6 +555,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
SysuiStatusBarStateController statusBarStateController,
HeadsUpManagerPhone headsUpManager,
KeyguardBypassController keyguardBypassController,
+ KeyguardMediaController keyguardMediaController,
FalsingManager falsingManager,
NotificationLockscreenUserManager notificationLockscreenUserManager,
NotificationGutsManager notificationGutsManager,
@@ -670,6 +674,16 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
initializeForegroundServiceSection(fgsFeatureController);
mUiEventLogger = uiEventLogger;
mColorExtractor.addOnColorsChangedListener(mOnColorsChangedListener);
+ mKeyguardMediaController = keyguardMediaController;
+ keyguardMediaController.setVisibilityChangedListener((visible) -> {
+ if (visible) {
+ generateAddAnimation(keyguardMediaController.getView(), false /*fromMoreCard */);
+ } else {
+ generateRemoveAnimation(keyguardMediaController.getView());
+ }
+ requestChildrenUpdate();
+ return null;
+ });
}
private void initializeForegroundServiceSection(
@@ -1047,6 +1061,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
Resources res = context.getResources();
mCollapsedSize = res.getDimensionPixelSize(R.dimen.notification_min_height);
+ mGapHeight = res.getDimensionPixelSize(R.dimen.notification_section_divider_height);
mStackScrollAlgorithm.initView(context);
mAmbientState.reload(context);
mPaddingBetweenElements = Math.max(1,
@@ -1407,14 +1422,12 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
// start
translationY = height - appearStartPosition + getExpandTranslationStart();
}
+ stackHeight = (int) (height - translationY);
if (isHeadsUpTransition()) {
- stackHeight =
- getFirstVisibleSection().getFirstVisibleChild().getPinnedHeadsUpHeight();
translationY = MathUtils.lerp(mHeadsUpInset - mTopPadding, 0, appearFraction);
- } else {
- stackHeight = (int) (height - translationY);
}
}
+ mAmbientState.setAppearFraction(appearFraction);
if (stackHeight != mCurrentStackHeight) {
mCurrentStackHeight = stackHeight;
updateAlgorithmHeightAndPadding();
@@ -1532,17 +1545,18 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
*/
@ShadeViewRefactor(RefactorComponent.COORDINATOR)
private float getAppearEndPosition() {
- int appearPosition;
- int notGoneChildCount = getNotGoneChildCount();
- if (mEmptyShadeView.getVisibility() == GONE && notGoneChildCount != 0) {
+ int appearPosition = 0;
+ int visibleNotifCount = getVisibleNotificationCount();
+ if (mEmptyShadeView.getVisibility() == GONE && visibleNotifCount > 0) {
if (isHeadsUpTransition()
|| (mHeadsUpManager.hasPinnedHeadsUp() && !mAmbientState.isDozing())) {
- appearPosition = getTopHeadsUpPinnedHeight();
- } else {
- appearPosition = 0;
- if (notGoneChildCount >= 1 && mShelf.getVisibility() != GONE) {
- appearPosition += mShelf.getIntrinsicHeight();
+ if (mShelf.getVisibility() != GONE && visibleNotifCount > 1) {
+ appearPosition += mShelf.getIntrinsicHeight() + mPaddingBetweenElements;
}
+ appearPosition += getTopHeadsUpPinnedHeight()
+ + getPositionInLinearLayout(mAmbientState.getTrackedHeadsUpRow());
+ } else if (mShelf.getVisibility() != GONE) {
+ appearPosition += mShelf.getIntrinsicHeight();
}
} else {
appearPosition = mEmptyShadeView.getHeight();
@@ -1552,9 +1566,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
private boolean isHeadsUpTransition() {
- NotificationSection firstVisibleSection = getFirstVisibleSection();
- return mTrackingHeadsUp && firstVisibleSection != null
- && firstVisibleSection.getFirstVisibleChild().isAboveShelf();
+ return mAmbientState.getTrackedHeadsUpRow() != null;
}
/**
@@ -2962,7 +2974,16 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
@ShadeViewRefactor(RefactorComponent.COORDINATOR)
public int getLayoutMinHeight() {
if (isHeadsUpTransition()) {
- return getTopHeadsUpPinnedHeight();
+ ExpandableNotificationRow trackedHeadsUpRow = mAmbientState.getTrackedHeadsUpRow();
+ if (trackedHeadsUpRow.isAboveShelf()) {
+ int hunDistance = (int) MathUtils.lerp(
+ 0,
+ getPositionInLinearLayout(trackedHeadsUpRow),
+ mAmbientState.getAppearFraction());
+ return getTopHeadsUpPinnedHeight() + hunDistance;
+ } else {
+ return getTopHeadsUpPinnedHeight();
+ }
}
return mShelf.getVisibility() == GONE ? 0 : mShelf.getIntrinsicHeight();
}
@@ -3101,9 +3122,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
*/
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
private boolean generateRemoveAnimation(ExpandableView child) {
- if (!child.wantsAddAndRemoveAnimations()) {
- return false;
- }
if (removeRemovedChildFromHeadsUpChangeAnimations(child)) {
mAddedHeadsUpChildren.remove(child);
return false;
@@ -3458,8 +3476,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
@Override
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
public void generateAddAnimation(ExpandableView child, boolean fromMoreCard) {
- if (mIsExpanded && mAnimationsEnabled && !mChangePositionInProgress && !isFullyHidden()
- && child.wantsAddAndRemoveAnimations()) {
+ if (mIsExpanded && mAnimationsEnabled && !mChangePositionInProgress && !isFullyHidden()) {
// Generate Animations
mChildrenToAddAnimated.add(child);
if (fromMoreCard) {
@@ -3654,6 +3671,8 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
ignoreChildren = false;
}
childWasSwipedOut |= Math.abs(row.getTranslation()) == row.getWidth();
+ } else if (child instanceof MediaHeaderView) {
+ childWasSwipedOut = true;
}
if (!childWasSwipedOut) {
Rect clipBounds = child.getClipBounds();
@@ -5082,8 +5101,10 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
}
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
- public int getFooterViewHeight() {
- return mFooterView == null ? 0 : mFooterView.getHeight() + mPaddingBetweenElements;
+ public int getFooterViewHeightWithPadding() {
+ return mFooterView == null ? 0 : mFooterView.getHeight()
+ + mPaddingBetweenElements
+ + mGapHeight;
}
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
@@ -5284,6 +5305,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
public void setTrackingHeadsUp(ExpandableNotificationRow row) {
+ mAmbientState.setTrackedHeadsUpRow(row);
mTrackingHeadsUp = row != null;
mRoundnessManager.setTrackingHeadsUp(row);
}
@@ -6370,7 +6392,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
@Override
public void onDragCancelled(View v) {
setSwipingInProgress(false);
- mFalsingManager.onNotificatonStopDismissing();
+ mFalsingManager.onNotificationStopDismissing();
}
/**
@@ -6470,7 +6492,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
@Override
public void onBeginDrag(View v) {
- mFalsingManager.onNotificatonStartDismissing();
+ mFalsingManager.onNotificationStartDismissing();
setSwipingInProgress(true);
mAmbientState.onBeginDrag((ExpandableView) v);
updateContinuousShadowDrawing();
@@ -6629,7 +6651,9 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
/* Only ever called as a consequence of a lockscreen expansion gesture. */
@Override
public boolean onDraggedDown(View startingChild, int dragLengthY) {
- if (mStatusBarState == StatusBarState.KEYGUARD && hasActiveNotifications()) {
+ boolean canDragDown = hasActiveNotifications()
+ || mKeyguardMediaController.getView().getVisibility() == VISIBLE;
+ if (mStatusBarState == StatusBarState.KEYGUARD && canDragDown) {
mLockscreenGestureLogger.write(
MetricsEvent.ACTION_LS_SHADE,
(int) (dragLengthY / mDisplayMetrics.density),
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
index a4598e9cec9f..541c7845a5d3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
@@ -21,6 +21,7 @@ import android.annotation.Nullable;
import android.content.Context;
import android.content.res.Resources;
import android.util.Log;
+import android.util.MathUtils;
import android.view.View;
import android.view.ViewGroup;
@@ -441,7 +442,7 @@ public class StackScrollAlgorithm {
} else if (isEmptyShadeView) {
childViewState.yTranslation = ambientState.getInnerHeight() - childHeight
+ ambientState.getStackTranslation() * 0.25f;
- } else {
+ } else if (child != ambientState.getTrackedHeadsUpRow()) {
clampPositionToShelf(child, childViewState, ambientState);
}
@@ -539,6 +540,19 @@ public class StackScrollAlgorithm {
private void updateHeadsUpStates(StackScrollAlgorithmState algorithmState,
AmbientState ambientState) {
int childCount = algorithmState.visibleChildren.size();
+
+ // Move the tracked heads up into position during the appear animation, by interpolating
+ // between the HUN inset (where it will appear as a HUN) and the end position in the shade
+ ExpandableNotificationRow trackedHeadsUpRow = ambientState.getTrackedHeadsUpRow();
+ if (trackedHeadsUpRow != null) {
+ ExpandableViewState childState = trackedHeadsUpRow.getViewState();
+ if (childState != null) {
+ float endPosition = childState.yTranslation - ambientState.getStackTranslation();
+ childState.yTranslation = MathUtils.lerp(
+ mHeadsUpInset, endPosition, ambientState.getAppearFraction());
+ }
+ }
+
ExpandableNotificationRow topHeadsUpEntry = null;
for (int i = 0; i < childCount; i++) {
View child = algorithmState.visibleChildren.get(i);
@@ -561,7 +575,7 @@ public class StackScrollAlgorithm {
&& !row.showingPulsing()) {
// Ensure that the heads up is always visible even when scrolled off
clampHunToTop(ambientState, row, childState);
- if (i == 0 && row.isAboveShelf()) {
+ if (isTopEntry && row.isAboveShelf()) {
// the first hun can't get off screen.
clampHunToMaxTranslation(ambientState, row, childState);
childState.hidden = false;
@@ -636,9 +650,13 @@ public class StackScrollAlgorithm {
return;
}
+ ExpandableNotificationRow trackedHeadsUpRow = ambientState.getTrackedHeadsUpRow();
+ boolean isBeforeTrackedHeadsUp = trackedHeadsUpRow != null
+ && mHostView.indexOfChild(child) < mHostView.indexOfChild(trackedHeadsUpRow);
+
int shelfStart = ambientState.getInnerHeight()
- ambientState.getShelf().getIntrinsicHeight();
- if (ambientState.isAppearing() && !child.isAboveShelf()) {
+ if (ambientState.isAppearing() && !child.isAboveShelf() && !isBeforeTrackedHeadsUp) {
// Don't show none heads-up notifications while in appearing phase.
childViewState.yTranslation = Math.max(childViewState.yTranslation, shelfStart);
}
@@ -695,7 +713,8 @@ public class StackScrollAlgorithm {
}
childViewState.zTranslation = baseZ
+ childrenOnTop * zDistanceBetweenElements;
- } else if (i == 0 && (child.isAboveShelf() || child.showingPulsing())) {
+ } else if (child == ambientState.getTrackedHeadsUpRow()
+ || (i == 0 && (child.isAboveShelf() || child.showingPulsing()))) {
// In case this is a new view that has never been measured before, we don't want to
// elevate if we are currently expanded more then the notification
int shelfHeight = ambientState.getShelf() == null ? 0 :
@@ -703,7 +722,7 @@ public class StackScrollAlgorithm {
float shelfStart = ambientState.getInnerHeight()
- shelfHeight + ambientState.getTopPadding()
+ ambientState.getStackTranslation();
- float notificationEnd = childViewState.yTranslation + child.getPinnedHeadsUpHeight()
+ float notificationEnd = childViewState.yTranslation + child.getIntrinsicHeight()
+ mPaddingBetweenElements;
if (shelfStart > notificationEnd) {
childViewState.zTranslation = baseZ;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java
index 978394ca05ab..304fe0090e77 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java
@@ -17,9 +17,12 @@ package com.android.systemui.statusbar.phone;
import static android.view.Display.INVALID_DISPLAY;
+import android.app.ActivityManager;
+import android.content.ComponentName;
import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
-import android.database.ContentObserver;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.PointF;
@@ -27,15 +30,11 @@ import android.graphics.Region;
import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayManager.DisplayListener;
import android.hardware.input.InputManager;
-import android.net.Uri;
-import android.os.Handler;
import android.os.Looper;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.SystemProperties;
-import android.os.UserHandle;
import android.provider.DeviceConfig;
-import android.provider.Settings;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.TypedValue;
@@ -75,6 +74,8 @@ import com.android.systemui.tracing.nano.EdgeBackGestureHandlerProto;
import com.android.systemui.tracing.nano.SystemUiTraceProto;
import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
import java.util.concurrent.Executor;
/**
@@ -86,8 +87,6 @@ public class EdgeBackGestureHandler extends CurrentUserTracker implements Displa
private static final String TAG = "EdgeBackGestureHandler";
private static final int MAX_LONG_PRESS_TIMEOUT = SystemProperties.getInt(
"gestures.back_timeout", 250);
- private static final String FIXED_ROTATION_TRANSFORM_SETTING_NAME = "fixed_rotation_transform";
-
private ISystemGestureExclusionListener mGestureExclusionListener =
new ISystemGestureExclusionListener.Stub() {
@@ -113,17 +112,20 @@ public class EdgeBackGestureHandler extends CurrentUserTracker implements Displa
}
};
- private final ContentObserver mFixedRotationObserver = new ContentObserver(
- new Handler(Looper.getMainLooper())) {
+ private TaskStackChangeListener mTaskStackListener = new TaskStackChangeListener() {
@Override
- public void onChange(boolean selfChange, Uri uri) {
- updatedFixedRotation();
+ public void onTaskStackChanged() {
+ mGestureBlockingActivityRunning = isGestureBlockingActivityRunning();
}
};
private final Context mContext;
private final OverviewProxyService mOverviewProxyService;
- private PluginManager mPluginManager;
+ private final Runnable mStateChangeCallback;
+
+ private final PluginManager mPluginManager;
+ // Activities which should not trigger Back gesture.
+ private final List<ComponentName> mGestureBlockingActivities = new ArrayList<>();
private final Point mDisplaySize = new Point();
private final int mDisplayId;
@@ -147,7 +149,6 @@ public class EdgeBackGestureHandler extends CurrentUserTracker implements Displa
// We temporarily disable back gesture when user is quickswitching
// between apps of different orientations
private boolean mDisabledForQuickstep;
- private boolean mFixedRotationFlagEnabled;
private final PointF mDownPoint = new PointF();
private final PointF mEndPoint = new PointF();
@@ -162,6 +163,7 @@ public class EdgeBackGestureHandler extends CurrentUserTracker implements Displa
private boolean mIsEnabled;
private boolean mIsNavBarShownTransiently;
private boolean mIsBackGestureAllowed;
+ private boolean mGestureBlockingActivityRunning;
private InputMonitor mInputMonitor;
private InputEventReceiver mInputEventReceiver;
@@ -196,20 +198,45 @@ public class EdgeBackGestureHandler extends CurrentUserTracker implements Displa
};
public EdgeBackGestureHandler(Context context, OverviewProxyService overviewProxyService,
- SysUiState sysUiFlagContainer, PluginManager pluginManager) {
+ SysUiState sysUiFlagContainer, PluginManager pluginManager,
+ Runnable stateChangeCallback) {
super(Dependency.get(BroadcastDispatcher.class));
mContext = context;
mDisplayId = context.getDisplayId();
mMainExecutor = context.getMainExecutor();
mOverviewProxyService = overviewProxyService;
mPluginManager = pluginManager;
- Dependency.get(ProtoTracer.class).add(this);
+ mStateChangeCallback = stateChangeCallback;
+ ComponentName recentsComponentName = ComponentName.unflattenFromString(
+ context.getString(com.android.internal.R.string.config_recentsComponentName));
+ if (recentsComponentName != null) {
+ String recentsPackageName = recentsComponentName.getPackageName();
+ PackageManager manager = context.getPackageManager();
+ try {
+ Resources resources = manager.getResourcesForApplication(recentsPackageName);
+ int resId = resources.getIdentifier(
+ "gesture_blocking_activities", "array", recentsPackageName);
+
+ if (resId == 0) {
+ Log.e(TAG, "No resource found for gesture-blocking activities");
+ } else {
+ String[] gestureBlockingActivities = resources.getStringArray(resId);
+ for (String gestureBlockingActivity : gestureBlockingActivities) {
+ mGestureBlockingActivities.add(
+ ComponentName.unflattenFromString(gestureBlockingActivity));
+ }
+ }
+ } catch (NameNotFoundException e) {
+ Log.e(TAG, "Failed to add gesture blocking activities", e);
+ }
+ }
+ Dependency.get(ProtoTracer.class).add(this);
mLongPressTimeout = Math.min(MAX_LONG_PRESS_TIMEOUT,
ViewConfiguration.getLongPressTimeout());
mGestureNavigationSettingsObserver = new GestureNavigationSettingsObserver(
- mContext.getMainThreadHandler(), mContext, this::updateCurrentUserResources);
+ mContext.getMainThreadHandler(), mContext, this::onNavigationSettingsChanged);
updateCurrentUserResources();
sysUiFlagContainer.addCallback(sysUiFlags -> mSysUiFlags = sysUiFlags);
@@ -240,6 +267,14 @@ public class EdgeBackGestureHandler extends CurrentUserTracker implements Displa
mTouchSlop = ViewConfiguration.get(mContext).getScaledTouchSlop() * backGestureSlop;
}
+ private void onNavigationSettingsChanged() {
+ boolean wasBackAllowed = isHandlingGestures();
+ updateCurrentUserResources();
+ if (wasBackAllowed != isHandlingGestures()) {
+ mStateChangeCallback.run();
+ }
+ }
+
@Override
public void onUserSwitched(int newUserId) {
updateIsEnabled();
@@ -251,13 +286,7 @@ public class EdgeBackGestureHandler extends CurrentUserTracker implements Displa
*/
public void onNavBarAttached() {
mIsAttached = true;
- updatedFixedRotation();
- if (mFixedRotationFlagEnabled) {
- setRotationCallbacks(true);
- }
- mContext.getContentResolver().registerContentObserver(
- Settings.Global.getUriFor(FIXED_ROTATION_TRANSFORM_SETTING_NAME),
- false /* notifyForDescendants */, mFixedRotationObserver, UserHandle.USER_ALL);
+ mOverviewProxyService.addCallback(mQuickSwitchListener);
updateIsEnabled();
startTracking();
}
@@ -267,22 +296,11 @@ public class EdgeBackGestureHandler extends CurrentUserTracker implements Displa
*/
public void onNavBarDetached() {
mIsAttached = false;
- if (mFixedRotationFlagEnabled) {
- setRotationCallbacks(false);
- }
- mContext.getContentResolver().unregisterContentObserver(mFixedRotationObserver);
+ mOverviewProxyService.removeCallback(mQuickSwitchListener);
updateIsEnabled();
stopTracking();
}
- private void setRotationCallbacks(boolean enable) {
- if (enable) {
- mOverviewProxyService.addCallback(mQuickSwitchListener);
- } else {
- mOverviewProxyService.removeCallback(mQuickSwitchListener);
- }
- }
-
/**
* @see NavigationModeController.ModeChangedListener#onNavigationModeChanged
*/
@@ -324,6 +342,7 @@ public class EdgeBackGestureHandler extends CurrentUserTracker implements Displa
mGestureNavigationSettingsObserver.unregister();
mContext.getSystemService(DisplayManager.class).unregisterDisplayListener(this);
mPluginManager.removePluginListener(this);
+ ActivityManagerWrapper.getInstance().unregisterTaskStackListener(mTaskStackListener);
try {
WindowManagerGlobal.getWindowManagerService()
@@ -338,6 +357,7 @@ public class EdgeBackGestureHandler extends CurrentUserTracker implements Displa
updateDisplaySize();
mContext.getSystemService(DisplayManager.class).registerDisplayListener(this,
mContext.getMainThreadHandler());
+ ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskStackListener);
try {
WindowManagerGlobal.getWindowManagerService()
@@ -491,6 +511,7 @@ public class EdgeBackGestureHandler extends CurrentUserTracker implements Displa
mLogGesture = false;
mInRejectedExclusion = false;
mAllowGesture = !mDisabledForQuickstep && mIsBackGestureAllowed
+ && !mGestureBlockingActivityRunning
&& !QuickStepContract.isBackGestureDisabled(mSysUiFlags)
&& isWithinTouchRegion((int) ev.getX(), (int) ev.getY());
if (mAllowGesture) {
@@ -599,17 +620,6 @@ public class EdgeBackGestureHandler extends CurrentUserTracker implements Displa
InputManager.getInstance().injectInputEvent(ev, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
}
- private void updatedFixedRotation() {
- boolean oldFlag = mFixedRotationFlagEnabled;
- mFixedRotationFlagEnabled = Settings.Global.getInt(mContext.getContentResolver(),
- FIXED_ROTATION_TRANSFORM_SETTING_NAME, 0) != 0;
- if (oldFlag == mFixedRotationFlagEnabled) {
- return;
- }
-
- setRotationCallbacks(mFixedRotationFlagEnabled);
- }
-
public void setInsets(int leftInset, int rightInset) {
mLeftInset = leftInset;
mRightInset = rightInset;
@@ -633,6 +643,13 @@ public class EdgeBackGestureHandler extends CurrentUserTracker implements Displa
pw.println(" mEdgeWidthRight=" + mEdgeWidthRight);
}
+ private boolean isGestureBlockingActivityRunning() {
+ ActivityManager.RunningTaskInfo runningTask =
+ ActivityManagerWrapper.getInstance().getRunningTask();
+ ComponentName topActivity = runningTask == null ? null : runningTask.topActivity;
+ return topActivity != null && mGestureBlockingActivities.contains(topActivity);
+ }
+
@Override
public void writeToProto(SystemUiTraceProto proto) {
if (proto.edgeBackGestureHandler == null) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index ae7867d68af4..b47c59acb82d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -125,6 +125,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
private KeyguardAffordanceView mRightAffordanceView;
private KeyguardAffordanceView mLeftAffordanceView;
private ViewGroup mIndicationArea;
+ private TextView mEnterpriseDisclosure;
private TextView mIndicationText;
private ViewGroup mPreviewContainer;
private ViewGroup mOverlayContainer;
@@ -238,6 +239,8 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
mRightAffordanceView = findViewById(R.id.camera_button);
mLeftAffordanceView = findViewById(R.id.left_button);
mIndicationArea = findViewById(R.id.keyguard_indication_area);
+ mEnterpriseDisclosure = findViewById(
+ R.id.keyguard_indication_enterprise_disclosure);
mIndicationText = findViewById(R.id.keyguard_indication_text);
mIndicationBottomMargin = getResources().getDimensionPixelSize(
R.dimen.keyguard_indication_margin_bottom);
@@ -315,6 +318,9 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
}
// Respect font size setting.
+ mEnterpriseDisclosure.setTextSize(TypedValue.COMPLEX_UNIT_PX,
+ getResources().getDimensionPixelSize(
+ com.android.internal.R.dimen.text_size_small_material));
mIndicationText.setTextSize(TypedValue.COMPLEX_UNIT_PX,
getResources().getDimensionPixelSize(
com.android.internal.R.dimen.text_size_small_material));
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenGestureLogger.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenGestureLogger.java
index 83d398d3e7ae..0d6597f1b11b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenGestureLogger.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenGestureLogger.java
@@ -39,7 +39,7 @@ import javax.inject.Singleton;
public class LockscreenGestureLogger {
/**
- * Contains Lockscreen related Westworld UiEvent enums.
+ * Contains Lockscreen related statsd UiEvent enums.
*/
public enum LockscreenUiEvent implements UiEventLogger.UiEventEnum {
@UiEvent(doc = "Lockscreen > Pull shade open")
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
index 11022bbcb7ea..27daf8615a31 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
@@ -25,6 +25,7 @@ import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
import static android.view.InsetsState.containsType;
import static android.view.WindowInsetsController.APPEARANCE_LOW_PROFILE_BARS;
import static android.view.WindowInsetsController.APPEARANCE_OPAQUE_NAVIGATION_BARS;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
@@ -152,8 +153,6 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
private static final String EXTRA_DISABLE2_STATE = "disabled2_state";
private static final String EXTRA_APPEARANCE = "appearance";
private static final String EXTRA_TRANSIENT_STATE = "transient_state";
- private static final String FIXED_ROTATION_TRANSFORM_SETTING_NAME = "fixed_rotation_transform";
-
/** Allow some time inbetween the long press for back and recents. */
private static final int LOCK_TO_APP_GESTURE_TOLERENCE = 200;
@@ -221,13 +220,13 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
* original handle hidden and we'll flip the visibilities once the
* {@link #mTasksFrozenListener} fires
*/
- private VerticalNavigationHandle mOrientationHandle;
+ private QuickswitchOrientedNavHandle mOrientationHandle;
private WindowManager.LayoutParams mOrientationParams;
- private int mStartingQuickSwitchRotation;
+ private int mStartingQuickSwitchRotation = -1;
private int mCurrentRotation;
- private boolean mFixedRotationEnabled;
private ViewTreeObserver.OnGlobalLayoutListener mOrientationHandleGlobalLayoutListener;
private UiEventLogger mUiEventLogger;
+ private boolean mShowOrientedHandleForImmersiveMode;
@com.android.internal.annotations.VisibleForTesting
public enum NavBarActionEvent implements UiEventLogger.UiEventEnum {
@@ -299,6 +298,9 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
@Override
public void onQuickSwitchToNewTask(@Surface.Rotation int rotation) {
mStartingQuickSwitchRotation = rotation;
+ if (rotation == -1) {
+ mShowOrientedHandleForImmersiveMode = false;
+ }
orientSecondaryHomeHandle();
}
@@ -323,6 +325,20 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
buttonDispatcher.setAlpha(forceVisible ? 1f : alpha, animate);
}
}
+
+ @Override
+ public void onOverviewShown(boolean fromHome) {
+ // If the overview has fixed orientation that may change display to natural rotation,
+ // we don't want the user rotation to be reset. So after user returns to application,
+ // it can keep in the original rotation.
+ mNavigationBarView.getRotationButtonController().setSkipOverrideUserLockPrefsOnce();
+ }
+
+ @Override
+ public void onToggleRecentApps() {
+ // The same case as onOverviewShown but only for 3-button navigation.
+ mNavigationBarView.getRotationButtonController().setSkipOverrideUserLockPrefsOnce();
+ }
};
private NavigationBarTransitions.DarkIntensityListener mOrientationHandleIntensityListener =
@@ -356,14 +372,6 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
}
};
- private final ContentObserver mFixedRotationObserver = new ContentObserver(
- new Handler(Looper.getMainLooper())) {
- @Override
- public void onChange(boolean selfChange, Uri uri) {
- updatedFixedRotation();
- }
- };
-
private final DeviceConfig.OnPropertiesChangedListener mOnPropertiesChangedListener =
new DeviceConfig.OnPropertiesChangedListener() {
@Override
@@ -425,10 +433,6 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
Settings.Secure.getUriFor(Settings.Secure.ASSISTANT),
false /* notifyForDescendants */, mAssistContentObserver, UserHandle.USER_ALL);
- mContentResolver.registerContentObserver(
- Settings.Global.getUriFor(FIXED_ROTATION_TRANSFORM_SETTING_NAME),
- false /* notifyForDescendants */, mFixedRotationObserver, UserHandle.USER_ALL);
-
if (savedInstanceState != null) {
mDisabledFlags1 = savedInstanceState.getInt(EXTRA_DISABLE_STATE, 0);
mDisabledFlags2 = savedInstanceState.getInt(EXTRA_DISABLE2_STATE, 0);
@@ -454,7 +458,6 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
mNavigationModeController.removeListener(this);
mAccessibilityManagerWrapper.removeCallback(mAccessibilityListener);
mContentResolver.unregisterContentObserver(mAssistContentObserver);
- mContentResolver.unregisterContentObserver(mFixedRotationObserver);
DeviceConfig.removeOnPropertiesChangedListener(mOnPropertiesChangedListener);
}
@@ -485,7 +488,6 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
}
mNavigationBarView.setNavigationIconHints(mNavigationIconHints);
mNavigationBarView.setWindowVisible(isNavBarWindowVisible());
- updatedFixedRotation();
prepareNavigationBarView();
checkNavBarModes();
@@ -588,7 +590,7 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
getContext().getSystemService(DisplayManager.class)
.registerDisplayListener(this, new Handler(Looper.getMainLooper()));
- mOrientationHandle = new VerticalNavigationHandle(getContext());
+ mOrientationHandle = new QuickswitchOrientedNavHandle(getContext());
getBarTransitions().addDarkIntensityListener(mOrientationHandleIntensityListener);
mOrientationParams = new WindowManager.LayoutParams(0, 0,
@@ -599,8 +601,11 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
| WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
| WindowManager.LayoutParams.FLAG_SLIPPERY,
PixelFormat.TRANSLUCENT);
+ mOrientationParams.setTitle("SecondaryHomeHandle" + getContext().getDisplayId());
+ mOrientationParams.privateFlags |= PRIVATE_FLAG_NO_MOVE_ANIMATION;
mWindowManager.addView(mOrientationHandle, mOrientationParams);
mOrientationHandle.setVisibility(View.GONE);
+ mOrientationParams.setFitInsetsTypes(0 /* types*/);
mOrientationHandleGlobalLayoutListener =
() -> {
if (mStartingQuickSwitchRotation == -1) {
@@ -637,22 +642,28 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
int height = 0;
int width = 0;
Rect dispSize = mWindowManager.getCurrentWindowMetrics().getBounds();
+ mOrientationHandle.setDeltaRotation(deltaRotation);
switch (deltaRotation) {
case Surface.ROTATION_90:
case Surface.ROTATION_270:
height = dispSize.height();
- width = getResources()
- .getDimensionPixelSize(R.dimen.navigation_bar_height);
+ width = mNavigationBarView.getHeight();
break;
case Surface.ROTATION_180:
case Surface.ROTATION_0:
// TODO(b/152683657): Need to determine best UX for this
- resetSecondaryHandle();
- return;
+ if (!mShowOrientedHandleForImmersiveMode) {
+ resetSecondaryHandle();
+ return;
+ }
+ width = dispSize.width();
+ height = mNavigationBarView.getHeight();
+ break;
}
mOrientationParams.gravity =
- deltaRotation == Surface.ROTATION_90 ? Gravity.LEFT : Gravity.RIGHT;
+ deltaRotation == Surface.ROTATION_0 ? Gravity.BOTTOM :
+ (deltaRotation == Surface.ROTATION_90 ? Gravity.LEFT : Gravity.RIGHT);
mOrientationParams.height = height;
mOrientationParams.width = width;
mWindowManager.updateViewLayout(mOrientationHandle, mOrientationParams);
@@ -679,14 +690,6 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
return delta;
}
- private void updatedFixedRotation() {
- mFixedRotationEnabled = Settings.Global.getInt(mContentResolver,
- FIXED_ROTATION_TRANSFORM_SETTING_NAME, 0) != 0;
- if (!canShowSecondaryHandle()) {
- resetSecondaryHandle();
- }
- }
-
@Override
public void dump(String prefix, FileDescriptor fd, PrintWriter pw, String[] args) {
if (mNavigationBarView != null) {
@@ -754,6 +757,11 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
&& mNavigationBarWindowState != state) {
mNavigationBarWindowState = state;
updateSystemUiStateFlags(-1);
+ mShowOrientedHandleForImmersiveMode = state == WINDOW_STATE_HIDDEN;
+ if (mOrientationHandle != null
+ && mStartingQuickSwitchRotation != -1) {
+ orientSecondaryHomeHandle();
+ }
if (DEBUG_WINDOW_STATE) Log.d(TAG, "Navigation bar " + windowStateToString(state));
if (mNavigationBarView != null) {
@@ -1395,7 +1403,7 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
}
private boolean canShowSecondaryHandle() {
- return mFixedRotationEnabled && mNavBarMode == NAV_BAR_MODE_GESTURAL;
+ return mNavBarMode == NAV_BAR_MODE_GESTURAL;
}
private final Consumer<Integer> mRotationWatcher = rotation -> {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java
index 1a6d3d770f9f..1f509549efd1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java
@@ -57,7 +57,6 @@ public final class NavigationBarTransitions extends BarTransitions implements
}
private final NavigationBarView mView;
- private final IStatusBarService mBarService;
private final LightBarTransitionsController mLightTransitionsController;
private final boolean mAllowAutoDimWallpaperNotVisible;
private boolean mWallpaperVisible;
@@ -82,8 +81,6 @@ public final class NavigationBarTransitions extends BarTransitions implements
public NavigationBarTransitions(NavigationBarView view, CommandQueue commandQueue) {
super(view, R.drawable.nav_background);
mView = view;
- mBarService = IStatusBarService.Stub.asInterface(
- ServiceManager.getService(Context.STATUS_BAR_SERVICE));
mLightTransitionsController = new LightBarTransitionsController(
view.getContext(), this, commandQueue);
mAllowAutoDimWallpaperNotVisible = view.getContext().getResources()
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index 4821d8c46ed4..1eab427b4155 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -74,6 +74,7 @@ import com.android.systemui.recents.RecentsOnboarding;
import com.android.systemui.shared.plugins.PluginManager;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.QuickStepContract;
+import com.android.systemui.shared.system.SysUiStatsLog;
import com.android.systemui.shared.system.WindowManagerWrapper;
import com.android.systemui.stackdivider.Divider;
import com.android.systemui.statusbar.CommandQueue;
@@ -140,6 +141,7 @@ public class NavigationBarView extends FrameLayout implements
private boolean mInCarMode = false;
private boolean mDockedStackExists;
private boolean mImeVisible;
+ private boolean mScreenOn = true;
private final SparseArray<ButtonDispatcher> mButtonDispatchers = new SparseArray<>();
private final ContextualButtonGroup mContextualButtonGroup;
@@ -324,8 +326,8 @@ public class NavigationBarView extends FrameLayout implements
mNavColorSampleMargin = getResources()
.getDimensionPixelSize(R.dimen.navigation_handle_sample_horizontal_margin);
- mEdgeBackGestureHandler = new EdgeBackGestureHandler(
- context, mOverviewProxyService, mSysUiFlagContainer, mPluginManager);
+ mEdgeBackGestureHandler = new EdgeBackGestureHandler(context, mOverviewProxyService,
+ mSysUiFlagContainer, mPluginManager, this::updateStates);
mRegionSamplingHelper = new RegionSamplingHelper(this,
new RegionSamplingHelper.SamplingCallback() {
@Override
@@ -371,6 +373,11 @@ public class NavigationBarView extends FrameLayout implements
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
+ if (isGesturalMode(mNavBarMode) && mImeVisible
+ && event.getAction() == MotionEvent.ACTION_DOWN) {
+ SysUiStatsLog.write(SysUiStatsLog.IME_TOUCH_REPORTED,
+ (int) event.getX(), (int) event.getY());
+ }
return shouldDeadZoneConsumeTouchEvents(event) || super.onInterceptTouchEvent(event);
}
@@ -573,6 +580,7 @@ public class NavigationBarView extends FrameLayout implements
/** To be called when screen lock/unlock state changes */
public void onScreenStateChanged(boolean isScreenOn) {
+ mScreenOn = isScreenOn;
if (isScreenOn) {
if (isGesturalModeOnDefaultDisplay(getContext(), mNavBarMode)) {
mRegionSamplingHelper.start(mSamplingBounds);
@@ -822,7 +830,7 @@ public class NavigationBarView extends FrameLayout implements
*/
public void updateSlippery() {
setSlippery(!isQuickStepSwipeUpEnabled() ||
- (mPanelView.isFullyExpanded() && !mPanelView.isCollapsing()));
+ (mPanelView != null && mPanelView.isFullyExpanded() && !mPanelView.isCollapsing()));
}
private void setSlippery(boolean slippery) {
@@ -1217,6 +1225,7 @@ public class NavigationBarView extends FrameLayout implements
dumpButton(pw, "a11y", getAccessibilityButton());
pw.println(" }");
+ pw.println(" mScreenOn: " + mScreenOn);
if (mNavigationInflaterView != null) {
mNavigationInflaterView.dump(pw);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
index 9e7bf6220546..f2eec39ed17e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -443,6 +443,7 @@ public class NotificationPanelViewController extends PanelViewController {
*/
private boolean mDelayShowingKeyguardStatusBar;
+ private boolean mAnimatingQS;
private int mOldLayoutDirection;
private View.AccessibilityDelegate mAccessibilityDelegate = new View.AccessibilityDelegate() {
@@ -1328,11 +1329,15 @@ public class NotificationPanelViewController extends PanelViewController {
*
* @param velocity unit is in px / millis
*/
- public void stopWaitingForOpenPanelGesture(final float velocity) {
+ public void stopWaitingForOpenPanelGesture(boolean cancel, final float velocity) {
if (mExpectingSynthesizedDown) {
mExpectingSynthesizedDown = false;
- maybeVibrateOnOpening();
- fling(velocity > 1f ? 1000f * velocity : 0, true /* expand */);
+ if (cancel) {
+ collapse(false /* delayed */, 1.0f /* speedUpFactor */);
+ } else {
+ maybeVibrateOnOpening();
+ fling(velocity > 1f ? 1000f * velocity : 0, true /* expand */);
+ }
onTrackingStopped(false);
}
}
@@ -1856,6 +1861,7 @@ public class NotificationPanelViewController extends PanelViewController {
@Override
public void onAnimationEnd(Animator animation) {
+ mAnimatingQS = false;
notifyExpandingFinished();
mNotificationStackScroller.resetCheckSnoozeLeavebehind();
mQsExpansionAnimator = null;
@@ -1864,6 +1870,9 @@ public class NotificationPanelViewController extends PanelViewController {
}
}
});
+ // Let's note that we're animating QS. Moving the animator here will cancel it immediately,
+ // so we need a separate flag.
+ mAnimatingQS = true;
animator.start();
mQsExpansionAnimator = animator;
mQsAnimatorExpand = expanding;
@@ -2216,6 +2225,9 @@ public class NotificationPanelViewController extends PanelViewController {
mNotificationStackScroller.onExpansionStarted();
mIsExpanding = true;
mQsExpandedWhenExpandingStarted = mQsFullyExpanded;
+ mMediaHierarchyManager.setCollapsingShadeFromQS(mQsExpandedWhenExpandingStarted &&
+ /* We also start expanding when flinging closed Qs. Let's exclude that */
+ !mAnimatingQS);
if (mQsExpanded) {
onQsExpansionStarted();
}
@@ -2232,6 +2244,7 @@ public class NotificationPanelViewController extends PanelViewController {
mHeadsUpManager.onExpandingFinished();
mConversationNotificationManager.onNotificationPanelExpandStateChanged(isFullyCollapsed());
mIsExpanding = false;
+ mMediaHierarchyManager.setCollapsingShadeFromQS(false);
if (isFullyCollapsed()) {
DejankUtils.postAfterTraversal(new Runnable() {
@Override
@@ -2393,8 +2406,8 @@ public class NotificationPanelViewController extends PanelViewController {
}
@Override
- protected int getClearAllHeight() {
- return mNotificationStackScroller.getFooterViewHeight();
+ protected int getClearAllHeightWithPadding() {
+ return mNotificationStackScroller.getFooterViewHeightWithPadding();
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
index a902e1b0c960..caddc4a874f4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
@@ -537,9 +537,9 @@ public abstract class PanelViewController {
// the animation only to the last notification, and then jump to the maximum panel height so
// clear all just fades in and the decelerating motion is towards the last notification.
final boolean clearAllExpandHack = expand &&
- shouldExpandToTopOfClearAll(getMaxPanelHeight() - getClearAllHeight());
+ shouldExpandToTopOfClearAll(getMaxPanelHeight() - getClearAllHeightWithPadding());
if (clearAllExpandHack) {
- target = getMaxPanelHeight() - getClearAllHeight();
+ target = getMaxPanelHeight() - getClearAllHeightWithPadding();
}
if (target == mExpandedHeight || getOverExpansionAmount() > 0f && expand) {
notifyExpandingFinished();
@@ -1030,9 +1030,9 @@ public abstract class PanelViewController {
protected abstract boolean isClearAllVisible();
/**
- * @return the height of the clear all button, in pixels
+ * @return the height of the clear all button, in pixels including padding
*/
- protected abstract int getClearAllHeight();
+ protected abstract int getClearAllHeightWithPadding();
public void setHeadsUpManager(HeadsUpManagerPhone headsUpManager) {
mHeadsUpManager = headsUpManager;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
index a065b74bda99..06d35a36e3c4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -38,6 +38,7 @@ import android.service.notification.ZenModeConfig;
import android.telecom.TelecomManager;
import android.text.format.DateFormat;
import android.util.Log;
+import android.view.View;
import androidx.lifecycle.Observer;
@@ -677,12 +678,18 @@ public class PhoneStatusBarPolicy
}
mIconController.setIcon(mSlotScreenRecord, resourceId, description);
mIconController.setIconVisibility(mSlotScreenRecord, true);
+ // Set as assertive so talkback will announce the countdown
+ mIconController.setIconAccessibilityLiveRegion(mSlotScreenRecord,
+ View.ACCESSIBILITY_LIVE_REGION_ASSERTIVE);
}
@Override
public void onCountdownEnd() {
if (DEBUG) Log.d(TAG, "screenrecord: hiding icon during countdown");
mHandler.post(() -> mIconController.setIconVisibility(mSlotScreenRecord, false));
+ // Reset talkback priority
+ mIconController.setIconAccessibilityLiveRegion(mSlotScreenRecord,
+ View.ACCESSIBILITY_LIVE_REGION_NONE);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/VerticalNavigationHandle.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickswitchOrientedNavHandle.java
index 0cdf1d32d6a0..fe74677a8d51 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/VerticalNavigationHandle.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickswitchOrientedNavHandle.java
@@ -19,19 +19,25 @@ package com.android.systemui.statusbar.phone;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.RectF;
+import android.view.Surface;
import com.android.systemui.R;
/** Temporarily shown view when using QuickSwitch to switch between apps of different rotations */
-public class VerticalNavigationHandle extends NavigationHandle {
+public class QuickswitchOrientedNavHandle extends NavigationHandle {
private final int mWidth;
private final RectF mTmpBoundsRectF = new RectF();
+ private @Surface.Rotation int mDeltaRotation;
- public VerticalNavigationHandle(Context context) {
+ public QuickswitchOrientedNavHandle(Context context) {
super(context);
mWidth = context.getResources().getDimensionPixelSize(R.dimen.navigation_home_handle_width);
}
+ void setDeltaRotation(@Surface.Rotation int rotation) {
+ mDeltaRotation = rotation;
+ }
+
@Override
protected void onDraw(Canvas canvas) {
canvas.drawRoundRect(computeHomeHandleBounds(), mRadius, mRadius, mPaint);
@@ -42,12 +48,32 @@ public class VerticalNavigationHandle extends NavigationHandle {
int top;
int bottom;
int right;
- int topStart = getLocationOnScreen()[1];
int radiusOffset = mRadius * 2;
- right = getWidth() - mBottom;
- top = getHeight() / 2 - (mWidth / 2) - (topStart / 2);
- left = getWidth() - mBottom - radiusOffset;
- bottom = top + mWidth;
+ int topStart = getLocationOnScreen()[1];
+
+ switch (mDeltaRotation) {
+ default:
+ case Surface.ROTATION_0:
+ case Surface.ROTATION_180:
+ int height = mRadius * 2;
+ left = getWidth() / 2 - mWidth / 2;
+ top = (getHeight() - mBottom - height);
+ right = getWidth() / 2 + mWidth / 2;
+ bottom = top + height;
+ break;
+ case Surface.ROTATION_90:
+ left = mBottom;
+ right = left + radiusOffset;
+ top = getHeight() / 2 - (mWidth / 2) - (topStart / 2);
+ bottom = top + mWidth;
+ break;
+ case Surface.ROTATION_270:
+ right = getWidth() - mBottom;
+ left = right - radiusOffset;
+ top = getHeight() / 2 - (mWidth / 2) - (topStart / 2);
+ bottom = top + mWidth;
+ break;
+ }
mTmpBoundsRectF.set(left, top, right, bottom);
return mTmpBoundsRectF;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/RegionSamplingHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/RegionSamplingHelper.java
index bf52a7ae2bf9..3c8aa86dd209 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/RegionSamplingHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/RegionSamplingHelper.java
@@ -41,7 +41,6 @@ public class RegionSamplingHelper implements View.OnAttachStateChangeListener,
private final View mSampledView;
private final CompositionSamplingListener mSamplingListener;
- private final Runnable mUpdateSamplingListener = this::updateSamplingListener;
/**
* The requested sampling bounds that we want to sample from
@@ -59,6 +58,7 @@ public class RegionSamplingHelper implements View.OnAttachStateChangeListener,
private float mLastMedianLuma;
private float mCurrentMedianLuma;
private boolean mWaitingOnDraw;
+ private boolean mIsDestroyed;
// Passing the threshold of this luminance value will make the button black otherwise white
private final float mLuminanceThreshold;
@@ -130,6 +130,7 @@ public class RegionSamplingHelper implements View.OnAttachStateChangeListener,
void stopAndDestroy() {
stop();
mSamplingListener.destroy();
+ mIsDestroyed = true;
}
@Override
@@ -229,12 +230,17 @@ public class RegionSamplingHelper implements View.OnAttachStateChangeListener,
pw.println(" sampleView isAttached: " + mSampledView.isAttachedToWindow());
pw.println(" sampleView isScValid: " + (mSampledView.isAttachedToWindow()
? mSampledView.getViewRootImpl().getSurfaceControl().isValid()
- : "false"));
+ : "notAttached"));
+ pw.println(" mSamplingEnabled: " + mSamplingEnabled);
pw.println(" mSamplingListenerRegistered: " + mSamplingListenerRegistered);
pw.println(" mSamplingRequestBounds: " + mSamplingRequestBounds);
+ pw.println(" mRegisteredSamplingBounds: " + mRegisteredSamplingBounds);
pw.println(" mLastMedianLuma: " + mLastMedianLuma);
pw.println(" mCurrentMedianLuma: " + mCurrentMedianLuma);
pw.println(" mWindowVisible: " + mWindowVisible);
+ pw.println(" mWaitingOnDraw: " + mWaitingOnDraw);
+ pw.println(" mRegisteredStopLayer: " + mRegisteredStopLayer);
+ pw.println(" mIsDestroyed: " + mIsDestroyed);
}
public interface SamplingCallback {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationButtonController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationButtonController.java
index de9c745cb357..59b10e416b03 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationButtonController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationButtonController.java
@@ -74,6 +74,7 @@ public class RotationButtonController {
private Consumer<Integer> mRotWatcherListener;
private boolean mListenersRegistered = false;
private boolean mIsNavigationBarShowing;
+ private boolean mSkipOverrideUserLockPrefsOnce;
private final Runnable mRemoveRotationProposal =
() -> setRotateSuggestionButtonState(false /* visible */);
@@ -349,7 +350,20 @@ public class RotationButtonController {
mUiEventLogger.log(RotationButtonEvent.ROTATION_SUGGESTION_SHOWN);
}
+ /**
+ * Makes {@link #shouldOverrideUserLockPrefs} always return {@code false} once. It is used to
+ * avoid losing original user rotation when display rotation is changed by entering the fixed
+ * orientation overview.
+ */
+ void setSkipOverrideUserLockPrefsOnce() {
+ mSkipOverrideUserLockPrefsOnce = true;
+ }
+
private boolean shouldOverrideUserLockPrefs(final int rotation) {
+ if (mSkipOverrideUserLockPrefsOnce) {
+ mSkipOverrideUserLockPrefsOnce = false;
+ return false;
+ }
// Only override user prefs when returning to the natural rotation (normally portrait).
// Don't let apps that force landscape or 180 alter user lock.
return rotation == NATURAL_ROTATION;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index 00eab952c504..60fc17d9474a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -113,6 +113,12 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, OnCo
* Scrim opacity when the phone is about to wake-up.
*/
public static final float WAKE_SENSOR_SCRIM_ALPHA = 0.6f;
+
+ /**
+ * Scrim opacity when bubbles are expanded.
+ */
+ public static final float BUBBLE_SCRIM_ALPHA = 0.6f;
+
/**
* The default scrim under the shade and dialogs.
* This should not be lower than 0.54, otherwise we won't pass GAR.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
index ade642c5ea9a..2db36f4a62f8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
@@ -235,7 +235,7 @@ public enum ScrimState {
mFrontAlpha = 0f;
mBehindAlpha = mDefaultScrimAlpha;
- mBubbleAlpha = mDefaultScrimAlpha;
+ mBubbleAlpha = ScrimController.BUBBLE_SCRIM_ALPHA;
mAnimationDuration = ScrimController.ANIMATION_DURATION;
mBlankScreen = false;
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 e2714af33247..a21ca5320518 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -1772,6 +1772,9 @@ public class StatusBar extends SystemUI implements DemoMode,
}
public void setPanelExpanded(boolean isExpanded) {
+ if (mPanelExpanded != isExpanded) {
+ mNotificationLogger.onPanelExpandedChanged(isExpanded);
+ }
mPanelExpanded = isExpanded;
updateHideIconsForBouncer(false /* animate */);
mNotificationShadeWindowController.setPanelExpanded(isExpanded);
@@ -2090,7 +2093,7 @@ public class StatusBar extends SystemUI implements DemoMode,
/**
* Called when another window is about to transfer it's input focus.
*/
- public void onInputFocusTransfer(boolean start, float velocity) {
+ public void onInputFocusTransfer(boolean start, boolean cancel, float velocity) {
if (!mCommandQueue.panelsEnabled()) {
return;
}
@@ -2098,7 +2101,7 @@ public class StatusBar extends SystemUI implements DemoMode,
if (start) {
mNotificationPanelViewController.startWaitingForOpenPanelGesture();
} else {
- mNotificationPanelViewController.stopWaitingForOpenPanelGesture(velocity);
+ mNotificationPanelViewController.stopWaitingForOpenPanelGesture(cancel, velocity);
}
}
@@ -2878,7 +2881,6 @@ public class StatusBar extends SystemUI implements DemoMode,
}
// Visibility reporting
-
protected void handleVisibleToUserChanged(boolean visibleToUser) {
if (visibleToUser) {
handleVisibleToUserChangedImpl(visibleToUser);
@@ -2900,12 +2902,12 @@ public class StatusBar extends SystemUI implements DemoMode,
}
}
- /**
- * The LEDs are turned off when the notification panel is shown, even just a little bit.
- * See also StatusBar.setPanelExpanded for another place where we attempt to do this.
- */
- private void handleVisibleToUserChangedImpl(boolean visibleToUser) {
+ // Visibility reporting
+
+ void handleVisibleToUserChangedImpl(boolean visibleToUser) {
if (visibleToUser) {
+ /* The LEDs are turned off when the notification panel is shown, even just a little bit.
+ * See also StatusBar.setPanelExpanded for another place where we attempt to do this. */
boolean pinnedHeadsUp = mHeadsUpManager.hasPinnedHeadsUp();
boolean clearNotificationEffects =
!mPresenter.isPresenterFullyCollapsed() &&
@@ -3982,7 +3984,7 @@ public class StatusBar extends SystemUI implements DemoMode,
} else if (mIsKeyguard && !unlocking) {
mScrimController.transitionTo(ScrimState.KEYGUARD);
} else if (mBubbleController.isStackExpanded()) {
- mScrimController.transitionTo(ScrimState.BUBBLE_EXPANDED);
+ mScrimController.transitionTo(ScrimState.BUBBLE_EXPANDED, mUnlockScrimCallback);
} else {
mScrimController.transitionTo(ScrimState.UNLOCKED, mUnlockScrimCallback);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
index 75da5d123972..93df14f18fda 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
@@ -67,6 +67,15 @@ public interface StatusBarIconController {
public void setSignalIcon(String slot, WifiIconState state);
public void setMobileIcons(String slot, List<MobileIconState> states);
public void setIconVisibility(String slot, boolean b);
+
+ /**
+ * Sets the live region mode for the icon
+ * @see android.view.View#setAccessibilityLiveRegion(int)
+ * @param slot Icon slot to set region for
+ * @param accessibilityLiveRegion live region mode for the icon
+ */
+ void setIconAccessibilityLiveRegion(String slot, int accessibilityLiveRegion);
+
/**
* If you don't know what to pass for `tag`, either remove all icons for slot, or use
* TAG_PRIMARY to refer to the first icon at a given slot.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java
index bfcbceaef9af..d0e806769f14 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java
@@ -265,6 +265,22 @@ public class StatusBarIconControllerImpl extends StatusBarIconList implements Tu
handleSet(index, holder);
}
+ @Override
+ public void setIconAccessibilityLiveRegion(String slotName, int accessibilityLiveRegion) {
+ Slot slot = getSlot(slotName);
+ if (!slot.hasIconsInSlot()) {
+ return;
+ }
+
+ int slotIndex = getSlotIndex(slotName);
+ List<StatusBarIconHolder> iconsToUpdate = slot.getHolderListInViewOrder();
+ for (StatusBarIconHolder holder : iconsToUpdate) {
+ int viewIndex = getViewIndex(slotIndex, holder.getTag());
+ mIconGroups.forEach(l -> l.mGroup.getChildAt(viewIndex)
+ .setAccessibilityLiveRegion(accessibilityLiveRegion));
+ }
+ }
+
public void removeIcon(String slot) {
removeAllIconsForSlot(slot);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index bc94cdeba37f..81d0699a29e6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -460,6 +460,18 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
}
@Override
+ public void onStartedWakingUp() {
+ mStatusBar.getNotificationShadeWindowView().getWindowInsetsController()
+ .setAnimationsDisabled(false);
+ }
+
+ @Override
+ public void onStartedGoingToSleep() {
+ mStatusBar.getNotificationShadeWindowView().getWindowInsetsController()
+ .setAnimationsDisabled(true);
+ }
+
+ @Override
public void onFinishedGoingToSleep() {
mBouncer.onScreenTurnedOff();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonRipple.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonRipple.java
index c929243085d6..2d8784dc41bd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonRipple.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonRipple.java
@@ -28,7 +28,7 @@ import android.graphics.PixelFormat;
import android.graphics.RecordingCanvas;
import android.graphics.drawable.Drawable;
import android.os.Handler;
-import android.util.Log;
+import android.os.Trace;
import android.view.RenderNodeAnimator;
import android.view.View;
import android.view.ViewConfiguration;
@@ -74,6 +74,11 @@ public class KeyButtonRipple extends Drawable {
private final HashSet<Animator> mRunningAnimations = new HashSet<>();
private final ArrayList<Animator> mTmpArray = new ArrayList<>();
+ private final TraceAnimatorListener mExitHwTraceAnimator =
+ new TraceAnimatorListener("exitHardware");
+ private final TraceAnimatorListener mEnterHwTraceAnimator =
+ new TraceAnimatorListener("enterHardware");
+
public enum Type {
OVAL,
ROUNDED_RECT
@@ -221,7 +226,7 @@ public class KeyButtonRipple extends Drawable {
@Override
public void jumpToCurrentState() {
- cancelAnimations("jumpToCurrentState");
+ endAnimations("jumpToCurrentState", false /* cancel */);
}
@Override
@@ -235,7 +240,6 @@ public class KeyButtonRipple extends Drawable {
}
public void setPressed(boolean pressed) {
- Log.d("b/63783866", "KeyButtonRipple.setPressed: pressed=" + pressed);
if (mDark != mLastDark && pressed) {
mRipplePaint = null;
mLastDark = mDark;
@@ -255,14 +259,19 @@ public class KeyButtonRipple extends Drawable {
mHandler.removeCallbacksAndMessages(null);
}
- private void cancelAnimations(String reason) {
- Log.d("b/63783866", "KeyButtonRipple.cancelAnimations: reason=" + reason);
+ private void endAnimations(String reason, boolean cancel) {
+ Trace.beginSection("KeyButtonRipple.endAnim: reason=" + reason + " cancel=" + cancel);
+ Trace.endSection();
mVisible = false;
mTmpArray.addAll(mRunningAnimations);
int size = mTmpArray.size();
for (int i = 0; i < size; i++) {
Animator a = mTmpArray.get(i);
- a.cancel();
+ if (cancel) {
+ a.cancel();
+ } else {
+ a.end();
+ }
}
mTmpArray.clear();
mRunningAnimations.clear();
@@ -287,7 +296,7 @@ public class KeyButtonRipple extends Drawable {
}
private void enterSoftware() {
- cancelAnimations("enterSoftware");
+ endAnimations("enterSoftware", true /* cancel */);
mVisible = true;
mGlowAlpha = getMaxGlowAlpha();
ObjectAnimator scaleAnimator = ObjectAnimator.ofFloat(this, "glowScale",
@@ -373,8 +382,7 @@ public class KeyButtonRipple extends Drawable {
}
private void enterHardware() {
- Log.d("b/63783866", "enterHardware");
- cancelAnimations("enterHardware");
+ endAnimations("enterHardware", true /* cancel */);
mVisible = true;
mDrawingHardwareGlow = true;
setExtendStart(CanvasProperty.createFloat(getExtendSize() / 2));
@@ -391,6 +399,7 @@ public class KeyButtonRipple extends Drawable {
endAnim.setDuration(ANIMATION_DURATION_SCALE);
endAnim.setInterpolator(mInterpolator);
endAnim.addListener(mAnimatorListener);
+ endAnim.addListener(mEnterHwTraceAnimator);
endAnim.setTarget(mTargetView);
if (isHorizontal()) {
@@ -426,13 +435,13 @@ public class KeyButtonRipple extends Drawable {
}
private void exitHardware() {
- Log.d("b/63783866", "exitHardware");
mPaintProp = CanvasProperty.createPaint(getRipplePaint());
final RenderNodeAnimator opacityAnim = new RenderNodeAnimator(mPaintProp,
RenderNodeAnimator.PAINT_ALPHA, 0);
opacityAnim.setDuration(ANIMATION_DURATION_FADE);
opacityAnim.setInterpolator(Interpolators.ALPHA_OUT);
opacityAnim.addListener(mAnimatorListener);
+ opacityAnim.addListener(mExitHwTraceAnimator);
opacityAnim.setTarget(mTargetView);
opacityAnim.start();
@@ -443,16 +452,41 @@ public class KeyButtonRipple extends Drawable {
private final AnimatorListenerAdapter mAnimatorListener =
new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mRunningAnimations.remove(animation);
+ if (mRunningAnimations.isEmpty() && !mPressed) {
+ mVisible = false;
+ mDrawingHardwareGlow = false;
+ invalidateSelf();
+ }
+ }
+ };
+
+ private static final class TraceAnimatorListener extends AnimatorListenerAdapter {
+ private final String mName;
+ TraceAnimatorListener(String name) {
+ mName = name;
+ }
+
+ @Override
+ public void onAnimationStart(Animator animation) {
+ Trace.beginSection("KeyButtonRipple.start." + mName);
+ Trace.endSection();
+ }
+
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ Trace.beginSection("KeyButtonRipple.cancel." + mName);
+ Trace.endSection();
+ }
+
@Override
public void onAnimationEnd(Animator animation) {
- mRunningAnimations.remove(animation);
- if (mRunningAnimations.isEmpty() && !mPressed) {
- mVisible = false;
- mDrawingHardwareGlow = false;
- invalidateSelf();
- }
+ Trace.beginSection("KeyButtonRipple.end." + mName);
+ Trace.endSection();
}
- };
+ }
/**
* Interpolator with a smooth log deceleration
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityController.java
index 1fb9b691d525..79d264ca4577 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityController.java
@@ -24,6 +24,8 @@ public interface SecurityController extends CallbackController<SecurityControlle
boolean isDeviceManaged();
boolean hasProfileOwner();
boolean hasWorkProfile();
+ /** Whether this device is organization-owned with a work profile **/
+ boolean isProfileOwnerOfOrganizationOwnedDevice();
String getDeviceOwnerName();
String getProfileOwnerName();
CharSequence getDeviceOwnerOrganizationName();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
index d29f4fcd0c26..309d4b04ebbf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
@@ -207,6 +207,11 @@ public class SecurityControllerImpl extends CurrentUserTracker implements Securi
}
@Override
+ public boolean isProfileOwnerOfOrganizationOwnedDevice() {
+ return mDevicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile();
+ }
+
+ @Override
public String getWorkProfileVpnName() {
final int profileId = getWorkProfileUserId(mVpnUserId);
if (profileId == UserHandle.USER_NULL) return null;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
index 3df1c11bc044..6bc0565510a2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
@@ -72,9 +72,6 @@ public class TvStatusBar extends SystemUI implements CommandQueue.Callbacks {
} catch (RemoteException ex) {
// If the system process isn't there we're doomed anyway.
}
-
- // Creating AudioRecordingDisclosureBar and just letting it run
- new AudioRecordingDisclosureBar(mContext);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tv/micdisclosure/AudioRecordingDisclosureBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tv/micdisclosure/AudioRecordingDisclosureBar.java
index 8b85a0961463..36e360da857f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tv/micdisclosure/AudioRecordingDisclosureBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tv/micdisclosure/AudioRecordingDisclosureBar.java
@@ -99,9 +99,10 @@ public class AudioRecordingDisclosureBar implements
private View mIconTextsContainer;
private View mIconContainerBg;
private View mIcon;
- private View mBgRight;
+ private View mBgEnd;
private View mTextsContainers;
private TextView mTextView;
+ private boolean mIsLtr;
@State private int mState = STATE_NOT_SHOWN;
@@ -232,6 +233,9 @@ public class AudioRecordingDisclosureBar implements
Log.d(TAG, "Showing indicator for " + packageName + " (" + label + ")...");
}
+ mIsLtr = mContext.getResources().getConfiguration().getLayoutDirection()
+ == View.LAYOUT_DIRECTION_LTR;
+
// Inflate the indicator view
mIndicatorView = LayoutInflater.from(mContext).inflate(
R.layout.tv_audio_recording_indicator,
@@ -241,7 +245,17 @@ public class AudioRecordingDisclosureBar implements
mIcon = mIconTextsContainer.findViewById(R.id.icon_mic);
mTextsContainers = mIconTextsContainer.findViewById(R.id.texts_container);
mTextView = mTextsContainers.findViewById(R.id.text);
- mBgRight = mIndicatorView.findViewById(R.id.bg_right);
+ mBgEnd = mIndicatorView.findViewById(R.id.bg_end);
+
+ // Swap background drawables depending on layout directions (both drawables have rounded
+ // corners only on one side)
+ if (mIsLtr) {
+ mBgEnd.setBackgroundResource(R.drawable.tv_rect_dark_right_rounded);
+ mIconContainerBg.setBackgroundResource(R.drawable.tv_rect_dark_left_rounded);
+ } else {
+ mBgEnd.setBackgroundResource(R.drawable.tv_rect_dark_left_rounded);
+ mIconContainerBg.setBackgroundResource(R.drawable.tv_rect_dark_right_rounded);
+ }
// Set up the notification text
mTextView.setText(mContext.getString(R.string.app_accessed_mic, label));
@@ -261,7 +275,8 @@ public class AudioRecordingDisclosureBar implements
// Now that the width of the indicator has been assigned, we can
// move it in from off the screen.
- final int initialOffset = mIndicatorView.getWidth();
+ final int initialOffset =
+ (mIsLtr ? 1 : -1) * mIndicatorView.getWidth();
final AnimatorSet set = new AnimatorSet();
set.setDuration(ANIMATION_DURATION);
set.playTogether(
@@ -294,7 +309,7 @@ public class AudioRecordingDisclosureBar implements
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
- layoutParams.gravity = Gravity.TOP | Gravity.RIGHT;
+ layoutParams.gravity = Gravity.TOP | (mIsLtr ? Gravity.RIGHT : Gravity.LEFT);
layoutParams.setTitle(LAYOUT_PARAMS_TITLE);
layoutParams.packageName = mContext.getPackageName();
final WindowManager windowManager = (WindowManager) mContext.getSystemService(
@@ -317,7 +332,7 @@ public class AudioRecordingDisclosureBar implements
ObjectAnimator.ofFloat(mIconTextsContainer, View.TRANSLATION_X, 0),
ObjectAnimator.ofFloat(mIconContainerBg, View.ALPHA, 1f),
ObjectAnimator.ofFloat(mTextsContainers, View.ALPHA, 1f),
- ObjectAnimator.ofFloat(mBgRight, View.ALPHA, 1f));
+ ObjectAnimator.ofFloat(mBgEnd, View.ALPHA, 1f));
set.setDuration(ANIMATION_DURATION);
set.addListener(
new AnimatorListenerAdapter() {
@@ -334,13 +349,13 @@ public class AudioRecordingDisclosureBar implements
@UiThread
private void minimize() {
if (DEBUG) Log.d(TAG, "Minimizing...");
- final int targetOffset = mTextsContainers.getWidth();
+ final int targetOffset = (mIsLtr ? 1 : -1) * mTextsContainers.getWidth();
final AnimatorSet set = new AnimatorSet();
set.playTogether(
ObjectAnimator.ofFloat(mIconTextsContainer, View.TRANSLATION_X, targetOffset),
ObjectAnimator.ofFloat(mIconContainerBg, View.ALPHA, 0f),
ObjectAnimator.ofFloat(mTextsContainers, View.ALPHA, 0f),
- ObjectAnimator.ofFloat(mBgRight, View.ALPHA, 0f));
+ ObjectAnimator.ofFloat(mBgEnd, View.ALPHA, 0f));
set.setDuration(ANIMATION_DURATION);
set.addListener(
new AnimatorListenerAdapter() {
@@ -357,8 +372,8 @@ public class AudioRecordingDisclosureBar implements
@UiThread
private void hide() {
if (DEBUG) Log.d(TAG, "Hiding...");
- final int targetOffset =
- mIndicatorView.getWidth() - (int) mIconTextsContainer.getTranslationX();
+ final int targetOffset = (mIsLtr ? 1 : -1) * (mIndicatorView.getWidth()
+ - (int) mIconTextsContainer.getTranslationX());
final AnimatorSet set = new AnimatorSet();
set.playTogether(
ObjectAnimator.ofFloat(mIndicatorView, View.TRANSLATION_X, targetOffset),
@@ -411,7 +426,7 @@ public class AudioRecordingDisclosureBar implements
mIcon = null;
mTextsContainers = null;
mTextView = null;
- mBgRight = null;
+ mBgEnd = null;
mState = STATE_NOT_SHOWN;
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java
index 248bdc870418..9ad2aa257aa0 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java
@@ -62,7 +62,8 @@ public class TunerServiceImpl extends TunerService {
// shouldn't be reset with tuner settings.
private static final String[] RESET_BLACKLIST = new String[] {
QSTileHost.TILES_SETTING,
- Settings.Secure.DOZE_ALWAYS_ON
+ Settings.Secure.DOZE_ALWAYS_ON,
+ Settings.Secure.MEDIA_CONTROLS_RESUME
};
private final Observer mObserver = new Observer();
diff --git a/packages/SystemUI/src/com/android/systemui/util/ConvenienceExtensions.kt b/packages/SystemUI/src/com/android/systemui/util/ConvenienceExtensions.kt
index c91033e4745a..ff53a9ff3b0a 100644
--- a/packages/SystemUI/src/com/android/systemui/util/ConvenienceExtensions.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/ConvenienceExtensions.kt
@@ -17,9 +17,32 @@
package com.android.systemui.util
import android.view.ViewGroup
+import com.android.internal.util.IndentingPrintWriter
+import java.io.PrintWriter
/** [Sequence] that yields all of the direct children of this [ViewGroup] */
val ViewGroup.children
get() = sequence {
for (i in 0 until childCount) yield(getChildAt(i))
- } \ No newline at end of file
+ }
+
+/** Inclusive version of [Iterable.takeWhile] */
+fun <T> Sequence<T>.takeUntil(pred: (T) -> Boolean): Sequence<T> = sequence {
+ for (x in this@takeUntil) {
+ yield(x)
+ if (pred(x)) {
+ break
+ }
+ }
+}
+
+/**
+ * If `this` is an [IndentingPrintWriter], it will process block inside an indentation level.
+ *
+ * If not, this will just process block.
+ */
+inline fun PrintWriter.indentIfPossible(block: PrintWriter.() -> Unit) {
+ if (this is IndentingPrintWriter) increaseIndent()
+ block()
+ if (this is IndentingPrintWriter) decreaseIndent()
+} \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/util/SparseArrayUtils.kt b/packages/SystemUI/src/com/android/systemui/util/SparseArrayUtils.kt
index accb81eae32a..1a25c84a7965 100644
--- a/packages/SystemUI/src/com/android/systemui/util/SparseArrayUtils.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/SparseArrayUtils.kt
@@ -19,6 +19,22 @@ package com.android.systemui.util
import android.util.SparseArray
/**
+ * Transforms a sequence of Key/Value pairs into a SparseArray.
+ *
+ * See [kotlin.collections.toMap].
+ */
+fun <T> Sequence<Pair<Int, T>>.toSparseArray(size: Int = -1): SparseArray<T> {
+ val sparseArray = when {
+ size < 0 -> SparseArray<T>()
+ else -> SparseArray<T>(size)
+ }
+ for ((i, v) in this) {
+ sparseArray.put(i, v)
+ }
+ return sparseArray
+}
+
+/**
* Transforms an [Array] into a [SparseArray], by applying each element to [keySelector] in order to
* generate the index at which it will be placed. If two elements produce the same index, the latter
* replaces the former in the final result.
diff --git a/packages/SystemUI/src/com/android/systemui/util/Utils.java b/packages/SystemUI/src/com/android/systemui/util/Utils.java
index 5c9db54a0f00..e5f30cf63ac3 100644
--- a/packages/SystemUI/src/com/android/systemui/util/Utils.java
+++ b/packages/SystemUI/src/com/android/systemui/util/Utils.java
@@ -139,7 +139,8 @@ public class Utils {
* Off by default, but can be enabled by setting to 1
*/
public static boolean useMediaResumption(Context context) {
- int flag = Settings.System.getInt(context.getContentResolver(), "qs_media_resumption", 0);
+ int flag = Settings.Secure.getInt(context.getContentResolver(),
+ Settings.Secure.MEDIA_CONTROLS_RESUME, 1);
return useQsMediaPlayer(context) && flag > 0;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/util/animation/FloatProperties.kt b/packages/SystemUI/src/com/android/systemui/util/animation/FloatProperties.kt
index ecd3afd687b3..a284a747da21 100644
--- a/packages/SystemUI/src/com/android/systemui/util/animation/FloatProperties.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/animation/FloatProperties.kt
@@ -67,6 +67,40 @@ class FloatProperties {
}
/**
+ * Represents the width of a [Rect]. Typically used to animate resizing a Rect horizontally.
+ *
+ * This property's getter returns [Rect.width], and its setter changes the value of
+ * [Rect.right] by adding the animated width value to [Rect.left].
+ */
+ @JvmField
+ val RECT_WIDTH = object : FloatPropertyCompat<Rect>("RectWidth") {
+ override fun getValue(rect: Rect): Float {
+ return rect.width().toFloat()
+ }
+
+ override fun setValue(rect: Rect, value: Float) {
+ rect.right = rect.left + value.toInt()
+ }
+ }
+
+ /**
+ * Represents the height of a [Rect]. Typically used to animate resizing a Rect vertically.
+ *
+ * This property's getter returns [Rect.height], and its setter changes the value of
+ * [Rect.bottom] by adding the animated height value to [Rect.top].
+ */
+ @JvmField
+ val RECT_HEIGHT = object : FloatPropertyCompat<Rect>("RectHeight") {
+ override fun getValue(rect: Rect): Float {
+ return rect.height().toFloat()
+ }
+
+ override fun setValue(rect: Rect, value: Float) {
+ rect.bottom = rect.top + value.toInt()
+ }
+ }
+
+ /**
* Represents the x-coordinate of a [RectF]. Typically used to animate moving a RectF
* horizontally.
*
diff --git a/packages/SystemUI/src/com/android/systemui/util/animation/TransitionLayout.kt b/packages/SystemUI/src/com/android/systemui/util/animation/TransitionLayout.kt
index 701ff5ecf8a1..3c0a23aa2eca 100644
--- a/packages/SystemUI/src/com/android/systemui/util/animation/TransitionLayout.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/animation/TransitionLayout.kt
@@ -17,6 +17,8 @@
package com.android.systemui.util.animation
import android.content.Context
+import android.graphics.Canvas
+import android.graphics.PointF
import android.graphics.Rect
import android.util.AttributeSet
import android.view.View
@@ -36,7 +38,9 @@ class TransitionLayout @JvmOverloads constructor(
defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr) {
+ private val boundsRect = Rect()
private val originalGoneChildrenSet: MutableSet<Int> = mutableSetOf()
+ private val originalViewAlphas: MutableMap<Int, Float> = mutableMapOf()
private var measureAsConstraint: Boolean = false
private var currentState: TransitionViewState = TransitionViewState()
private var updateScheduled = false
@@ -67,6 +71,7 @@ class TransitionLayout @JvmOverloads constructor(
if (child.visibility == GONE) {
originalGoneChildrenSet.add(child.id)
}
+ originalViewAlphas[child.id] = child.alpha
}
}
@@ -144,11 +149,21 @@ class TransitionLayout @JvmOverloads constructor(
}
}
+ override fun dispatchDraw(canvas: Canvas?) {
+ canvas?.save()
+ canvas?.clipRect(boundsRect)
+ super.dispatchDraw(canvas)
+ canvas?.restore()
+ }
+
private fun updateBounds() {
val layoutLeft = left
val layoutTop = top
setLeftTopRightBottom(layoutLeft, layoutTop, layoutLeft + currentState.width,
layoutTop + currentState.height)
+ translationX = currentState.translation.x
+ translationY = currentState.translation.y
+ boundsRect.set(0, 0, (width + translationX).toInt(), (height + translationY).toInt())
}
/**
@@ -198,6 +213,8 @@ class TransitionLayout @JvmOverloads constructor(
if (originalGoneChildrenSet.contains(child.id)) {
child.visibility = View.GONE
}
+ // Reset the alphas, to only have the alphas present from the constraintset
+ child.alpha = originalViewAlphas[child.id] ?: 1.0f
}
// Let's now apply the constraintSet to get the full state
constraintSet.applyTo(this)
@@ -230,11 +247,13 @@ class TransitionViewState {
var widgetStates: MutableMap<Int, WidgetState> = mutableMapOf()
var width: Int = 0
var height: Int = 0
+ val translation = PointF()
fun copy(reusedState: TransitionViewState? = null): TransitionViewState {
// we need a deep copy of this, so we can't use a data class
val copy = reusedState ?: TransitionViewState()
copy.width = width
copy.height = height
+ copy.translation.set(translation.x, translation.y)
for (entry in widgetStates) {
copy.widgetStates[entry.key] = entry.value.copy()
}
@@ -252,6 +271,7 @@ class TransitionViewState {
}
width = transitionLayout.measuredWidth
height = transitionLayout.measuredHeight
+ translation.set(0.0f, 0.0f)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/util/animation/TransitionLayoutController.kt b/packages/SystemUI/src/com/android/systemui/util/animation/TransitionLayoutController.kt
index 9ee141053861..5143e429768e 100644
--- a/packages/SystemUI/src/com/android/systemui/util/animation/TransitionLayoutController.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/animation/TransitionLayoutController.kt
@@ -17,6 +17,7 @@
package com.android.systemui.util.animation
import android.animation.ValueAnimator
+import android.graphics.PointF
import android.util.MathUtils
import com.android.systemui.Interpolators
@@ -43,7 +44,11 @@ open class TransitionLayoutController {
private var currentState = TransitionViewState()
private var animationStartState: TransitionViewState? = null
private var state = TransitionViewState()
+ private var pivot = PointF()
private var animator: ValueAnimator = ValueAnimator.ofFloat(0.0f, 1.0f)
+ private var currentHeight: Int = 0
+ private var currentWidth: Int = 0
+ var sizeChangedListener: ((Int, Int) -> Unit)? = null
init {
animator.apply {
@@ -63,8 +68,18 @@ open class TransitionLayoutController {
startState = animationStartState!!,
endState = state,
progress = animator.animatedFraction,
+ pivot = pivot,
resultState = currentState)
- view.setState(currentState)
+ applyStateToLayout(currentState)
+ }
+
+ private fun applyStateToLayout(state: TransitionViewState) {
+ transitionLayout?.setState(state)
+ if (currentHeight != state.height || currentWidth != state.width) {
+ currentHeight = state.height
+ currentWidth = state.width
+ sizeChangedListener?.invoke(currentWidth, currentHeight)
+ }
}
/**
@@ -75,8 +90,10 @@ open class TransitionLayoutController {
startState: TransitionViewState,
endState: TransitionViewState,
progress: Float,
+ pivot: PointF,
resultState: TransitionViewState
) {
+ this.pivot.set(pivot)
val view = transitionLayout ?: return
val childCount = view.childCount
for (i in 0 until childCount) {
@@ -178,6 +195,8 @@ open class TransitionLayoutController {
progress).toInt()
height = MathUtils.lerp(startState.height.toFloat(), endState.height.toFloat(),
progress).toInt()
+ translation.x = (endState.width - width) * pivot.x
+ translation.y = (endState.height - height) * pivot.y
}
}
@@ -206,7 +225,7 @@ open class TransitionLayoutController {
this.state = state.copy()
if (applyImmediately || transitionLayout == null) {
animator.cancel()
- transitionLayout?.setState(this.state)
+ applyStateToLayout(this.state)
currentState = state.copy(reusedState = currentState)
} else if (animated) {
animationStartState = currentState.copy()
@@ -214,7 +233,7 @@ open class TransitionLayoutController {
animator.startDelay = delay
animator.start()
} else if (!animator.isRunning) {
- transitionLayout?.setState(this.state)
+ applyStateToLayout(this.state)
currentState = state.copy(reusedState = currentState)
}
// otherwise the desired state was updated and the animation will go to the new target
diff --git a/packages/SystemUI/src/com/android/systemui/util/animation/UniqueObjectHostView.kt b/packages/SystemUI/src/com/android/systemui/util/animation/UniqueObjectHostView.kt
index 5b6444d8feaf..d6e7a8b28f0c 100644
--- a/packages/SystemUI/src/com/android/systemui/util/animation/UniqueObjectHostView.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/animation/UniqueObjectHostView.kt
@@ -70,7 +70,10 @@ class UniqueObjectHostView(
}
override fun addView(child: View?, index: Int, params: ViewGroup.LayoutParams?) {
- if (child?.measuredWidth == 0 || measuredWidth == 0 || child?.requiresRemeasuring == true) {
+ if (child == null) {
+ throw IllegalArgumentException("child must be non-null")
+ }
+ if (child.measuredWidth == 0 || measuredWidth == 0 || child.requiresRemeasuring == true) {
super.addView(child, index, params)
return
}
@@ -78,11 +81,13 @@ class UniqueObjectHostView(
// right size when being attached to this view
invalidate()
addViewInLayout(child, index, params, true /* preventRequestLayout */)
+ // RTL properties are normally resolved in onMeasure(), which we are intentionally skipping
+ child.resolveRtlPropertiesIfNeeded()
val left = paddingLeft
val top = paddingTop
val paddingHorizontal = paddingStart + paddingEnd
val paddingVertical = paddingTop + paddingBottom
- child!!.layout(left,
+ child.layout(left,
top,
left + measuredWidth - paddingHorizontal,
top + measuredHeight - paddingVertical)
diff --git a/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java b/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java
index 2e0c035b8547..b12224bf583d 100644
--- a/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java
+++ b/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java
@@ -62,22 +62,38 @@ import javax.inject.Inject;
import javax.inject.Singleton;
/**
+ * Suite of tools to periodically inspect the System UI heap and possibly prompt the user to
+ * capture heap dumps and report them. Includes the implementation of the "Dump SysUI Heap"
+ * quick settings tile.
*/
@Singleton
public class GarbageMonitor implements Dumpable {
- private static final boolean LEAK_REPORTING_ENABLED =
- Build.IS_DEBUGGABLE
- && SystemProperties.getBoolean("debug.enable_leak_reporting", false);
- private static final String FORCE_ENABLE_LEAK_REPORTING = "sysui_force_enable_leak_reporting";
+ // Feature switches
+ // ================
- private static final boolean HEAP_TRACKING_ENABLED = Build.IS_DEBUGGABLE;
+ // Whether to use TrackedGarbage to trigger LeakReporter. Off by default unless you set the
+ // appropriate sysprop on a userdebug device.
+ public static final boolean LEAK_REPORTING_ENABLED = Build.IS_DEBUGGABLE
+ && SystemProperties.getBoolean("debug.enable_leak_reporting", false);
+ public static final String FORCE_ENABLE_LEAK_REPORTING = "sysui_force_enable_leak_reporting";
- // whether to use ActivityManager.setHeapLimit
- private static final boolean ENABLE_AM_HEAP_LIMIT = Build.IS_DEBUGGABLE;
- // heap limit value, in KB (overrides R.integer.watch_heap_limit)
- private static final String SETTINGS_KEY_AM_HEAP_LIMIT = "systemui_am_heap_limit";
+ // Heap tracking: watch the current memory levels and update the MemoryTile if available.
+ // On for all userdebug devices.
+ public static final boolean HEAP_TRACKING_ENABLED = Build.IS_DEBUGGABLE;
- private static final String TAG = "GarbageMonitor";
+ // Tell QSTileHost.java to toss this into the default tileset?
+ public static final boolean ADD_MEMORY_TILE_TO_DEFAULT_ON_DEBUGGABLE_BUILDS = true;
+
+ // whether to use ActivityManager.setHeapLimit (and post a notification to the user asking
+ // to dump the heap). Off by default unless you set the appropriate sysprop on userdebug
+ private static final boolean ENABLE_AM_HEAP_LIMIT = Build.IS_DEBUGGABLE
+ && SystemProperties.getBoolean("debug.enable_sysui_heap_limit", false);
+
+ // Tuning params
+ // =============
+
+ // threshold for setHeapLimit(), in KB (overrides R.integer.watch_heap_limit)
+ private static final String SETTINGS_KEY_AM_HEAP_LIMIT = "systemui_am_heap_limit";
private static final long GARBAGE_INSPECTION_INTERVAL =
15 * DateUtils.MINUTE_IN_MILLIS; // 15 min
@@ -89,6 +105,7 @@ public class GarbageMonitor implements Dumpable {
private static final int GARBAGE_ALLOWANCE = 5;
+ private static final String TAG = "GarbageMonitor";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
private final Handler mHandler;
@@ -378,9 +395,6 @@ public class GarbageMonitor implements Dumpable {
public static class MemoryTile extends QSTileImpl<QSTile.State> {
public static final String TILE_SPEC = "dbg:mem";
- // Tell QSTileHost.java to toss this into the default tileset?
- public static final boolean ADD_TO_DEFAULT_ON_DEBUGGABLE_BUILDS = true;
-
private final GarbageMonitor gm;
private final ActivityStarter mActivityStarter;
private ProcessMemInfo pmi;
diff --git a/packages/SystemUI/src/com/android/systemui/util/magnetictarget/MagnetizedObject.kt b/packages/SystemUI/src/com/android/systemui/util/magnetictarget/MagnetizedObject.kt
index 5a2b064c5389..f441049feefb 100644
--- a/packages/SystemUI/src/com/android/systemui/util/magnetictarget/MagnetizedObject.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/magnetictarget/MagnetizedObject.kt
@@ -178,6 +178,18 @@ abstract class MagnetizedObject<T : Any>(
var physicsAnimatorEndListener: PhysicsAnimator.EndListener<T>? = null
/**
+ * Method that is called when the object should be animated stuck to the target. The default
+ * implementation uses the object's x and y properties to animate the object centered inside the
+ * target. You can override this if you need custom animation.
+ *
+ * The method is invoked with the MagneticTarget that the object is sticking to, the X and Y
+ * velocities of the gesture that brought the object into the magnetic radius, whether or not it
+ * was flung, and a callback you must call after your animation completes.
+ */
+ var animateStuckToTarget: (MagneticTarget, Float, Float, Boolean, (() -> Unit)?) -> Unit =
+ ::animateStuckToTargetInternal
+
+ /**
* Sets whether forcefully flinging the object vertically towards a target causes it to be
* attracted to the target and then released immediately, despite never being dragged within the
* magnetic field.
@@ -229,7 +241,7 @@ abstract class MagnetizedObject<T : Any>(
* to the target. If this velocity is reached, the object will be freed even if it wasn't moved
* outside the magnetic field radius.
*/
- var flingUnstuckFromTargetMinVelocity = 1000f
+ var flingUnstuckFromTargetMinVelocity = 4000f
/**
* Sets the maximum X velocity above which the object will not stick to the target. Even if the
@@ -373,7 +385,7 @@ abstract class MagnetizedObject<T : Any>(
targetObjectIsStuckTo = targetObjectIsInMagneticFieldOf
cancelAnimations()
magnetListener.onStuckToTarget(targetObjectIsInMagneticFieldOf!!)
- animateStuckToTarget(targetObjectIsInMagneticFieldOf, velX, velY, false)
+ animateStuckToTarget(targetObjectIsInMagneticFieldOf, velX, velY, false, null)
vibrateIfEnabled(VibrationEffect.EFFECT_HEAVY_CLICK)
} else if (targetObjectIsInMagneticFieldOf == null && objectStuckToTarget) {
@@ -402,9 +414,10 @@ abstract class MagnetizedObject<T : Any>(
cancelAnimations()
if (objectStuckToTarget) {
- if (hypot(velX, velY) > flingUnstuckFromTargetMinVelocity) {
- // If the object is stuck, but it was forcefully flung away from the target,
- // tell the listener so the object can be animated out of the target.
+ if (-velY > flingUnstuckFromTargetMinVelocity) {
+ // If the object is stuck, but it was forcefully flung away from the target in
+ // the upward direction, tell the listener so the object can be animated out of
+ // the target.
magnetListener.onUnstuckFromTarget(
targetObjectIsStuckTo!!, velX, velY, wasFlungOut = true)
} else {
@@ -430,8 +443,8 @@ abstract class MagnetizedObject<T : Any>(
targetObjectIsStuckTo = flungToTarget
animateStuckToTarget(flungToTarget, velX, velY, true) {
- targetObjectIsStuckTo = null
magnetListener.onReleasedInTarget(flungToTarget)
+ targetObjectIsStuckTo = null
vibrateIfEnabled(VibrationEffect.EFFECT_HEAVY_CLICK)
}
@@ -465,7 +478,7 @@ abstract class MagnetizedObject<T : Any>(
}
/** Animates sticking the object to the provided target with the given start velocities. */
- private fun animateStuckToTarget(
+ private fun animateStuckToTargetInternal(
target: MagneticTarget,
velX: Float,
velY: Float,
@@ -581,10 +594,10 @@ abstract class MagnetizedObject<T : Any>(
* multiple objects.
*/
class MagneticTarget(
- internal val targetView: View,
+ val targetView: View,
var magneticFieldRadiusPx: Int
) {
- internal val centerOnScreen = PointF()
+ val centerOnScreen = PointF()
private val tempLoc = IntArray(2)
diff --git a/packages/SystemUI/src/com/android/systemui/volume/Events.java b/packages/SystemUI/src/com/android/systemui/volume/Events.java
index 6131e3b504af..369552fc814d 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/Events.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/Events.java
@@ -340,7 +340,7 @@ public class Events {
}
/**
- * Logs an event to the event log and UiEvent (Westworld) logging. Compare writeEvent, which
+ * Logs an event to the event log and UiEvent (statsd) logging. Compare writeEvent, which
* adds more log destinations.
* @param tag One of the EVENT_* codes above.
* @param list Any additional event-specific arguments, documented above.
diff --git a/packages/SystemUI/src/com/android/systemui/wm/DisplayImeController.java b/packages/SystemUI/src/com/android/systemui/wm/DisplayImeController.java
index 32e3a7fc032e..8ba5b9951c54 100644
--- a/packages/SystemUI/src/com/android/systemui/wm/DisplayImeController.java
+++ b/packages/SystemUI/src/com/android/systemui/wm/DisplayImeController.java
@@ -19,11 +19,13 @@ package com.android.systemui.wm;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
+import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.Handler;
import android.os.RemoteException;
+import android.os.ServiceManager;
import android.util.Slog;
import android.util.SparseArray;
import android.view.IDisplayWindowInsetsController;
@@ -36,6 +38,7 @@ import android.view.WindowInsets;
import android.view.animation.Interpolator;
import android.view.animation.PathInterpolator;
+import com.android.internal.view.IInputMethodManager;
import com.android.systemui.TransactionPool;
import com.android.systemui.dagger.qualifiers.Main;
@@ -53,12 +56,14 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged
private static final boolean DEBUG = false;
+ // NOTE: All these constants came from InsetsController.
public static final int ANIMATION_DURATION_SHOW_MS = 275;
public static final int ANIMATION_DURATION_HIDE_MS = 340;
public static final Interpolator INTERPOLATOR = new PathInterpolator(0.4f, 0f, 0.2f, 1f);
private static final int DIRECTION_NONE = 0;
private static final int DIRECTION_SHOW = 1;
private static final int DIRECTION_HIDE = 2;
+ private static final int FLOATING_IME_BOTTOM_INSET = -80;
SystemWindows mSystemWindows;
final Handler mHandler;
@@ -268,8 +273,16 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged
}
// Set frame, but only if the new frame isn't empty -- this maintains continuity
final Rect newFrame = imeSource.getFrame();
- if (newFrame.height() != 0) {
+ mImeFrame.set(newFrame);
+ final boolean isFloating = newFrame.height() == 0;
+ if (isFloating) {
+ // This is likely a "floating" or "expanded" IME, so to get animations, just
+ // pretend the ime has some size just below the screen.
mImeFrame.set(newFrame);
+ final int floatingInset = (int) (
+ mSystemWindows.mDisplayController.getDisplayLayout(mDisplayId).density()
+ * FLOATING_IME_BOTTOM_INSET);
+ mImeFrame.bottom -= floatingInset;
}
if (DEBUG) {
Slog.d(TAG, "Run startAnim show:" + show + " was:"
@@ -313,6 +326,8 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged
SurfaceControl.Transaction t = mTransactionPool.acquire();
float value = (float) animation.getAnimatedValue();
t.setPosition(mImeSourceControl.getLeash(), x, value);
+ final float alpha = isFloating ? (value - hiddenY) / (shownY - hiddenY) : 1.f;
+ t.setAlpha(mImeSourceControl.getLeash(), alpha);
dispatchPositionChanged(mDisplayId, imeTop(value), t);
t.apply();
mTransactionPool.release(t);
@@ -324,6 +339,8 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged
public void onAnimationStart(Animator animation) {
SurfaceControl.Transaction t = mTransactionPool.acquire();
t.setPosition(mImeSourceControl.getLeash(), x, startY);
+ final float alpha = isFloating ? (startY - hiddenY) / (shownY - hiddenY) : 1.f;
+ t.setAlpha(mImeSourceControl.getLeash(), alpha);
if (DEBUG) {
Slog.d(TAG, "onAnimationStart d:" + mDisplayId + " top:"
+ imeTop(hiddenY) + "->" + imeTop(shownY)
@@ -348,10 +365,21 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged
SurfaceControl.Transaction t = mTransactionPool.acquire();
if (!mCancelled) {
t.setPosition(mImeSourceControl.getLeash(), x, endY);
+ t.setAlpha(mImeSourceControl.getLeash(), 1.f);
}
dispatchEndPositioning(mDisplayId, mCancelled, t);
if (mAnimationDirection == DIRECTION_HIDE && !mCancelled) {
t.hide(mImeSourceControl.getLeash());
+ final IInputMethodManager imms = getImms();
+ if (imms != null) {
+ try {
+ // Remove the IME surface to make the insets invisible for
+ // non-client controlled insets.
+ imms.removeImeSurface();
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Failed to remove IME surface.", e);
+ }
+ }
}
t.apply();
mTransactionPool.release(t);
@@ -382,9 +410,9 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged
* Called when the IME position is starting to animate.
*
* @param hiddenTop The y position of the top of the IME surface when it is hidden.
- * @param shownTop The y position of the top of the IME surface when it is shown.
- * @param showing {@code true} when we are animating from hidden to shown, {@code false}
- * when animating from shown to hidden.
+ * @param shownTop The y position of the top of the IME surface when it is shown.
+ * @param showing {@code true} when we are animating from hidden to shown, {@code false}
+ * when animating from shown to hidden.
*/
default void onImeStartPositioning(int displayId, int hiddenTop, int shownTop,
boolean showing, SurfaceControl.Transaction t) {}
@@ -406,4 +434,9 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged
default void onImeEndPositioning(int displayId, boolean cancel,
SurfaceControl.Transaction t) {}
}
+
+ public IInputMethodManager getImms() {
+ return IInputMethodManager.Stub.asInterface(
+ ServiceManager.getService(Context.INPUT_METHOD_SERVICE));
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java
index e324d844144c..a867825e223d 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java
@@ -18,7 +18,9 @@ package com.android.keyguard;
import static android.view.WindowInsets.Type.ime;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -110,6 +112,7 @@ public class KeyguardSecurityContainerTest extends SysuiTestCase {
mKeyguardSecurityContainer.startDisappearAnimation(null);
verify(mSecurityView).startDisappearAnimation(eq(null));
- verify(mWindowInsetsController).hide(eq(ime()));
+ verify(mWindowInsetsController).controlWindowInsetsAnimation(eq(ime()), anyLong(), any(),
+ any(), any());
}
} \ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index 023879926563..7bc453ac9aa1 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -452,6 +452,12 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
}
@Test
+ public void requiresAuthentication_whenEncryptedKeyguard_andBypass() {
+ testStrongAuthExceptOnBouncer(
+ KeyguardUpdateMonitor.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT);
+ }
+
+ @Test
public void requiresAuthentication_whenTimeoutKeyguard_andBypass() {
testStrongAuthExceptOnBouncer(
KeyguardUpdateMonitor.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_TIMEOUT);
@@ -507,20 +513,10 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
@Test
public void testIgnoresAuth_whenLockdown() {
- testIgnoresAuth(
- KeyguardUpdateMonitor.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN);
- }
-
- @Test
- public void testIgnoresAuth_whenEncrypted() {
- testIgnoresAuth(
- KeyguardUpdateMonitor.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT);
- }
-
- private void testIgnoresAuth(int strongAuth) {
mKeyguardUpdateMonitor.dispatchStartedWakingUp();
mTestableLooper.processAllMessages();
- when(mStrongAuthTracker.getStrongAuthForUser(anyInt())).thenReturn(strongAuth);
+ when(mStrongAuthTracker.getStrongAuthForUser(anyInt())).thenReturn(
+ KeyguardUpdateMonitor.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN);
mKeyguardUpdateMonitor.onKeyguardVisibilityChanged(true);
verify(mFaceManager, never()).authenticate(any(), any(), anyInt(), any(), any(), anyInt());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java
index 805254cda175..60f0cd9da5f2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java
@@ -406,60 +406,76 @@ public class ForegroundServiceControllerTest extends SysuiTestCase {
}
@Test
- public void testStdLayoutBasic() {
- final String PKG1 = "com.example.app0";
-
- StatusBarNotification sbn_user1_app1 = makeMockFgSBN(USERID_ONE, PKG1, 0, true);
- sbn_user1_app1.getNotification().flags = 0;
- StatusBarNotification sbn_user1_app1_fg = makeMockFgSBN(USERID_ONE, PKG1, 1, true);
- entryAdded(sbn_user1_app1, NotificationManager.IMPORTANCE_MIN); // not fg
- assertTrue(mFsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1)); // should be required!
- entryAdded(sbn_user1_app1_fg, NotificationManager.IMPORTANCE_MIN);
- assertFalse(mFsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1)); // app1 has got it covered
- assertFalse(mFsc.isSystemAlertWarningNeeded(USERID_TWO, "otherpkg"));
- // let's take out the non-fg notification and see what happens.
- entryRemoved(sbn_user1_app1);
- // still covered by sbn_user1_app1_fg
- assertFalse(mFsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1));
- assertFalse(mFsc.isSystemAlertWarningNeeded(USERID_TWO, "anyPkg"));
+ public void testNoNotifsNorAppOps_noSystemAlertWarningRequired() {
+ // no notifications nor app op signals that this package/userId requires system alert
+ // warning
+ assertFalse(mFsc.isSystemAlertWarningNeeded(USERID_ONE, "any"));
+ }
- // let's attempt to downgrade the notification from FLAG_FOREGROUND and see what we get
- StatusBarNotification sbn_user1_app1_fg_sneaky = makeMockFgSBN(USERID_ONE, PKG1, 1, true);
- sbn_user1_app1_fg_sneaky.getNotification().flags = 0;
- entryUpdated(sbn_user1_app1_fg_sneaky, NotificationManager.IMPORTANCE_MIN);
- assertTrue(mFsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1)); // should be required!
- assertFalse(mFsc.isSystemAlertWarningNeeded(USERID_TWO, "anything"));
- // ok, ok, we'll put it back
- sbn_user1_app1_fg_sneaky.getNotification().flags = Notification.FLAG_FOREGROUND_SERVICE;
- entryUpdated(sbn_user1_app1_fg, NotificationManager.IMPORTANCE_MIN);
- assertFalse(mFsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1));
- assertFalse(mFsc.isSystemAlertWarningNeeded(USERID_TWO, "whatever"));
+ @Test
+ public void testCustomLayouts_systemAlertWarningRequired() {
+ // GIVEN a notification with a custom layout
+ final String pkg = "com.example.app0";
+ StatusBarNotification customLayoutNotif = makeMockSBN(USERID_ONE, pkg, 0,
+ false);
+
+ // WHEN the custom layout entry is added
+ entryAdded(customLayoutNotif, NotificationManager.IMPORTANCE_MIN);
+
+ // THEN a system alert warning is required since there aren't any notifications that can
+ // display the app ops
+ assertTrue(mFsc.isSystemAlertWarningNeeded(USERID_ONE, pkg));
+ }
- entryRemoved(sbn_user1_app1_fg_sneaky);
- assertTrue(mFsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1)); // should be required!
- assertFalse(mFsc.isSystemAlertWarningNeeded(USERID_TWO, "a"));
-
- // let's try a custom layout
- sbn_user1_app1_fg_sneaky = makeMockFgSBN(USERID_ONE, PKG1, 1, false);
- entryUpdated(sbn_user1_app1_fg_sneaky, NotificationManager.IMPORTANCE_MIN);
- assertTrue(mFsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1)); // should be required!
- assertFalse(mFsc.isSystemAlertWarningNeeded(USERID_TWO, "anything"));
- // now let's test an upgrade (non fg to fg)
- entryAdded(sbn_user1_app1, NotificationManager.IMPORTANCE_MIN);
- assertTrue(mFsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1));
- assertFalse(mFsc.isSystemAlertWarningNeeded(USERID_TWO, "b"));
- sbn_user1_app1.getNotification().flags |= Notification.FLAG_FOREGROUND_SERVICE;
- entryUpdated(sbn_user1_app1,
- NotificationManager.IMPORTANCE_MIN); // this is now a fg notification
+ @Test
+ public void testStandardLayoutExists_noSystemAlertWarningRequired() {
+ // GIVEN two notifications (one with a custom layout, the other with a standard layout)
+ final String pkg = "com.example.app0";
+ StatusBarNotification customLayoutNotif = makeMockSBN(USERID_ONE, pkg, 0,
+ false);
+ StatusBarNotification standardLayoutNotif = makeMockSBN(USERID_ONE, pkg, 1, true);
+
+ // WHEN the entries are added
+ entryAdded(customLayoutNotif, NotificationManager.IMPORTANCE_MIN);
+ entryAdded(standardLayoutNotif, NotificationManager.IMPORTANCE_MIN);
+
+ // THEN no system alert warning is required, since there is at least one notification
+ // with a standard layout that can display the app ops on the notification
+ assertFalse(mFsc.isSystemAlertWarningNeeded(USERID_ONE, pkg));
+ }
- assertFalse(mFsc.isSystemAlertWarningNeeded(USERID_TWO, PKG1));
- assertFalse(mFsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1));
+ @Test
+ public void testStandardLayoutRemoved_systemAlertWarningRequired() {
+ // GIVEN two notifications (one with a custom layout, the other with a standard layout)
+ final String pkg = "com.example.app0";
+ StatusBarNotification customLayoutNotif = makeMockSBN(USERID_ONE, pkg, 0,
+ false);
+ StatusBarNotification standardLayoutNotif = makeMockSBN(USERID_ONE, pkg, 1, true);
+
+ // WHEN the entries are added and then the standard layout notification is removed
+ entryAdded(customLayoutNotif, NotificationManager.IMPORTANCE_MIN);
+ entryAdded(standardLayoutNotif, NotificationManager.IMPORTANCE_MIN);
+ entryRemoved(standardLayoutNotif);
+
+ // THEN a system alert warning is required since there aren't any notifications that can
+ // display the app ops
+ assertTrue(mFsc.isSystemAlertWarningNeeded(USERID_ONE, pkg));
+ }
- // remove it, make sure we're out of compliance again
- entryRemoved(sbn_user1_app1); // was fg, should return true
- entryRemoved(sbn_user1_app1);
- assertFalse(mFsc.isSystemAlertWarningNeeded(USERID_TWO, PKG1));
- assertTrue(mFsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1));
+ @Test
+ public void testStandardLayoutUpdatedToCustomLayout_systemAlertWarningRequired() {
+ // GIVEN a standard layout notification and then an updated version with a customLayout
+ final String pkg = "com.example.app0";
+ StatusBarNotification standardLayoutNotif = makeMockSBN(USERID_ONE, pkg, 1, true);
+ StatusBarNotification updatedToCustomLayoutNotif = makeMockSBN(USERID_ONE, pkg, 1, false);
+
+ // WHEN the entries is added and then updated to a custom layout
+ entryAdded(standardLayoutNotif, NotificationManager.IMPORTANCE_MIN);
+ entryUpdated(updatedToCustomLayoutNotif, NotificationManager.IMPORTANCE_MIN);
+
+ // THEN a system alert warning is required since there aren't any notifications that can
+ // display the app ops
+ assertTrue(mFsc.isSystemAlertWarningNeeded(USERID_ONE, pkg));
}
private StatusBarNotification makeMockSBN(int userId, String pkg, int id, String tag,
@@ -483,6 +499,19 @@ public class ForegroundServiceControllerTest extends SysuiTestCase {
return sbn;
}
+ private StatusBarNotification makeMockSBN(int uid, String pkg, int id,
+ boolean usesStdLayout) {
+ StatusBarNotification sbn = makeMockSBN(uid, pkg, id, "foo", 0);
+ if (usesStdLayout) {
+ sbn.getNotification().contentView = null;
+ sbn.getNotification().headsUpContentView = null;
+ sbn.getNotification().bigContentView = null;
+ } else {
+ sbn.getNotification().contentView = mock(RemoteViews.class);
+ }
+ return sbn;
+ }
+
private StatusBarNotification makeMockFgSBN(int uid, String pkg, int id,
boolean usesStdLayout) {
StatusBarNotification sbn =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
index 713aef9e8a91..dd3a7858fd1f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
@@ -49,6 +49,7 @@ import org.junit.Rule;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executor;
import java.util.concurrent.Future;
/**
@@ -74,7 +75,8 @@ public abstract class SysuiTestCase {
SystemUIFactory.createFromConfig(mContext);
mDependency = new TestableDependency(mContext);
mFakeBroadcastDispatcher = new FakeBroadcastDispatcher(mContext, mock(Looper.class),
- mock(DumpManager.class), mock(BroadcastDispatcherLogger.class));
+ mock(Executor.class), mock(DumpManager.class),
+ mock(BroadcastDispatcherLogger.class));
mRealInstrumentation = InstrumentationRegistry.getInstrumentation();
Instrumentation inst = spy(mRealInstrumentation);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/broadcast/ActionReceiverTest.kt b/packages/SystemUI/tests/src/com/android/systemui/broadcast/ActionReceiverTest.kt
new file mode 100644
index 000000000000..e95eb4ef6509
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/broadcast/ActionReceiverTest.kt
@@ -0,0 +1,256 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.broadcast
+
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import android.content.IntentFilter
+import android.os.UserHandle
+import android.test.suitebuilder.annotation.SmallTest
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.broadcast.logging.BroadcastDispatcherLogger
+import com.android.systemui.util.concurrency.FakeExecutor
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.capture
+import com.android.systemui.util.mockito.eq
+import com.android.systemui.util.time.FakeSystemClock
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertTrue
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.ArgumentMatchers.anyString
+import org.mockito.Captor
+import org.mockito.Mock
+import org.mockito.Mockito
+import org.mockito.Mockito.mock
+import org.mockito.Mockito.never
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+import java.lang.IllegalArgumentException
+import java.lang.IllegalStateException
+import java.util.concurrent.Executor
+
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper
+@SmallTest
+class ActionReceiverTest : SysuiTestCase() {
+
+ companion object {
+ private const val ACTION1 = "TEST_ACTION1"
+ private const val ACTION2 = "TEST_ACTION2"
+ private const val CATEGORY = "TEST_CATEGORY"
+ private val USER = UserHandle.of(0)
+ private fun <T : Any> sameNotNull(arg: T): T = Mockito.same(arg) ?: arg
+
+ fun IntentFilter.matchesOther(it: IntentFilter): Boolean {
+ val actions = actionsIterator()?.asSequence()?.toSet() ?: emptySet()
+ val categories = categoriesIterator()?.asSequence()?.toSet() ?: emptySet()
+ return (it.actionsIterator()?.asSequence()?.toSet() ?: emptySet()) == actions &&
+ (it.categoriesIterator()?.asSequence()?.toSet() ?: emptySet()) == categories &&
+ it.countDataAuthorities() == 0 &&
+ it.countDataPaths() == 0 &&
+ it.countDataSchemes() == 0 &&
+ it.countDataTypes() == 0 &&
+ it.countMimeGroups() == 0 &&
+ it.priority == 0
+ }
+ }
+
+ @Mock
+ private lateinit var registerFunction: BroadcastReceiver.(IntentFilter) -> Unit
+ @Mock
+ private lateinit var unregisterFunction: BroadcastReceiver.() -> Unit
+ @Mock
+ private lateinit var receiver1: BroadcastReceiver
+ @Mock
+ private lateinit var receiver2: BroadcastReceiver
+ @Mock
+ private lateinit var logger: BroadcastDispatcherLogger
+ @Captor
+ private lateinit var intentFilterCaptor: ArgumentCaptor<IntentFilter>
+
+ private lateinit var executor: FakeExecutor
+ private lateinit var actionReceiver: ActionReceiver
+ private val directExecutor = Executor { it.run() }
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+ executor = FakeExecutor(FakeSystemClock())
+
+ actionReceiver = ActionReceiver(
+ ACTION1,
+ USER.identifier,
+ registerFunction,
+ unregisterFunction,
+ executor,
+ logger
+ )
+ }
+
+ @Test
+ fun testStartsUnregistered() {
+ assertFalse(actionReceiver.registered)
+ verify(registerFunction, never()).invoke(sameNotNull(actionReceiver),
+ any(IntentFilter::class.java))
+ }
+
+ @Test
+ fun testRegistersOnFirstAdd() {
+ val receiverData = ReceiverData(receiver1, IntentFilter(ACTION1), directExecutor, USER)
+
+ actionReceiver.addReceiverData(receiverData)
+
+ assertTrue(actionReceiver.registered)
+ verify(registerFunction).invoke(sameNotNull(actionReceiver), capture(intentFilterCaptor))
+
+ assertTrue(IntentFilter(ACTION1).matchesOther(intentFilterCaptor.value))
+ }
+
+ @Test
+ fun testRegistersOnlyOnce() {
+ val receiverData1 = ReceiverData(receiver1, IntentFilter(ACTION1), directExecutor, USER)
+ val receiverData2 = ReceiverData(receiver2, IntentFilter(ACTION1), directExecutor, USER)
+
+ actionReceiver.addReceiverData(receiverData1)
+ actionReceiver.addReceiverData(receiverData2)
+
+ verify(registerFunction).invoke(sameNotNull(actionReceiver), any(IntentFilter::class.java))
+ }
+
+ @Test
+ fun testRemovingLastReceiverUnregisters() {
+ val receiverData = ReceiverData(receiver1, IntentFilter(ACTION1), directExecutor, USER)
+
+ actionReceiver.addReceiverData(receiverData)
+
+ actionReceiver.removeReceiver(receiver1)
+
+ assertFalse(actionReceiver.registered)
+ verify(unregisterFunction).invoke(sameNotNull(actionReceiver))
+ }
+
+ @Test
+ fun testRemovingWhileOtherReceiversDoesntUnregister() {
+ val receiverData1 = ReceiverData(receiver1, IntentFilter(ACTION1), directExecutor, USER)
+ val receiverData2 = ReceiverData(receiver2, IntentFilter(ACTION1), directExecutor, USER)
+
+ actionReceiver.addReceiverData(receiverData1)
+ actionReceiver.addReceiverData(receiverData2)
+
+ actionReceiver.removeReceiver(receiver1)
+
+ assertTrue(actionReceiver.registered)
+ verify(unregisterFunction, never()).invoke(any(BroadcastReceiver::class.java))
+ }
+
+ @Test
+ fun testReceiverHasCategories() {
+ val filter = IntentFilter(ACTION1)
+ filter.addCategory(CATEGORY)
+
+ val receiverData = ReceiverData(receiver1, filter, directExecutor, USER)
+
+ actionReceiver.addReceiverData(receiverData)
+
+ verify(registerFunction).invoke(sameNotNull(actionReceiver), capture(intentFilterCaptor))
+ assertTrue(intentFilterCaptor.value.hasCategory(CATEGORY))
+ }
+
+ @Test(expected = IllegalArgumentException::class)
+ fun testNotRegisteredWithWrongAction_throwsException() {
+ val receiverData = ReceiverData(receiver1, IntentFilter(ACTION2), directExecutor, USER)
+
+ actionReceiver.addReceiverData(receiverData)
+ }
+
+ @Test
+ fun testReceiverGetsBroadcast() {
+ val receiverData = ReceiverData(receiver1, IntentFilter(ACTION1), directExecutor, USER)
+ actionReceiver.addReceiverData(receiverData)
+
+ val intent = Intent(ACTION1)
+
+ actionReceiver.onReceive(mContext, intent)
+
+ executor.runAllReady()
+
+ verify(receiver1).onReceive(any(Context::class.java), sameNotNull(intent))
+ }
+
+ @Test
+ fun testReceiverGetsPendingResult() {
+ val receiverData = ReceiverData(receiver1, IntentFilter(ACTION1), directExecutor, USER)
+ actionReceiver.addReceiverData(receiverData)
+
+ val intent = Intent(ACTION1)
+ val pendingResult = mock(BroadcastReceiver.PendingResult::class.java)
+
+ actionReceiver.pendingResult = pendingResult
+ actionReceiver.onReceive(mContext, intent)
+
+ executor.runAllReady()
+ verify(receiver1).pendingResult = pendingResult
+ }
+
+ @Test
+ fun testBroadcastIsDispatchedInExecutor() {
+ val executor = FakeExecutor(FakeSystemClock())
+ val receiverData = ReceiverData(receiver1, IntentFilter(ACTION1), executor, USER)
+ actionReceiver.addReceiverData(receiverData)
+
+ val intent = Intent(ACTION1)
+ actionReceiver.onReceive(mContext, intent)
+
+ this.executor.runAllReady()
+
+ verify(receiver1, never()).onReceive(mContext, intent)
+
+ executor.runAllReady()
+ // Dispatched after executor is processed
+ verify(receiver1).onReceive(mContext, intent)
+ }
+
+ @Test
+ fun testBroadcastReceivedDispatched_logger() {
+ val receiverData = ReceiverData(receiver1, IntentFilter(ACTION1), directExecutor, USER)
+
+ actionReceiver.addReceiverData(receiverData)
+
+ val intent = Intent(ACTION1)
+ actionReceiver.onReceive(mContext, intent)
+ verify(logger).logBroadcastReceived(anyInt(), eq(USER.identifier), eq(intent))
+
+ verify(logger, never()).logBroadcastDispatched(anyInt(), anyString(),
+ any(BroadcastReceiver::class.java))
+
+ executor.runAllReady()
+
+ verify(logger).logBroadcastDispatched(anyInt(), eq(ACTION1), sameNotNull(receiver1))
+ }
+
+ @Test(expected = IllegalStateException::class)
+ fun testBroadcastWithWrongAction_throwsException() {
+ actionReceiver.onReceive(mContext, Intent(ACTION2))
+ }
+} \ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastDispatcherTest.kt b/packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastDispatcherTest.kt
index 4ed284ede634..22e9594ca420 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastDispatcherTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastDispatcherTest.kt
@@ -98,6 +98,7 @@ class BroadcastDispatcherTest : SysuiTestCase() {
broadcastDispatcher = TestBroadcastDispatcher(
mockContext,
testableLooper.looper,
+ mock(Executor::class.java),
mock(DumpManager::class.java),
logger,
mapOf(0 to mockUBRUser0, 1 to mockUBRUser1))
@@ -246,10 +247,11 @@ class BroadcastDispatcherTest : SysuiTestCase() {
private class TestBroadcastDispatcher(
context: Context,
bgLooper: Looper,
+ executor: Executor,
dumpManager: DumpManager,
logger: BroadcastDispatcherLogger,
var mockUBRMap: Map<Int, UserBroadcastDispatcher>
- ) : BroadcastDispatcher(context, bgLooper, dumpManager, logger) {
+ ) : BroadcastDispatcher(context, bgLooper, executor, dumpManager, logger) {
override fun createUBRForUser(userId: Int): UserBroadcastDispatcher {
return mockUBRMap.getOrDefault(userId, mock(UserBroadcastDispatcher::class.java))
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/broadcast/FakeBroadcastDispatcher.kt b/packages/SystemUI/tests/src/com/android/systemui/broadcast/FakeBroadcastDispatcher.kt
index 09a091689a23..949932da4d50 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/broadcast/FakeBroadcastDispatcher.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/broadcast/FakeBroadcastDispatcher.kt
@@ -31,9 +31,10 @@ import java.util.concurrent.Executor
class FakeBroadcastDispatcher(
context: SysuiTestableContext,
looper: Looper,
+ executor: Executor,
dumpManager: DumpManager,
logger: BroadcastDispatcherLogger
-) : BroadcastDispatcher(context, looper, dumpManager, logger) {
+) : BroadcastDispatcher(context, looper, executor, dumpManager, logger) {
private val registeredReceivers = ArraySet<BroadcastReceiver>()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/broadcast/UserBroadcastDispatcherTest.kt b/packages/SystemUI/tests/src/com/android/systemui/broadcast/UserBroadcastDispatcherTest.kt
index 443357694f4d..dfe143254788 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/broadcast/UserBroadcastDispatcherTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/broadcast/UserBroadcastDispatcherTest.kt
@@ -18,7 +18,6 @@ package com.android.systemui.broadcast
import android.content.BroadcastReceiver
import android.content.Context
-import android.content.Intent
import android.content.IntentFilter
import android.os.Handler
import android.os.UserHandle
@@ -29,26 +28,18 @@ import com.android.systemui.SysuiTestCase
import com.android.systemui.broadcast.logging.BroadcastDispatcherLogger
import com.android.systemui.util.concurrency.FakeExecutor
import com.android.systemui.util.time.FakeSystemClock
-import junit.framework.Assert.assertEquals
import junit.framework.Assert.assertFalse
-import junit.framework.Assert.assertTrue
+import junit.framework.Assert.assertNotNull
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentCaptor
-import org.mockito.ArgumentMatchers.any
-import org.mockito.ArgumentMatchers.anyInt
-import org.mockito.ArgumentMatchers.eq
-import org.mockito.Captor
import org.mockito.Mock
import org.mockito.Mockito
-import org.mockito.Mockito.anyString
-import org.mockito.Mockito.atLeastOnce
-import org.mockito.Mockito.never
-import org.mockito.Mockito.reset
-import org.mockito.Mockito.times
+import org.mockito.Mockito.mock
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
+import java.util.concurrent.Executor
@RunWith(AndroidTestingRunner::class)
@TestableLooper.RunWithLooper
@@ -58,8 +49,6 @@ class UserBroadcastDispatcherTest : SysuiTestCase() {
companion object {
private const val ACTION_1 = "com.android.systemui.tests.ACTION_1"
private const val ACTION_2 = "com.android.systemui.tests.ACTION_2"
- private const val CATEGORY_1 = "com.android.systemui.tests.CATEGORY_1"
- private const val CATEGORY_2 = "com.android.systemui.tests.CATEGORY_2"
private const val USER_ID = 0
private val USER_HANDLE = UserHandle.of(USER_ID)
@@ -75,13 +64,8 @@ class UserBroadcastDispatcherTest : SysuiTestCase() {
@Mock
private lateinit var mockContext: Context
@Mock
- private lateinit var mPendingResult: BroadcastReceiver.PendingResult
- @Mock
private lateinit var logger: BroadcastDispatcherLogger
- @Captor
- private lateinit var argumentCaptor: ArgumentCaptor<IntentFilter>
-
private lateinit var testableLooper: TestableLooper
private lateinit var userBroadcastDispatcher: UserBroadcastDispatcher
private lateinit var intentFilter: IntentFilter
@@ -96,46 +80,25 @@ class UserBroadcastDispatcherTest : SysuiTestCase() {
handler = Handler(testableLooper.looper)
fakeExecutor = FakeExecutor(FakeSystemClock())
- userBroadcastDispatcher = UserBroadcastDispatcher(
- mockContext, USER_ID, testableLooper.looper, logger)
- userBroadcastDispatcher.pendingResult = mPendingResult
- }
-
- @Test
- fun testNotRegisteredOnStart() {
- testableLooper.processAllMessages()
- verify(mockContext, never()).registerReceiver(any(), any())
- verify(mockContext, never()).registerReceiver(any(), any(), anyInt())
- verify(mockContext, never()).registerReceiver(any(), any(), anyString(), any())
- verify(mockContext, never()).registerReceiver(any(), any(), anyString(), any(), anyInt())
- verify(mockContext, never()).registerReceiverAsUser(any(), any(), any(), anyString(), any())
- }
-
- @Test
- fun testNotRegisteredOnStart_logging() {
- testableLooper.processAllMessages()
-
- verify(logger, never()).logContextReceiverRegistered(anyInt(), any())
+ userBroadcastDispatcher = object : UserBroadcastDispatcher(
+ mockContext, USER_ID, testableLooper.looper, mock(Executor::class.java), logger) {
+ override fun createActionReceiver(action: String): ActionReceiver {
+ return mock(ActionReceiver::class.java)
+ }
+ }
}
@Test
fun testSingleReceiverRegistered() {
intentFilter = IntentFilter(ACTION_1)
+ val receiverData = ReceiverData(broadcastReceiver, intentFilter, fakeExecutor, USER_HANDLE)
- userBroadcastDispatcher.registerReceiver(
- ReceiverData(broadcastReceiver, intentFilter, fakeExecutor, USER_HANDLE))
+ userBroadcastDispatcher.registerReceiver(receiverData)
testableLooper.processAllMessages()
- assertTrue(userBroadcastDispatcher.isRegistered())
- verify(mockContext).registerReceiverAsUser(
- any(),
- eq(USER_HANDLE),
- capture(argumentCaptor),
- any(),
- any())
- assertEquals(1, argumentCaptor.value.countActions())
- assertTrue(argumentCaptor.value.hasAction(ACTION_1))
- assertEquals(0, argumentCaptor.value.countCategories())
+ val actionReceiver = userBroadcastDispatcher.getActionReceiver(ACTION_1)
+ assertNotNull(actionReceiver)
+ verify(actionReceiver)?.addReceiverData(receiverData)
}
@Test
@@ -147,7 +110,6 @@ class UserBroadcastDispatcherTest : SysuiTestCase() {
testableLooper.processAllMessages()
verify(logger).logReceiverRegistered(USER_HANDLE.identifier, broadcastReceiver)
- verify(logger).logContextReceiverRegistered(eq(USER_HANDLE.identifier), any())
}
@Test
@@ -157,16 +119,13 @@ class UserBroadcastDispatcherTest : SysuiTestCase() {
userBroadcastDispatcher.registerReceiver(
ReceiverData(broadcastReceiver, intentFilter, fakeExecutor, USER_HANDLE))
testableLooper.processAllMessages()
- reset(mockContext)
-
- assertTrue(userBroadcastDispatcher.isRegistered())
userBroadcastDispatcher.unregisterReceiver(broadcastReceiver)
testableLooper.processAllMessages()
- verify(mockContext, atLeastOnce()).unregisterReceiver(any())
- verify(mockContext, never()).registerReceiverAsUser(any(), any(), any(), any(), any())
- assertFalse(userBroadcastDispatcher.isRegistered())
+ val actionReceiver = userBroadcastDispatcher.getActionReceiver(ACTION_1)
+ assertNotNull(actionReceiver)
+ verify(actionReceiver)?.removeReceiver(broadcastReceiver)
}
@Test
@@ -181,139 +140,6 @@ class UserBroadcastDispatcherTest : SysuiTestCase() {
testableLooper.processAllMessages()
verify(logger).logReceiverUnregistered(USER_HANDLE.identifier, broadcastReceiver)
- verify(logger).logContextReceiverUnregistered(USER_HANDLE.identifier)
- }
-
- @Test
- fun testFilterHasAllActionsAndCategories_twoReceivers() {
- intentFilter = IntentFilter(ACTION_1)
- intentFilterOther = IntentFilter(ACTION_2).apply {
- addCategory(CATEGORY_1)
- addCategory(CATEGORY_2)
- }
-
- userBroadcastDispatcher.registerReceiver(
- ReceiverData(broadcastReceiver, intentFilter, fakeExecutor, USER_HANDLE))
- userBroadcastDispatcher.registerReceiver(
- ReceiverData(broadcastReceiverOther, intentFilterOther, fakeExecutor, USER_HANDLE))
-
- testableLooper.processAllMessages()
- assertTrue(userBroadcastDispatcher.isRegistered())
-
- verify(mockContext, times(2)).registerReceiverAsUser(
- any(),
- eq(USER_HANDLE),
- capture(argumentCaptor),
- any(),
- any())
-
- val lastFilter = argumentCaptor.value
-
- assertTrue(lastFilter.hasAction(ACTION_1))
- assertTrue(lastFilter.hasAction(ACTION_2))
- assertTrue(lastFilter.hasCategory(CATEGORY_1))
- assertTrue(lastFilter.hasCategory(CATEGORY_1))
- }
-
- @Test
- fun testDispatchToCorrectReceiver() {
- intentFilter = IntentFilter(ACTION_1)
- intentFilterOther = IntentFilter(ACTION_2)
-
- userBroadcastDispatcher.registerReceiver(
- ReceiverData(broadcastReceiver, intentFilter, fakeExecutor, USER_HANDLE))
- userBroadcastDispatcher.registerReceiver(
- ReceiverData(broadcastReceiverOther, intentFilterOther, fakeExecutor, USER_HANDLE))
-
- val intent = Intent(ACTION_2)
-
- userBroadcastDispatcher.onReceive(mockContext, intent)
- testableLooper.processAllMessages()
- fakeExecutor.runAllReady()
-
- verify(broadcastReceiver, never()).onReceive(any(), any())
- verify(broadcastReceiverOther).onReceive(mockContext, intent)
- }
-
- @Test
- fun testDispatch_logger() {
- intentFilter = IntentFilter(ACTION_1)
- intentFilterOther = IntentFilter(ACTION_2)
-
- userBroadcastDispatcher.registerReceiver(
- ReceiverData(broadcastReceiver, intentFilter, fakeExecutor, USER_HANDLE))
- userBroadcastDispatcher.registerReceiver(
- ReceiverData(broadcastReceiverOther, intentFilterOther, fakeExecutor, USER_HANDLE))
-
- val intent = Intent(ACTION_2)
-
- userBroadcastDispatcher.onReceive(mockContext, intent)
- testableLooper.processAllMessages()
- fakeExecutor.runAllReady()
-
- val captor = ArgumentCaptor.forClass(Int::class.java)
- verify(logger)
- .logBroadcastReceived(captor.capture(), eq(USER_HANDLE.identifier), eq(intent))
- verify(logger).logBroadcastDispatched(captor.value, ACTION_2, broadcastReceiverOther)
- verify(logger, never())
- .logBroadcastDispatched(eq(captor.value), any(), eq(broadcastReceiver))
- }
-
- @Test
- fun testDispatchToCorrectReceiver_differentFiltersSameReceiver() {
- intentFilter = IntentFilter(ACTION_1)
- intentFilterOther = IntentFilter(ACTION_2)
-
- userBroadcastDispatcher.registerReceiver(
- ReceiverData(broadcastReceiver, intentFilter, fakeExecutor, USER_HANDLE))
- userBroadcastDispatcher.registerReceiver(
- ReceiverData(broadcastReceiver, intentFilterOther, fakeExecutor, USER_HANDLE))
-
- val intent = Intent(ACTION_2)
-
- userBroadcastDispatcher.onReceive(mockContext, intent)
- testableLooper.processAllMessages()
- fakeExecutor.runAllReady()
-
- verify(broadcastReceiver).onReceive(mockContext, intent)
- }
-
- @Test
- fun testDispatchIntentWithoutCategories() {
- intentFilter = IntentFilter(ACTION_1)
- intentFilter.addCategory(CATEGORY_1)
- intentFilterOther = IntentFilter(ACTION_1)
- intentFilterOther.addCategory(CATEGORY_2)
-
- userBroadcastDispatcher.registerReceiver(
- ReceiverData(broadcastReceiver, intentFilter, fakeExecutor, USER_HANDLE))
- userBroadcastDispatcher.registerReceiver(
- ReceiverData(broadcastReceiverOther, intentFilterOther, fakeExecutor, USER_HANDLE))
-
- val intent = Intent(ACTION_1)
-
- userBroadcastDispatcher.onReceive(mockContext, intent)
- testableLooper.processAllMessages()
- fakeExecutor.runAllReady()
-
- verify(broadcastReceiver).onReceive(mockContext, intent)
- verify(broadcastReceiverOther).onReceive(mockContext, intent)
- }
-
- @Test
- fun testPendingResult() {
- intentFilter = IntentFilter(ACTION_1)
- userBroadcastDispatcher.registerReceiver(
- ReceiverData(broadcastReceiver, intentFilter, fakeExecutor, USER_HANDLE))
-
- val intent = Intent(ACTION_1)
- userBroadcastDispatcher.onReceive(mockContext, intent)
-
- testableLooper.processAllMessages()
- fakeExecutor.runAllReady()
-
- verify(broadcastReceiver).onReceive(mockContext, intent)
- verify(broadcastReceiver).pendingResult = mPendingResult
}
@Test
@@ -333,4 +159,8 @@ class UserBroadcastDispatcherTest : SysuiTestCase() {
assertFalse(userBroadcastDispatcher.isReceiverReferenceHeld(broadcastReceiver))
}
+
+ private fun UserBroadcastDispatcher.getActionReceiver(action: String): ActionReceiver? {
+ return actionsToActionsReceivers.get(action)
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java
index 36398a6fc122..5b46b7fa4d9f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java
@@ -44,6 +44,7 @@ import android.app.IActivityManager;
import android.app.INotificationManager;
import android.app.Notification;
import android.app.PendingIntent;
+import android.content.pm.LauncherApps;
import android.hardware.display.AmbientDisplayConfiguration;
import android.hardware.face.FaceManager;
import android.os.Handler;
@@ -179,6 +180,8 @@ public class BubbleControllerTest extends SysuiTestCase {
private NotificationShadeWindowView mNotificationShadeWindowView;
@Mock
private IStatusBarService mStatusBarService;
+ @Mock
+ private LauncherApps mLauncherApps;
private BubbleData mBubbleData;
@@ -256,7 +259,8 @@ public class BubbleControllerTest extends SysuiTestCase {
mSysUiState,
mock(INotificationManager.class),
mStatusBarService,
- mWindowManager);
+ mWindowManager,
+ mLauncherApps);
mBubbleController.setExpandListener(mBubbleExpandListener);
// Get a reference to the BubbleController's entry listener
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleDataTest.java
index 1ca2f02db1bd..ed4e6865e508 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleDataTest.java
@@ -177,7 +177,7 @@ public class BubbleDataTest extends SysuiTestCase {
mBubbleData.setListener(mListener);
// Test
- mBubbleData.notificationEntryRemoved(
+ mBubbleData.dismissBubbleWithKey(
mEntryA1.getKey(), BubbleController.DISMISS_USER_GESTURE);
// Verify
@@ -300,13 +300,13 @@ public class BubbleDataTest extends SysuiTestCase {
mBubbleData.setListener(mListener);
mBubbleData.setMaxOverflowBubbles(1);
- mBubbleData.notificationEntryRemoved(
+ mBubbleData.dismissBubbleWithKey(
mEntryA1.getKey(), BubbleController.DISMISS_USER_GESTURE);
verifyUpdateReceived();
assertOverflowChangedTo(ImmutableList.of(mBubbleA1));
// Overflow max of 1 is reached; A1 is oldest, so it gets removed
- mBubbleData.notificationEntryRemoved(
+ mBubbleData.dismissBubbleWithKey(
mEntryA2.getKey(), BubbleController.DISMISS_USER_GESTURE);
verifyUpdateReceived();
assertOverflowChangedTo(ImmutableList.of(mBubbleA2));
@@ -328,13 +328,13 @@ public class BubbleDataTest extends SysuiTestCase {
mBubbleData.setListener(mListener);
// Test
- mBubbleData.notificationEntryRemoved(mEntryA1.getKey(),
+ mBubbleData.dismissBubbleWithKey(mEntryA1.getKey(),
BubbleController.DISMISS_NOTIF_CANCEL);
verifyUpdateReceived();
assertOverflowChangedTo(ImmutableList.of(mBubbleA2));
// Test
- mBubbleData.notificationEntryRemoved(mEntryA2.getKey(),
+ mBubbleData.dismissBubbleWithKey(mEntryA2.getKey(),
BubbleController.DISMISS_GROUP_CANCELLED);
verifyUpdateReceived();
assertOverflowChangedTo(ImmutableList.of());
@@ -415,7 +415,7 @@ public class BubbleDataTest extends SysuiTestCase {
mBubbleData.setListener(mListener);
// Test
- mBubbleData.notificationEntryRemoved(
+ mBubbleData.dismissBubbleWithKey(
mEntryA2.getKey(), BubbleController.DISMISS_USER_GESTURE);
verifyUpdateReceived();
// TODO: this should fail if things work as I expect them to?
@@ -436,7 +436,7 @@ public class BubbleDataTest extends SysuiTestCase {
mBubbleData.setListener(mListener);
// Test
- mBubbleData.notificationEntryRemoved(
+ mBubbleData.dismissBubbleWithKey(
mEntryA1.getKey(), BubbleController.DISMISS_USER_GESTURE);
verifyUpdateReceived();
assertOrderNotChanged();
@@ -456,7 +456,7 @@ public class BubbleDataTest extends SysuiTestCase {
mBubbleData.setListener(mListener);
// Test
- mBubbleData.notificationEntryRemoved(
+ mBubbleData.dismissBubbleWithKey(
mEntryA2.getKey(), BubbleController.DISMISS_NOTIF_CANCEL);
verifyUpdateReceived();
assertSelectionChangedTo(mBubbleB2);
@@ -531,7 +531,7 @@ public class BubbleDataTest extends SysuiTestCase {
mBubbleData.setListener(mListener);
// Test
- mBubbleData.notificationEntryRemoved(
+ mBubbleData.dismissBubbleWithKey(
mEntryA1.getKey(), BubbleController.DISMISS_USER_GESTURE);
// Verify the selection was cleared.
@@ -632,7 +632,7 @@ public class BubbleDataTest extends SysuiTestCase {
mBubbleData.setListener(mListener);
// Test
- mBubbleData.notificationEntryRemoved(
+ mBubbleData.dismissBubbleWithKey(
mEntryB2.getKey(), BubbleController.DISMISS_USER_GESTURE);
verifyUpdateReceived();
assertOrderChangedTo(mBubbleA2, mBubbleB1, mBubbleA1);
@@ -657,12 +657,12 @@ public class BubbleDataTest extends SysuiTestCase {
mBubbleData.setListener(mListener);
// Test
- mBubbleData.notificationEntryRemoved(
+ mBubbleData.dismissBubbleWithKey(
mEntryA2.getKey(), BubbleController.DISMISS_USER_GESTURE);
verifyUpdateReceived();
assertSelectionChangedTo(mBubbleB1);
- mBubbleData.notificationEntryRemoved(
+ mBubbleData.dismissBubbleWithKey(
mEntryB1.getKey(), BubbleController.DISMISS_USER_GESTURE);
verifyUpdateReceived();
assertSelectionChangedTo(mBubbleA1);
@@ -777,7 +777,7 @@ public class BubbleDataTest extends SysuiTestCase {
mBubbleData.setListener(mListener);
// Test
- mBubbleData.notificationEntryRemoved(
+ mBubbleData.dismissBubbleWithKey(
mEntryA1.getKey(), BubbleController.DISMISS_USER_GESTURE);
verifyUpdateReceived();
assertExpandedChangedTo(false);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/NewNotifPipelineBubbleControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/NewNotifPipelineBubbleControllerTest.java
index 1c70db3a548e..52c64cc40e79 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/NewNotifPipelineBubbleControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/NewNotifPipelineBubbleControllerTest.java
@@ -40,6 +40,7 @@ import android.app.IActivityManager;
import android.app.INotificationManager;
import android.app.Notification;
import android.app.PendingIntent;
+import android.content.pm.LauncherApps;
import android.content.res.Resources;
import android.hardware.display.AmbientDisplayConfiguration;
import android.hardware.face.FaceManager;
@@ -174,6 +175,8 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase {
private LockscreenLockIconController mLockIconController;
@Mock
private IStatusBarService mStatusBarService;
+ @Mock
+ private LauncherApps mLauncherApps;
private BubbleData mBubbleData;
@@ -241,7 +244,8 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase {
mSysUiState,
mock(INotificationManager.class),
mStatusBarService,
- mWindowManager);
+ mWindowManager,
+ mLauncherApps);
mBubbleController.addNotifCallback(mNotifCallback);
mBubbleController.setExpandListener(mBubbleExpandListener);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/TestableBubbleController.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/TestableBubbleController.java
index ab49134ee8c0..0a6d0716cb85 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/TestableBubbleController.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/TestableBubbleController.java
@@ -18,6 +18,7 @@ package com.android.systemui.bubbles;
import android.app.INotificationManager;
import android.content.Context;
+import android.content.pm.LauncherApps;
import android.view.WindowManager;
import com.android.internal.statusbar.IStatusBarService;
@@ -61,14 +62,15 @@ public class TestableBubbleController extends BubbleController {
SysUiState sysUiState,
INotificationManager notificationManager,
IStatusBarService statusBarService,
- WindowManager windowManager) {
+ WindowManager windowManager,
+ LauncherApps launcherApps) {
super(context,
notificationShadeWindowController, statusBarStateController, shadeController,
data, Runnable::run, configurationController, interruptionStateProvider,
zenModeController, lockscreenUserManager, groupManager, entryManager,
notifPipeline, featureFlags, dumpManager, floatingContentCoordinator,
dataRepository, sysUiState, notificationManager, statusBarService,
- windowManager);
+ windowManager, launcherApps);
setInflateSynchronously(true);
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/storage/BubbleVolatileRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bubbles/storage/BubbleVolatileRepositoryTest.kt
index 76c58339726c..7ea611c9c6a9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/storage/BubbleVolatileRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/storage/BubbleVolatileRepositoryTest.kt
@@ -102,6 +102,19 @@ class BubbleVolatileRepositoryTest : SysuiTestCase() {
eq(listOf("alice and bob")), eq(user10),
eq(LauncherApps.FLAG_CACHE_BUBBLE_SHORTCUTS))
}
+
+ @Test
+ fun testAddBubbleMatchesByKey() {
+ val bubble = BubbleEntity(0, "com.example.pkg", "shortcut-id", "key", 120, 0, "title")
+ repository.addBubbles(listOf(bubble))
+ assertEquals(bubble, repository.bubbles.get(0))
+
+ // Same key as first bubble but different entry
+ val bubbleModified = BubbleEntity(0, "com.example.pkg", "shortcut-id", "key", 120, 0,
+ "different title")
+ repository.addBubbles(listOf(bubbleModified))
+ assertEquals(bubbleModified, repository.bubbles.get(0))
+ }
}
private const val PKG_MESSENGER = "com.example.messenger"
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/storage/BubbleXmlHelperTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bubbles/storage/BubbleXmlHelperTest.kt
index 81687c7fbe1a..8cf4534ecdce 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/storage/BubbleXmlHelperTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/storage/BubbleXmlHelperTest.kt
@@ -55,7 +55,7 @@ class BubbleXmlHelperTest : SysuiTestCase() {
fun testReadXml() {
val src = """
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
-<bs>
+<bs v="1">
<bb uid="0" pkg="com.example.messenger" sid="shortcut-1" key="k1" h="120" hid="0" />
<bb uid="10" pkg="com.example.chat" sid="alice and bob" key="k2" h="0" hid="16537428" t="title" />
<bb uid="0" pkg="com.example.messenger" sid="shortcut-2" key="k3" h="120" hid="0" />
@@ -64,4 +64,19 @@ class BubbleXmlHelperTest : SysuiTestCase() {
val actual = readXml(ByteArrayInputStream(src.toByteArray(Charsets.UTF_8)))
assertEquals("failed parsing bubbles from xml\n$src", bubbles, actual)
}
+
+ // TODO: We should handle upgrades gracefully but this is v1
+ @Test
+ fun testUpgradeDropsPreviousData() {
+ val src = """
+<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
+<bs>
+<bb uid="0" pkg="com.example.messenger" sid="shortcut-1" key="k1" h="120" hid="0" />
+<bb uid="10" pkg="com.example.chat" sid="alice and bob" key="k2" h="0" hid="16537428" t="title" />
+<bb uid="0" pkg="com.example.messenger" sid="shortcut-2" key="k3" h="120" hid="0" />
+</bs>
+ """.trimIndent()
+ val actual = readXml(ByteArrayInputStream(src.toByteArray(Charsets.UTF_8)))
+ assertEquals("failed parsing bubbles from xml\n$src", emptyList<BubbleEntity>(), actual)
+ }
} \ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
index 73aaeffd6044..1cdc02fdd01a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
@@ -41,12 +41,10 @@ import com.android.systemui.SysuiTestCase;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dock.DockManager;
import com.android.systemui.statusbar.phone.DozeParameters;
-import com.android.systemui.util.concurrency.FakeExecutor;
import com.android.systemui.util.sensors.AsyncSensorManager;
import com.android.systemui.util.sensors.FakeProximitySensor;
import com.android.systemui.util.sensors.FakeSensorManager;
import com.android.systemui.util.sensors.ProximitySensor;
-import com.android.systemui.util.time.FakeSystemClock;
import com.android.systemui.util.wakelock.WakeLock;
import com.android.systemui.util.wakelock.WakeLockFake;
@@ -72,11 +70,12 @@ public class DozeTriggersTest extends SysuiTestCase {
private BroadcastDispatcher mBroadcastDispatcher;
@Mock
private DockManager mDockManager;
+ @Mock
+ private ProximitySensor.ProximityCheck mProximityCheck;
private DozeTriggers mTriggers;
private FakeSensorManager mSensors;
private Sensor mTapSensor;
private FakeProximitySensor mProximitySensor;
- private FakeExecutor mFakeExecutor = new FakeExecutor(new FakeSystemClock());
@Before
public void setUp() throws Exception {
@@ -91,8 +90,8 @@ public class DozeTriggersTest extends SysuiTestCase {
mProximitySensor = new FakeProximitySensor(getContext().getResources(), asyncSensorManager);
mTriggers = new DozeTriggers(mContext, mMachine, mHost, mAlarmManager, config, parameters,
- asyncSensorManager, mFakeExecutor, wakeLock, true,
- mDockManager, mProximitySensor, mock(DozeLog.class), mBroadcastDispatcher);
+ asyncSensorManager, wakeLock, true, mDockManager, mProximitySensor,
+ mProximityCheck, mock(DozeLog.class), mBroadcastDispatcher);
waitForSensorManager();
}
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 329af2b7f62b..ac8c6710e041 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java
@@ -16,14 +16,14 @@
package com.android.systemui.globalactions;
-import static com.google.common.truth.Truth.assertThat;
+import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED;
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertTrue;
+import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
@@ -34,11 +34,13 @@ import android.app.IActivityManager;
import android.app.admin.DevicePolicyManager;
import android.app.trust.TrustManager;
import android.content.ContentResolver;
+import android.content.pm.UserInfo;
import android.content.res.Resources;
import android.graphics.Color;
import android.media.AudioManager;
import android.net.ConnectivityManager;
import android.os.Handler;
+import android.os.RemoteException;
import android.os.UserManager;
import android.service.dreams.IDreamManager;
import android.telephony.TelephonyManager;
@@ -81,6 +83,7 @@ import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.util.List;
import java.util.concurrent.Executor;
@SmallTest
@@ -244,6 +247,14 @@ public class GlobalActionsDialogTest extends SysuiTestCase {
.log(event);
}
+ @SafeVarargs
+ private static <T> void assertItemsOfType(List<T> stuff, Class<? extends T>... classes) {
+ assertThat(stuff).hasSize(classes.length);
+ for (int i = 0; i < stuff.size(); i++) {
+ assertThat(stuff.get(i)).isInstanceOf(classes[i]);
+ }
+ }
+
@Test
public void testCreateActionItems_maxThree_noOverflow() {
mGlobalActionsDialog = spy(mGlobalActionsDialog);
@@ -259,9 +270,12 @@ public class GlobalActionsDialogTest extends SysuiTestCase {
doReturn(actions).when(mGlobalActionsDialog).getDefaultActions();
mGlobalActionsDialog.createActionItems();
- assertEquals(3, mGlobalActionsDialog.mItems.size());
- assertEquals(0, mGlobalActionsDialog.mOverflowItems.size());
- assertEquals(0, mGlobalActionsDialog.mPowerItems.size());
+ assertItemsOfType(mGlobalActionsDialog.mItems,
+ GlobalActionsDialog.EmergencyAction.class,
+ GlobalActionsDialog.ShutDownAction.class,
+ GlobalActionsDialog.RestartAction.class);
+ assertThat(mGlobalActionsDialog.mOverflowItems).isEmpty();
+ assertThat(mGlobalActionsDialog.mPowerItems).isEmpty();
}
@Test
@@ -275,55 +289,53 @@ public class GlobalActionsDialogTest extends SysuiTestCase {
doReturn(true).when(mGlobalActionsDialog).shouldDisplayLockdown(any());
String[] actions = {
GlobalActionsDialog.GLOBAL_ACTION_KEY_EMERGENCY,
+ GlobalActionsDialog.GLOBAL_ACTION_KEY_LOCKDOWN,
GlobalActionsDialog.GLOBAL_ACTION_KEY_POWER,
GlobalActionsDialog.GLOBAL_ACTION_KEY_RESTART,
- GlobalActionsDialog.GLOBAL_ACTION_KEY_LOCKDOWN,
};
doReturn(actions).when(mGlobalActionsDialog).getDefaultActions();
mGlobalActionsDialog.createActionItems();
- assertEquals(3, mGlobalActionsDialog.mItems.size());
- assertEquals(0, mGlobalActionsDialog.mOverflowItems.size());
- assertEquals(2, mGlobalActionsDialog.mPowerItems.size());
-
- // PowerOptionsAction should appear immediately after the Emergency action
-
- GlobalActionsDialog.Action firstItem = mGlobalActionsDialog.mItems.get(0);
- GlobalActionsDialog.Action secondItem = mGlobalActionsDialog.mItems.get(1);
-
- assertTrue(firstItem instanceof GlobalActionsDialog.EmergencyAction);
- assertTrue(secondItem instanceof GlobalActionsDialog.PowerOptionsAction);
+ assertItemsOfType(mGlobalActionsDialog.mItems,
+ GlobalActionsDialog.EmergencyAction.class,
+ GlobalActionsDialog.LockDownAction.class,
+ GlobalActionsDialog.PowerOptionsAction.class);
+ assertThat(mGlobalActionsDialog.mOverflowItems).isEmpty();
+ assertItemsOfType(mGlobalActionsDialog.mPowerItems,
+ GlobalActionsDialog.ShutDownAction.class,
+ GlobalActionsDialog.RestartAction.class);
}
@Test
- public void testCreateActionItems_maxThree_condensePower_noEmergency() {
+ public void testCreateActionItems_maxThree_condensePower_splitPower() {
mGlobalActionsDialog = spy(mGlobalActionsDialog);
// allow 3 items to be shown
doReturn(3).when(mGlobalActionsDialog).getMaxShownPowerItems();
// make sure lockdown action will be shown
doReturn(true).when(mGlobalActionsDialog).shouldDisplayLockdown(any());
+ // make sure bugreport also shown
+ doReturn(true).when(mGlobalActionsDialog).shouldDisplayBugReport(any());
// ensure items are not blocked by keyguard or device provisioning
doReturn(true).when(mGlobalActionsDialog).shouldShowAction(any());
String[] actions = {
+ GlobalActionsDialog.GLOBAL_ACTION_KEY_EMERGENCY,
+ GlobalActionsDialog.GLOBAL_ACTION_KEY_LOCKDOWN,
GlobalActionsDialog.GLOBAL_ACTION_KEY_POWER,
+ GlobalActionsDialog.GLOBAL_ACTION_KEY_BUGREPORT,
GlobalActionsDialog.GLOBAL_ACTION_KEY_RESTART,
- GlobalActionsDialog.GLOBAL_ACTION_KEY_SCREENSHOT,
- GlobalActionsDialog.GLOBAL_ACTION_KEY_LOCKDOWN,
};
doReturn(actions).when(mGlobalActionsDialog).getDefaultActions();
mGlobalActionsDialog.createActionItems();
- assertEquals(3, mGlobalActionsDialog.mItems.size());
- assertEquals(0, mGlobalActionsDialog.mOverflowItems.size());
- assertEquals(2, mGlobalActionsDialog.mPowerItems.size());
-
- // When Emergency isn't used, PowerOptionsAction should be first
-
- GlobalActionsDialog.Action firstItem = mGlobalActionsDialog.mItems.get(0);
- GlobalActionsDialog.Action secondItem = mGlobalActionsDialog.mItems.get(1);
-
- assertTrue(firstItem instanceof GlobalActionsDialog.PowerOptionsAction);
- assertTrue(secondItem instanceof GlobalActionsDialog.ScreenshotAction);
+ assertItemsOfType(mGlobalActionsDialog.mItems,
+ GlobalActionsDialog.EmergencyAction.class,
+ GlobalActionsDialog.LockDownAction.class,
+ GlobalActionsDialog.PowerOptionsAction.class);
+ assertItemsOfType(mGlobalActionsDialog.mOverflowItems,
+ GlobalActionsDialog.BugReportAction.class);
+ assertItemsOfType(mGlobalActionsDialog.mPowerItems,
+ GlobalActionsDialog.ShutDownAction.class,
+ GlobalActionsDialog.RestartAction.class);
}
@Test
@@ -337,24 +349,23 @@ public class GlobalActionsDialogTest extends SysuiTestCase {
doReturn(true).when(mGlobalActionsDialog).shouldShowAction(any());
String[] actions = {
GlobalActionsDialog.GLOBAL_ACTION_KEY_EMERGENCY,
+ GlobalActionsDialog.GLOBAL_ACTION_KEY_LOCKDOWN,
GlobalActionsDialog.GLOBAL_ACTION_KEY_POWER,
GlobalActionsDialog.GLOBAL_ACTION_KEY_RESTART,
- GlobalActionsDialog.GLOBAL_ACTION_KEY_LOCKDOWN,
GlobalActionsDialog.GLOBAL_ACTION_KEY_SCREENSHOT
};
doReturn(actions).when(mGlobalActionsDialog).getDefaultActions();
mGlobalActionsDialog.createActionItems();
- assertEquals(4, mGlobalActionsDialog.mItems.size());
- assertEquals(0, mGlobalActionsDialog.mOverflowItems.size());
- assertEquals(2, mGlobalActionsDialog.mPowerItems.size());
-
- // with four items, make sure power still shows up immediately after Emergency
- GlobalActionsDialog.Action firstItem = mGlobalActionsDialog.mItems.get(0);
- GlobalActionsDialog.Action secondItem = mGlobalActionsDialog.mItems.get(1);
-
- assertTrue(firstItem instanceof GlobalActionsDialog.EmergencyAction);
- assertTrue(secondItem instanceof GlobalActionsDialog.PowerOptionsAction);
+ assertItemsOfType(mGlobalActionsDialog.mItems,
+ GlobalActionsDialog.EmergencyAction.class,
+ GlobalActionsDialog.LockDownAction.class,
+ GlobalActionsDialog.PowerOptionsAction.class,
+ GlobalActionsDialog.ScreenshotAction.class);
+ assertThat(mGlobalActionsDialog.mOverflowItems).isEmpty();
+ assertItemsOfType(mGlobalActionsDialog.mPowerItems,
+ GlobalActionsDialog.ShutDownAction.class,
+ GlobalActionsDialog.RestartAction.class);
}
@Test
@@ -364,20 +375,26 @@ public class GlobalActionsDialogTest extends SysuiTestCase {
doReturn(3).when(mGlobalActionsDialog).getMaxShownPowerItems();
// make sure lockdown action will be shown
doReturn(true).when(mGlobalActionsDialog).shouldDisplayLockdown(any());
+ // make sure bugreport is also shown
+ doReturn(true).when(mGlobalActionsDialog).shouldDisplayBugReport(any());
// ensure items are not blocked by keyguard or device provisioning
doReturn(true).when(mGlobalActionsDialog).shouldShowAction(any());
String[] actions = {
GlobalActionsDialog.GLOBAL_ACTION_KEY_EMERGENCY,
GlobalActionsDialog.GLOBAL_ACTION_KEY_POWER,
- GlobalActionsDialog.GLOBAL_ACTION_KEY_SCREENSHOT,
+ GlobalActionsDialog.GLOBAL_ACTION_KEY_BUGREPORT,
GlobalActionsDialog.GLOBAL_ACTION_KEY_LOCKDOWN,
};
doReturn(actions).when(mGlobalActionsDialog).getDefaultActions();
mGlobalActionsDialog.createActionItems();
- assertEquals(3, mGlobalActionsDialog.mItems.size());
- assertEquals(1, mGlobalActionsDialog.mOverflowItems.size());
- assertEquals(0, mGlobalActionsDialog.mPowerItems.size());
+ assertItemsOfType(mGlobalActionsDialog.mItems,
+ GlobalActionsDialog.EmergencyAction.class,
+ GlobalActionsDialog.ShutDownAction.class,
+ GlobalActionsDialog.BugReportAction.class);
+ assertItemsOfType(mGlobalActionsDialog.mOverflowItems,
+ GlobalActionsDialog.LockDownAction.class);
+ assertThat(mGlobalActionsDialog.mPowerItems).isEmpty();
}
@Test
@@ -398,12 +415,17 @@ public class GlobalActionsDialogTest extends SysuiTestCase {
doReturn(actions).when(mGlobalActionsDialog).getDefaultActions();
mGlobalActionsDialog.createActionItems();
- assertEquals(4, mGlobalActionsDialog.mItems.size());
- assertEquals(0, mGlobalActionsDialog.mOverflowItems.size());
+ assertItemsOfType(mGlobalActionsDialog.mItems,
+ GlobalActionsDialog.EmergencyAction.class,
+ GlobalActionsDialog.ShutDownAction.class,
+ GlobalActionsDialog.RestartAction.class,
+ GlobalActionsDialog.LockDownAction.class);
+ assertThat(mGlobalActionsDialog.mOverflowItems).isEmpty();
+ assertThat(mGlobalActionsDialog.mPowerItems).isEmpty();
}
@Test
- public void testCreateActionItems_maxThree_itemNotShown() {
+ public void testCreateActionItems_maxThree_lockdownDisabled_doesNotShowLockdown() {
mGlobalActionsDialog = spy(mGlobalActionsDialog);
// allow only 3 items to be shown
doReturn(3).when(mGlobalActionsDialog).getMaxShownPowerItems();
@@ -419,15 +441,51 @@ public class GlobalActionsDialogTest extends SysuiTestCase {
doReturn(actions).when(mGlobalActionsDialog).getDefaultActions();
mGlobalActionsDialog.createActionItems();
- assertEquals(3, mGlobalActionsDialog.mItems.size());
- assertEquals(0, mGlobalActionsDialog.mOverflowItems.size());
+ assertItemsOfType(mGlobalActionsDialog.mItems,
+ GlobalActionsDialog.EmergencyAction.class,
+ GlobalActionsDialog.ShutDownAction.class,
+ GlobalActionsDialog.RestartAction.class);
+ assertThat(mGlobalActionsDialog.mOverflowItems).isEmpty();
+ assertThat(mGlobalActionsDialog.mPowerItems).isEmpty();
+ }
+
+ @Test
+ public void testCreateActionItems_shouldShowAction_excludeBugReport() {
+ mGlobalActionsDialog = spy(mGlobalActionsDialog);
+ // allow only 3 items to be shown
+ doReturn(3).when(mGlobalActionsDialog).getMaxShownPowerItems();
+ doReturn(true).when(mGlobalActionsDialog).shouldDisplayBugReport(any());
+ // exclude bugreport in shouldShowAction to demonstrate how any button can be removed
+ doAnswer(
+ invocation -> !(invocation.getArgument(0)
+ instanceof GlobalActionsDialog.BugReportAction))
+ .when(mGlobalActionsDialog).shouldShowAction(any());
+
+ String[] actions = {
+ GlobalActionsDialog.GLOBAL_ACTION_KEY_EMERGENCY,
+ // bugreport action not allowed
+ GlobalActionsDialog.GLOBAL_ACTION_KEY_BUGREPORT,
+ GlobalActionsDialog.GLOBAL_ACTION_KEY_POWER,
+ GlobalActionsDialog.GLOBAL_ACTION_KEY_RESTART,
+ };
+ doReturn(actions).when(mGlobalActionsDialog).getDefaultActions();
+ mGlobalActionsDialog.createActionItems();
+
+ assertItemsOfType(mGlobalActionsDialog.mItems,
+ GlobalActionsDialog.EmergencyAction.class,
+ GlobalActionsDialog.ShutDownAction.class,
+ GlobalActionsDialog.RestartAction.class);
+ assertThat(mGlobalActionsDialog.mOverflowItems).isEmpty();
+ assertThat(mGlobalActionsDialog.mPowerItems).isEmpty();
}
@Test
- public void testShouldShowLockScreenMessage() {
+ public void testShouldShowLockScreenMessage() 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 = false;
setupDefaultActions();
when(mWalletPlugin.onPanelShown(any(), anyBoolean())).thenReturn(mWalletController);
@@ -438,13 +496,19 @@ public class GlobalActionsDialogTest extends SysuiTestCase {
GlobalActionsDialog.ActionsDialog dialog = mGlobalActionsDialog.mDialog;
assertThat(dialog).isNotNull();
assertThat(dialog.mLockMessageContainer.getVisibility()).isEqualTo(View.VISIBLE);
+
+ // Dismiss the dialog so that it does not pollute other tests
+ mGlobalActionsDialog.showOrHideDialog(false, true, mWalletPlugin);
}
@Test
- public void testShouldNotShowLockScreenMessage_whenWalletOrControlsShownOnLockScreen() {
+ public void testShouldNotShowLockScreenMessage_whenWalletOrControlsShownOnLockScreen()
+ 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;
setupDefaultActions();
when(mWalletPlugin.onPanelShown(any(), anyBoolean())).thenReturn(mWalletController);
@@ -455,13 +519,20 @@ public class GlobalActionsDialogTest extends SysuiTestCase {
GlobalActionsDialog.ActionsDialog dialog = mGlobalActionsDialog.mDialog;
assertThat(dialog).isNotNull();
assertThat(dialog.mLockMessageContainer.getVisibility()).isEqualTo(View.GONE);
+
+ // Dismiss the dialog so that it does not pollute other tests
+ mGlobalActionsDialog.showOrHideDialog(false, true, mWalletPlugin);
}
@Test
- public void testShouldNotShowLockScreenMessage_whenControlsAndWalletBothDisabled() {
+ public void testShouldNotShowLockScreenMessage_whenControlsAndWalletBothDisabled()
+ 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;
setupDefaultActions();
when(mWalletPlugin.onPanelShown(any(), anyBoolean())).thenReturn(mWalletController);
@@ -473,13 +544,20 @@ public class GlobalActionsDialogTest extends SysuiTestCase {
GlobalActionsDialog.ActionsDialog dialog = mGlobalActionsDialog.mDialog;
assertThat(dialog).isNotNull();
assertThat(dialog.mLockMessageContainer.getVisibility()).isEqualTo(View.GONE);
+
+ // Dismiss the dialog so that it does not pollute other tests
+ mGlobalActionsDialog.showOrHideDialog(false, true, mWalletPlugin);
+ }
+
+ private UserInfo newUserInfo() {
+ return new UserInfo(0, null, null, UserInfo.FLAG_PRIMARY, null);
}
private void setupDefaultActions() {
String[] actions = {
+ GlobalActionsDialog.GLOBAL_ACTION_KEY_EMERGENCY,
GlobalActionsDialog.GLOBAL_ACTION_KEY_POWER,
GlobalActionsDialog.GLOBAL_ACTION_KEY_RESTART,
- GlobalActionsDialog.GLOBAL_ACTION_KEY_SCREENSHOT,
};
doReturn(actions).when(mGlobalActionsDialog).getDefaultActions();
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsImeTest.java b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsImeTest.java
index f38c722ad2db..8b254e3a2df0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsImeTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsImeTest.java
@@ -60,8 +60,13 @@ public class GlobalActionsImeTest extends SysuiTestCase {
public void testGlobalActions_doesntStealImeControl() throws Exception {
turnScreenOn();
final TestActivity activity = mActivityTestRule.launchActivity(null);
-
- waitUntil("Ime is visible", activity::isImeVisible);
+ boolean isImeVisible = waitUntil(activity::isImeVisible);
+ if (!isImeVisible) {
+ // Sometimes the keyboard is dismissed when run with other tests. Bringing it up again
+ // should improve test reliability
+ activity.showIme();
+ waitUntil("Ime is not visible", activity::isImeVisible);
+ }
executeShellCommand("input keyevent --longpress POWER");
@@ -91,17 +96,23 @@ public class GlobalActionsImeTest extends SysuiTestCase {
private static void waitUntil(String message, BooleanSupplier predicate)
throws Exception {
+ if (!waitUntil(predicate)) {
+ fail(message);
+ }
+ }
+
+ private static boolean waitUntil(BooleanSupplier predicate) throws Exception {
int sleep = 125;
final long timeout = SystemClock.uptimeMillis() + 10_000; // 10 second timeout
while (SystemClock.uptimeMillis() < timeout) {
if (predicate.getAsBoolean()) {
- return; // okay
+ return true;
}
Thread.sleep(sleep);
sleep *= 5;
sleep = Math.min(2000, sleep);
}
- fail(message);
+ return false;
}
private static void executeShellCommand(String cmd) {
@@ -130,6 +141,7 @@ public class GlobalActionsImeTest extends SysuiTestCase {
WindowInsetsController.OnControllableInsetsChangedListener,
View.OnApplyWindowInsetsListener {
+ private EditText mEditText;
boolean mHasFocus;
boolean mControlsIme;
boolean mImeVisible;
@@ -137,14 +149,16 @@ public class GlobalActionsImeTest extends SysuiTestCase {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ mEditText = new EditText(this);
+ mEditText.setCursorVisible(false); // Otherwise, main thread doesn't go idle.
+ setContentView(mEditText);
+ showIme();
+ }
- EditText content = new EditText(this);
- content.setCursorVisible(false); // Otherwise, main thread doesn't go idle.
- setContentView(content);
- content.requestFocus();
-
+ private void showIme() {
+ mEditText.requestFocus();
getWindow().getDecorView().setOnApplyWindowInsetsListener(this);
- WindowInsetsController wic = content.getWindowInsetsController();
+ WindowInsetsController wic = mEditText.getWindowInsetsController();
wic.addOnControllableInsetsChangedListener(this);
wic.show(ime());
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/KeyguardMediaControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/KeyguardMediaControllerTest.kt
index 9aee11e4924f..008dc12bba03 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/KeyguardMediaControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/KeyguardMediaControllerTest.kt
@@ -27,6 +27,7 @@ import com.android.systemui.statusbar.StatusBarState
import com.android.systemui.statusbar.SysuiStatusBarStateController
import com.android.systemui.statusbar.notification.stack.MediaHeaderView
import com.android.systemui.statusbar.phone.KeyguardBypassController
+import com.android.systemui.util.mockito.capture
import org.junit.Before
import org.junit.Rule
import org.junit.Test
@@ -94,7 +95,7 @@ class KeyguardMediaControllerTest : SysuiTestCase() {
private fun triggerVisibilityListener() {
keyguardMediaController.attach(mediaHeaderView)
- verify(mediaHost).visibleChangedListener = visibilityListener.capture()
+ verify(mediaHost).addVisibilityChangeListener(capture(visibilityListener))
visibilityListener.value.invoke(true)
}
} \ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt
index 737ced63eed0..b7f317b38743 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt
@@ -25,12 +25,14 @@ import android.media.session.MediaSession
import android.media.session.PlaybackState
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
+import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.ImageButton
import android.widget.ImageView
import android.widget.SeekBar
import android.widget.TextView
+import androidx.constraintlayout.widget.ConstraintSet
import androidx.lifecycle.LiveData
import androidx.test.filters.SmallTest
import com.android.systemui.R
@@ -75,9 +77,11 @@ public class MediaControlPanelTest : SysuiTestCase() {
@Mock private lateinit var holder: PlayerViewHolder
@Mock private lateinit var view: TransitionLayout
- @Mock private lateinit var mediaHostStatesManager: MediaHostStatesManager
@Mock private lateinit var seekBarViewModel: SeekBarViewModel
@Mock private lateinit var seekBarData: LiveData<SeekBarViewModel.Progress>
+ @Mock private lateinit var mediaViewController: MediaViewController
+ @Mock private lateinit var expandedSet: ConstraintSet
+ @Mock private lateinit var collapsedSet: ConstraintSet
private lateinit var appIcon: ImageView
private lateinit var appName: TextView
private lateinit var albumView: ImageView
@@ -86,6 +90,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
private lateinit var seamless: ViewGroup
private lateinit var seamlessIcon: ImageView
private lateinit var seamlessText: TextView
+ private lateinit var seamlessFallback: ImageView
private lateinit var seekBar: SeekBar
private lateinit var elapsedTimeView: TextView
private lateinit var totalTimeView: TextView
@@ -104,8 +109,10 @@ public class MediaControlPanelTest : SysuiTestCase() {
@Before
fun setUp() {
bgExecutor = FakeExecutor(FakeSystemClock())
+ whenever(mediaViewController.expandedLayout).thenReturn(expandedSet)
+ whenever(mediaViewController.collapsedLayout).thenReturn(collapsedSet)
- player = MediaControlPanel(context, bgExecutor, activityStarter, mediaHostStatesManager,
+ player = MediaControlPanel(context, bgExecutor, activityStarter, mediaViewController,
seekBarViewModel)
whenever(seekBarViewModel.progress).thenReturn(seekBarData)
@@ -130,6 +137,8 @@ public class MediaControlPanelTest : SysuiTestCase() {
whenever(holder.seamlessIcon).thenReturn(seamlessIcon)
seamlessText = TextView(context)
whenever(holder.seamlessText).thenReturn(seamlessText)
+ seamlessFallback = ImageView(context)
+ whenever(holder.seamlessFallback).thenReturn(seamlessFallback)
seekBar = SeekBar(context)
whenever(holder.seekBar).thenReturn(seekBar)
elapsedTimeView = TextView(context)
@@ -172,7 +181,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
@Test
fun bindWhenUnattached() {
val state = MediaData(true, BG_COLOR, APP, null, ARTIST, TITLE, null, emptyList(),
- emptyList(), PACKAGE, null, null, device, null)
+ emptyList(), PACKAGE, null, null, device, true, null)
player.bind(state)
assertThat(player.isPlaying()).isFalse()
}
@@ -181,7 +190,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
fun bindText() {
player.attach(holder)
val state = MediaData(true, BG_COLOR, APP, null, ARTIST, TITLE, null, emptyList(),
- emptyList(), PACKAGE, session.getSessionToken(), null, device, null)
+ emptyList(), PACKAGE, session.getSessionToken(), null, device, true, null)
player.bind(state)
assertThat(appName.getText()).isEqualTo(APP)
assertThat(titleText.getText()).isEqualTo(TITLE)
@@ -192,7 +201,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
fun bindBackgroundColor() {
player.attach(holder)
val state = MediaData(true, BG_COLOR, APP, null, ARTIST, TITLE, null, emptyList(),
- emptyList(), PACKAGE, session.getSessionToken(), null, device, null)
+ emptyList(), PACKAGE, session.getSessionToken(), null, device, true, null)
player.bind(state)
val list = ArgumentCaptor.forClass(ColorStateList::class.java)
verify(view).setBackgroundTintList(list.capture())
@@ -203,7 +212,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
fun bindDevice() {
player.attach(holder)
val state = MediaData(true, BG_COLOR, APP, null, ARTIST, TITLE, null, emptyList(),
- emptyList(), PACKAGE, session.getSessionToken(), null, device, null)
+ emptyList(), PACKAGE, session.getSessionToken(), null, device, true, null)
player.bind(state)
assertThat(seamlessText.getText()).isEqualTo(DEVICE_NAME)
assertThat(seamless.isEnabled()).isTrue()
@@ -211,23 +220,37 @@ public class MediaControlPanelTest : SysuiTestCase() {
@Test
fun bindDisabledDevice() {
+ seamless.id = 1
+ seamlessFallback.id = 2
player.attach(holder)
val state = MediaData(true, BG_COLOR, APP, null, ARTIST, TITLE, null, emptyList(),
- emptyList(), PACKAGE, session.getSessionToken(), null, disabledDevice, null)
+ emptyList(), PACKAGE, session.getSessionToken(), null, disabledDevice, true, null)
player.bind(state)
- assertThat(seamless.isEnabled()).isFalse()
- assertThat(seamlessText.getText()).isEqualTo(context.getResources().getString(
- R.string.media_seamless_remote_device))
+ verify(expandedSet).setVisibility(seamless.id, View.GONE)
+ verify(expandedSet).setVisibility(seamlessFallback.id, View.VISIBLE)
+ verify(collapsedSet).setVisibility(seamless.id, View.GONE)
+ verify(collapsedSet).setVisibility(seamlessFallback.id, View.VISIBLE)
}
@Test
fun bindNullDevice() {
player.attach(holder)
val state = MediaData(true, BG_COLOR, APP, null, ARTIST, TITLE, null, emptyList(),
- emptyList(), PACKAGE, session.getSessionToken(), null, null, null)
+ emptyList(), PACKAGE, session.getSessionToken(), null, null, true, null)
player.bind(state)
assertThat(seamless.isEnabled()).isTrue()
assertThat(seamlessText.getText()).isEqualTo(context.getResources().getString(
com.android.internal.R.string.ext_media_seamless_action))
}
+
+ @Test
+ fun bindDeviceResumptionPlayer() {
+ player.attach(holder)
+ val state = MediaData(true, BG_COLOR, APP, null, ARTIST, TITLE, null, emptyList(),
+ emptyList(), PACKAGE, session.getSessionToken(), null, device, true, null,
+ resumption = true)
+ player.bind(state)
+ assertThat(seamlessText.getText()).isEqualTo(DEVICE_NAME)
+ assertThat(seamless.isEnabled()).isFalse()
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java
index bed5c9eb6df5..9fdd9ad744ff 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java
@@ -79,7 +79,8 @@ public class MediaDataCombineLatestTest extends SysuiTestCase {
mManager.addListener(mListener);
mMediaData = new MediaData(true, BG_COLOR, APP, null, ARTIST, TITLE, null,
- new ArrayList<>(), new ArrayList<>(), PACKAGE, null, null, null, null, KEY, false);
+ new ArrayList<>(), new ArrayList<>(), PACKAGE, null, null, null, true, null, false,
+ KEY, false);
mDeviceData = new MediaDeviceData(true, null, DEVICE_NAME);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt
new file mode 100644
index 000000000000..e56bbabfdc0b
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt
@@ -0,0 +1,249 @@
+package com.android.systemui.media
+
+import android.app.Notification.MediaStyle
+import android.app.PendingIntent
+import android.media.MediaDescription
+import android.media.MediaMetadata
+import android.media.session.MediaController
+import android.media.session.MediaSession
+import android.service.notification.StatusBarNotification
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper.RunWithLooper
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.broadcast.BroadcastDispatcher
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.statusbar.SbnBuilder
+import com.android.systemui.util.concurrency.FakeExecutor
+import com.android.systemui.util.mockito.eq
+import com.android.systemui.util.time.FakeSystemClock
+import com.google.common.truth.Truth.assertThat
+import org.junit.After
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito
+import org.mockito.Mockito.mock
+import org.mockito.Mockito.verify
+import org.mockito.junit.MockitoJUnit
+import org.mockito.Mockito.`when` as whenever
+
+private const val KEY = "KEY"
+private const val PACKAGE_NAME = "com.android.systemui"
+private const val APP_NAME = "SystemUI"
+private const val SESSION_ARTIST = "artist"
+private const val SESSION_TITLE = "title"
+
+private fun <T> anyObject(): T {
+ return Mockito.anyObject<T>()
+}
+
+@SmallTest
+@RunWithLooper(setAsMainLooper = true)
+@RunWith(AndroidTestingRunner::class)
+class MediaDataManagerTest : SysuiTestCase() {
+
+ @Mock lateinit var mediaControllerFactory: MediaControllerFactory
+ @Mock lateinit var controller: MediaController
+ lateinit var session: MediaSession
+ lateinit var metadataBuilder: MediaMetadata.Builder
+ lateinit var backgroundExecutor: FakeExecutor
+ lateinit var foregroundExecutor: FakeExecutor
+ @Mock lateinit var dumpManager: DumpManager
+ @Mock lateinit var broadcastDispatcher: BroadcastDispatcher
+ @Mock lateinit var mediaTimeoutListener: MediaTimeoutListener
+ @Mock lateinit var mediaResumeListener: MediaResumeListener
+ @Mock lateinit var pendingIntent: PendingIntent
+ @JvmField @Rule val mockito = MockitoJUnit.rule()
+ lateinit var mediaDataManager: MediaDataManager
+ lateinit var mediaNotification: StatusBarNotification
+
+ @Before
+ fun setup() {
+ foregroundExecutor = FakeExecutor(FakeSystemClock())
+ backgroundExecutor = FakeExecutor(FakeSystemClock())
+ mediaDataManager = MediaDataManager(context, backgroundExecutor, foregroundExecutor,
+ mediaControllerFactory, broadcastDispatcher, dumpManager,
+ mediaTimeoutListener, mediaResumeListener, useMediaResumption = true,
+ useQsMediaPlayer = true)
+ session = MediaSession(context, "MediaDataManagerTestSession")
+ mediaNotification = SbnBuilder().run {
+ setPkg(PACKAGE_NAME)
+ modifyNotification(context).also {
+ it.setSmallIcon(android.R.drawable.ic_media_pause)
+ it.setStyle(MediaStyle().apply { setMediaSession(session.sessionToken) })
+ }
+ build()
+ }
+ metadataBuilder = MediaMetadata.Builder().apply {
+ putString(MediaMetadata.METADATA_KEY_ARTIST, SESSION_ARTIST)
+ putString(MediaMetadata.METADATA_KEY_TITLE, SESSION_TITLE)
+ }
+ whenever(mediaControllerFactory.create(eq(session.sessionToken))).thenReturn(controller)
+ }
+
+ @After
+ fun tearDown() {
+ session.release()
+ mediaDataManager.destroy()
+ }
+
+ @Test
+ fun testHasActiveMedia() {
+ assertThat(mediaDataManager.hasActiveMedia()).isFalse()
+ val data = mock(MediaData::class.java)
+
+ mediaDataManager.onNotificationAdded(KEY, mediaNotification)
+ mediaDataManager.onMediaDataLoaded(KEY, oldKey = null, data = data)
+ assertThat(mediaDataManager.hasActiveMedia()).isFalse()
+
+ whenever(data.active).thenReturn(true)
+ assertThat(mediaDataManager.hasActiveMedia()).isTrue()
+ }
+
+ @Test
+ fun testOnSwipeToDismiss_deactivatesMedia() {
+ val data = MediaData(initialized = true, backgroundColor = 0, app = null, appIcon = null,
+ artist = null, song = null, artwork = null, actions = emptyList(),
+ actionsToShowInCompact = emptyList(), packageName = "INVALID", token = null,
+ clickIntent = null, device = null, active = true, resumeAction = null)
+ mediaDataManager.onNotificationAdded(KEY, mediaNotification)
+ mediaDataManager.onMediaDataLoaded(KEY, oldKey = null, data = data)
+
+ mediaDataManager.onSwipeToDismiss()
+ assertThat(data.active).isFalse()
+ }
+
+ @Test
+ fun testLoadsMetadataOnBackground() {
+ mediaDataManager.onNotificationAdded(KEY, mediaNotification)
+ assertThat(backgroundExecutor.numPending()).isEqualTo(1)
+ }
+
+ @Test
+ fun testOnMetaDataLoaded_callsListener() {
+ val listener = mock(MediaDataManager.Listener::class.java)
+ mediaDataManager.addListener(listener)
+ mediaDataManager.onNotificationAdded(KEY, mediaNotification)
+ mediaDataManager.onMediaDataLoaded(KEY, oldKey = null, data = mock(MediaData::class.java))
+ verify(listener).onMediaDataLoaded(eq(KEY), eq(null), anyObject())
+ }
+
+ @Test
+ fun testOnMetaDataLoaded_conservesActiveFlag() {
+ val listener = TestListener()
+ whenever(mediaControllerFactory.create(anyObject())).thenReturn(controller)
+ whenever(controller.metadata).thenReturn(metadataBuilder.build())
+ mediaDataManager.addListener(listener)
+ mediaDataManager.onNotificationAdded(KEY, mediaNotification)
+ assertThat(backgroundExecutor.runAllReady()).isEqualTo(1)
+ assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
+ assertThat(listener.data!!.active).isTrue()
+
+ // Swiping away makes the notification not active
+ mediaDataManager.onSwipeToDismiss()
+ assertThat(mediaDataManager.hasActiveMedia()).isFalse()
+
+ // And when a notification is updated
+ mediaDataManager.onNotificationAdded(KEY, mediaNotification)
+ assertThat(backgroundExecutor.runAllReady()).isEqualTo(1)
+ assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
+
+ // MediaData should still be inactive
+ assertThat(mediaDataManager.hasActiveMedia()).isFalse()
+ }
+
+ @Test
+ fun testHasAnyMedia_whenAddingMedia() {
+ assertThat(mediaDataManager.hasAnyMedia()).isFalse()
+ val data = mock(MediaData::class.java)
+
+ mediaDataManager.onNotificationAdded(KEY, mediaNotification)
+ mediaDataManager.onMediaDataLoaded(KEY, oldKey = null, data = data)
+ assertThat(mediaDataManager.hasAnyMedia()).isTrue()
+ }
+
+ @Test
+ fun testOnNotificationRemoved_doesntHaveMedia() {
+ val data = mock(MediaData::class.java)
+ mediaDataManager.onNotificationAdded(KEY, mediaNotification)
+ mediaDataManager.onMediaDataLoaded(KEY, oldKey = null, data = data)
+ mediaDataManager.onNotificationRemoved(KEY)
+ assertThat(mediaDataManager.hasAnyMedia()).isFalse()
+ }
+
+ @Test
+ fun testOnNotificationRemoved_callsListener() {
+ val listener = mock(MediaDataManager.Listener::class.java)
+ mediaDataManager.addListener(listener)
+ mediaDataManager.onNotificationAdded(KEY, mediaNotification)
+ mediaDataManager.onMediaDataLoaded(KEY, oldKey = null, data = mock(MediaData::class.java))
+ mediaDataManager.onNotificationRemoved(KEY)
+
+ verify(listener).onMediaDataRemoved(eq(KEY))
+ }
+
+ @Test
+ fun testOnNotificationRemoved_withResumption() {
+ // GIVEN that the manager has a notification with a resume action
+ val listener = TestListener()
+ mediaDataManager.addListener(listener)
+ whenever(controller.metadata).thenReturn(metadataBuilder.build())
+ mediaDataManager.onNotificationAdded(KEY, mediaNotification)
+ assertThat(backgroundExecutor.runAllReady()).isEqualTo(1)
+ assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
+ val data = listener.data!!
+ assertThat(data.resumption).isFalse()
+ mediaDataManager.onMediaDataLoaded(KEY, null, data.copy(resumeAction = Runnable {}))
+ // WHEN the notification is removed
+ mediaDataManager.onNotificationRemoved(KEY)
+ // THEN the media data indicates that it is
+ assertThat(listener.data!!.resumption).isTrue()
+ }
+
+ @Test
+ fun testAddResumptionControls() {
+ val listener = TestListener()
+ mediaDataManager.addListener(listener)
+ // WHEN resumption controls are added`
+ val desc = MediaDescription.Builder().run {
+ setTitle(SESSION_TITLE)
+ build()
+ }
+ mediaDataManager.addResumptionControls(desc, Runnable {}, session.sessionToken, APP_NAME,
+ pendingIntent, PACKAGE_NAME)
+ assertThat(backgroundExecutor.runAllReady()).isEqualTo(1)
+ assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
+ // THEN the media data indicates that it is for resumption
+ val data = listener.data!!
+ assertThat(data.resumption).isTrue()
+ assertThat(data.song).isEqualTo(SESSION_TITLE)
+ assertThat(data.app).isEqualTo(APP_NAME)
+ assertThat(data.actions).hasSize(1)
+ }
+
+ /**
+ * Simple implementation of [MediaDataManager.Listener] for the test.
+ *
+ * Giving up on trying to get a mock Listener and ArgumentCaptor to work.
+ */
+ private class TestListener : MediaDataManager.Listener {
+ var data: MediaData? = null
+ var key: String? = null
+ var oldKey: String? = null
+
+ override fun onMediaDataLoaded(key: String, oldKey: String?, data: MediaData) {
+ this.key = key
+ this.oldKey = oldKey
+ this.data = data
+ }
+
+ override fun onMediaDataRemoved(key: String) {
+ this.key = key
+ oldKey = null
+ data = null
+ }
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt
index 6fcf6e37572b..6c7f2e8d7925 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt
@@ -30,6 +30,7 @@ import androidx.test.filters.SmallTest
import com.android.settingslib.media.LocalMediaManager
import com.android.settingslib.media.MediaDevice
import com.android.systemui.SysuiTestCase
+import com.android.systemui.dump.DumpManager
import com.android.systemui.util.concurrency.FakeExecutor
import com.android.systemui.util.time.FakeSystemClock
@@ -71,6 +72,7 @@ public class MediaDeviceManagerTest : SysuiTestCase() {
@Mock private lateinit var lmm: LocalMediaManager
@Mock private lateinit var mr2: MediaRouter2Manager
private lateinit var fakeExecutor: FakeExecutor
+ @Mock private lateinit var dumpster: DumpManager
@Mock private lateinit var listener: MediaDeviceManager.Listener
@Mock private lateinit var device: MediaDevice
@Mock private lateinit var icon: Drawable
@@ -85,7 +87,8 @@ public class MediaDeviceManagerTest : SysuiTestCase() {
@Before
fun setUp() {
fakeExecutor = FakeExecutor(FakeSystemClock())
- manager = MediaDeviceManager(context, lmmFactory, mr2, fakeExecutor, mediaDataManager)
+ manager = MediaDeviceManager(context, lmmFactory, mr2, fakeExecutor, mediaDataManager,
+ dumpster)
manager.addListener(listener)
// Configure mocks.
@@ -116,7 +119,8 @@ public class MediaDeviceManagerTest : SysuiTestCase() {
setStyle(Notification.MediaStyle().setMediaSession(session.getSessionToken()))
}
mediaData = MediaData(true, 0, PACKAGE, null, null, SESSION_TITLE, null,
- emptyList(), emptyList(), PACKAGE, session.sessionToken, null, null, null)
+ emptyList(), emptyList(), PACKAGE, session.sessionToken, clickIntent = null,
+ device = null, active = true, resumeAction = null)
}
@After
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaHierarchyManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaHierarchyManagerTest.kt
index c9e6f55ff59a..91c5ff8ee627 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaHierarchyManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaHierarchyManagerTest.kt
@@ -70,7 +70,7 @@ class MediaHierarchyManagerTest : SysuiTestCase() {
@Mock
private lateinit var notificationLockscreenUserManager: NotificationLockscreenUserManager
@Mock
- private lateinit var mediaViewManager: MediaViewManager
+ private lateinit var mediaCarouselController: MediaCarouselController
@Mock
private lateinit var wakefulnessLifecycle: WakefulnessLifecycle
@Captor
@@ -82,13 +82,13 @@ class MediaHierarchyManagerTest : SysuiTestCase() {
@Before
fun setup() {
- `when`(mediaViewManager.mediaFrame).thenReturn(mediaFrame)
+ `when`(mediaCarouselController.mediaFrame).thenReturn(mediaFrame)
mediaHiearchyManager = MediaHierarchyManager(
context,
statusBarStateController,
keyguardStateController,
bypassController,
- mediaViewManager,
+ mediaCarouselController,
notificationLockscreenUserManager,
wakefulnessLifecycle)
verify(wakefulnessLifecycle).addObserver(wakefullnessObserver.capture())
@@ -97,7 +97,7 @@ class MediaHierarchyManagerTest : SysuiTestCase() {
setupHost(qqsHost, MediaHierarchyManager.LOCATION_QQS)
`when`(statusBarStateController.state).thenReturn(StatusBarState.SHADE)
// We'll use the viewmanager to verify a few calls below, let's reset this.
- clearInvocations(mediaViewManager)
+ clearInvocations(mediaCarouselController)
}
@@ -118,14 +118,14 @@ class MediaHierarchyManagerTest : SysuiTestCase() {
fun testBlockedWhenScreenTurningOff() {
// Let's set it onto QS:
mediaHiearchyManager.qsExpansion = 1.0f
- verify(mediaViewManager).onDesiredLocationChanged(ArgumentMatchers.anyInt(),
+ verify(mediaCarouselController).onDesiredLocationChanged(ArgumentMatchers.anyInt(),
any(MediaHostState::class.java), anyBoolean(), anyLong(), anyLong())
val observer = wakefullnessObserver.value
assertNotNull("lifecycle observer wasn't registered", observer)
observer.onStartedGoingToSleep()
- clearInvocations(mediaViewManager)
+ clearInvocations(mediaCarouselController)
mediaHiearchyManager.qsExpansion = 0.0f
- verify(mediaViewManager, times(0)).onDesiredLocationChanged(ArgumentMatchers.anyInt(),
+ verify(mediaCarouselController, times(0)).onDesiredLocationChanged(ArgumentMatchers.anyInt(),
any(MediaHostState::class.java), anyBoolean(), anyLong(), anyLong())
}
@@ -133,13 +133,13 @@ class MediaHierarchyManagerTest : SysuiTestCase() {
fun testAllowedWhenNotTurningOff() {
// Let's set it onto QS:
mediaHiearchyManager.qsExpansion = 1.0f
- verify(mediaViewManager).onDesiredLocationChanged(ArgumentMatchers.anyInt(),
+ verify(mediaCarouselController).onDesiredLocationChanged(ArgumentMatchers.anyInt(),
any(MediaHostState::class.java), anyBoolean(), anyLong(), anyLong())
val observer = wakefullnessObserver.value
assertNotNull("lifecycle observer wasn't registered", observer)
- clearInvocations(mediaViewManager)
+ clearInvocations(mediaCarouselController)
mediaHiearchyManager.qsExpansion = 0.0f
- verify(mediaViewManager).onDesiredLocationChanged(ArgumentMatchers.anyInt(),
+ verify(mediaCarouselController).onDesiredLocationChanged(ArgumentMatchers.anyInt(),
any(MediaHostState::class.java), anyBoolean(), anyLong(), anyLong())
}
} \ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaTimeoutListenerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaTimeoutListenerTest.kt
index 7d44327b0d38..916fd0fe11b7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaTimeoutListenerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaTimeoutListenerTest.kt
@@ -38,6 +38,7 @@ import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.Mockito.`when`
import org.mockito.Mockito.clearInvocations
+import org.mockito.Mockito.mock
import org.mockito.Mockito.never
import org.mockito.Mockito.verify
import org.mockito.junit.MockitoJUnit
@@ -93,11 +94,16 @@ class MediaTimeoutListenerTest : SysuiTestCase() {
}
session.setActive(true)
mediaData = MediaData(true, 0, PACKAGE, null, null, SESSION_TITLE, null,
- emptyList(), emptyList(), PACKAGE, session.sessionToken, null, null, null)
+ emptyList(), emptyList(), PACKAGE, session.sessionToken, clickIntent = null,
+ device = null, active = true, resumeAction = null)
}
@Test
fun testOnMediaDataLoaded_registersPlaybackListener() {
+ val playingState = mock(android.media.session.PlaybackState::class.java)
+ `when`(playingState.state).thenReturn(PlaybackState.STATE_PLAYING)
+
+ `when`(mediaController.playbackState).thenReturn(playingState)
mediaTimeoutListener.onMediaDataLoaded(KEY, null, mediaData)
verify(mediaController).registerCallback(capture(mediaCallbackCaptor))
@@ -108,6 +114,13 @@ class MediaTimeoutListenerTest : SysuiTestCase() {
}
@Test
+ fun testOnMediaDataLoaded_registersTimeout_whenPaused() {
+ mediaTimeoutListener.onMediaDataLoaded(KEY, null, mediaData)
+ verify(mediaController).registerCallback(capture(mediaCallbackCaptor))
+ verify(executor).executeDelayed(capture(timeoutCaptor), anyLong())
+ }
+
+ @Test
fun testOnMediaDataRemoved_unregistersPlaybackListener() {
mediaTimeoutListener.onMediaDataLoaded(KEY, null, mediaData)
mediaTimeoutListener.onMediaDataRemoved(KEY)
@@ -164,4 +177,4 @@ class MediaTimeoutListenerTest : SysuiTestCase() {
mediaTimeoutListener.onMediaDataLoaded(KEY, null, mediaData)
assertThat(mediaTimeoutListener.isTimedOut(KEY)).isFalse()
}
-} \ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/SeekBarObserverTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/SeekBarObserverTest.kt
index 75018df023cc..e9a0a40fe8ae 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/SeekBarObserverTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/SeekBarObserverTest.kt
@@ -22,6 +22,7 @@ import android.view.View
import android.widget.SeekBar
import android.widget.TextView
import androidx.test.filters.SmallTest
+import com.android.systemui.R
import com.android.systemui.SysuiTestCase
import com.google.common.truth.Truth.assertThat
import org.junit.Before
@@ -36,6 +37,9 @@ import org.mockito.Mockito.`when` as whenever
@TestableLooper.RunWithLooper
public class SeekBarObserverTest : SysuiTestCase() {
+ private val disabledHeight = 1
+ private val enabledHeight = 2
+
private lateinit var observer: SeekBarObserver
@Mock private lateinit var mockHolder: PlayerViewHolder
private lateinit var seekBarView: SeekBar
@@ -45,12 +49,19 @@ public class SeekBarObserverTest : SysuiTestCase() {
@Before
fun setUp() {
mockHolder = mock(PlayerViewHolder::class.java)
+
+ context.orCreateTestableResources
+ .addOverride(R.dimen.qs_media_enabled_seekbar_height, enabledHeight)
+ context.orCreateTestableResources
+ .addOverride(R.dimen.qs_media_disabled_seekbar_height, disabledHeight)
+
seekBarView = SeekBar(context)
elapsedTimeView = TextView(context)
totalTimeView = TextView(context)
whenever(mockHolder.seekBar).thenReturn(seekBarView)
whenever(mockHolder.elapsedTimeView).thenReturn(elapsedTimeView)
whenever(mockHolder.totalTimeView).thenReturn(totalTimeView)
+
observer = SeekBarObserver(mockHolder)
}
@@ -60,11 +71,12 @@ public class SeekBarObserverTest : SysuiTestCase() {
val isEnabled = false
val data = SeekBarViewModel.Progress(isEnabled, false, null, null)
observer.onChanged(data)
- // THEN seek bar shows just a line with no text
+ // THEN seek bar shows just a thin line with no text
assertThat(seekBarView.isEnabled()).isFalse()
assertThat(seekBarView.getThumb().getAlpha()).isEqualTo(0)
assertThat(elapsedTimeView.getText()).isEqualTo("")
assertThat(totalTimeView.getText()).isEqualTo("")
+ assertThat(seekBarView.maxHeight).isEqualTo(disabledHeight)
}
@Test
@@ -73,10 +85,11 @@ public class SeekBarObserverTest : SysuiTestCase() {
val isEnabled = true
val data = SeekBarViewModel.Progress(isEnabled, true, 3000, 12000)
observer.onChanged(data)
- // THEN seek bar is visible
+ // THEN seek bar is visible and thick
assertThat(seekBarView.getVisibility()).isEqualTo(View.VISIBLE)
assertThat(elapsedTimeView.getVisibility()).isEqualTo(View.VISIBLE)
assertThat(totalTimeView.getVisibility()).isEqualTo(View.VISIBLE)
+ assertThat(seekBarView.maxHeight).isEqualTo(enabledHeight)
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/pip/phone/PipTouchHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/pip/phone/PipTouchHandlerTest.java
index 601fad6e0fef..96bb521a5d5b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/pip/phone/PipTouchHandlerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/pip/phone/PipTouchHandlerTest.java
@@ -23,7 +23,6 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import android.app.IActivityManager;
-import android.app.IActivityTaskManager;
import android.graphics.Point;
import android.graphics.Rect;
import android.testing.AndroidTestingRunner;
@@ -34,6 +33,7 @@ import androidx.test.filters.SmallTest;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.model.SysUiState;
import com.android.systemui.pip.PipBoundsHandler;
import com.android.systemui.pip.PipSnapAlgorithm;
import com.android.systemui.pip.PipTaskOrganizer;
@@ -82,6 +82,9 @@ public class PipTouchHandlerTest extends SysuiTestCase {
@Mock
private DeviceConfigProxy mDeviceConfigProxy;
+ @Mock
+ private SysUiState mSysUiState;
+
private PipSnapAlgorithm mPipSnapAlgorithm;
private PipMotionHelper mMotionHelper;
private PipResizeGestureHandler mPipResizeGestureHandler;
@@ -101,7 +104,7 @@ public class PipTouchHandlerTest extends SysuiTestCase {
mPipTouchHandler = new PipTouchHandler(mContext, mActivityManager,
mPipMenuActivityController, mInputConsumerController, mPipBoundsHandler,
mPipTaskOrganizer, mFloatingContentCoordinator, mDeviceConfigProxy,
- mPipSnapAlgorithm);
+ mPipSnapAlgorithm, mSysUiState);
mMotionHelper = Mockito.spy(mPipTouchHandler.getMotionHelper());
mPipResizeGestureHandler = Mockito.spy(mPipTouchHandler.getPipResizeGestureHandler());
mPipTouchHandler.setPipMotionHelper(mMotionHelper);
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 e58a3a6bf5d7..ea5449b4448e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java
@@ -96,6 +96,7 @@ public class QSSecurityFooterTest extends SysuiTestCase {
@Test
public void testUnmanaged() {
when(mSecurityController.isDeviceManaged()).thenReturn(false);
+ when(mSecurityController.isProfileOwnerOfOrganizationOwnedDevice()).thenReturn(false);
mFooter.refreshState();
TestableLooper.get(this).processAllMessages();
@@ -317,6 +318,33 @@ public class QSSecurityFooterTest extends SysuiTestCase {
}
@Test
+ public void testProfileOwnerOfOrganizationOwnedDeviceNoName() {
+ when(mSecurityController.isProfileOwnerOfOrganizationOwnedDevice()).thenReturn(true);
+
+ mFooter.refreshState();
+ TestableLooper.get(this).processAllMessages();
+
+ assertEquals(mContext.getString(
+ R.string.quick_settings_disclosure_management),
+ mFooterText.getText());
+ }
+
+ @Test
+ public void testProfileOwnerOfOrganizationOwnedDeviceWithName() {
+ when(mSecurityController.isProfileOwnerOfOrganizationOwnedDevice()).thenReturn(true);
+ when(mSecurityController.getWorkProfileOrganizationName())
+ .thenReturn(MANAGING_ORGANIZATION);
+
+ mFooter.refreshState();
+ TestableLooper.get(this).processAllMessages();
+
+ assertEquals(mContext.getString(
+ R.string.quick_settings_disclosure_named_management,
+ MANAGING_ORGANIZATION),
+ mFooterText.getText());
+ }
+
+ @Test
public void testVpnEnabled() {
when(mSecurityController.isVpnEnabled()).thenReturn(true);
when(mSecurityController.getPrimaryVpnName()).thenReturn(VPN_PACKAGE);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java
index 1c0d451e064a..438de99015a4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java
@@ -14,6 +14,10 @@
package com.android.systemui.qs.tileimpl;
+
+import static androidx.lifecycle.Lifecycle.State.DESTROYED;
+import static androidx.lifecycle.Lifecycle.State.RESUMED;
+
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_QS_CLICK;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_QS_LONG_PRESS;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_QS_SECONDARY_CLICK;
@@ -23,6 +27,9 @@ import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_ACTION;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
@@ -267,6 +274,42 @@ public class QSTileImplTest extends SysuiTestCase {
verify(mQsLogger).logTileChangeListening(SPEC, false);
}
+ @Test
+ public void testListeningTrue_stateAtLeastResumed() {
+ mTile.setListening(new Object(), true); // Listen with some object
+
+ TestableLooper.get(this).processAllMessages();
+
+ assertTrue(mTile.getLifecycle().getCurrentState().isAtLeast(RESUMED));
+ }
+
+ @Test
+ public void testTileDoesntStartResumed() {
+ assertFalse(mTile.getLifecycle().getCurrentState().isAtLeast(RESUMED));
+ }
+
+ @Test
+ public void testListeningFalse_stateAtMostCreated() {
+ Object o = new Object();
+ mTile.setListening(o, true);
+
+ mTile.setListening(o, false);
+
+ TestableLooper.get(this).processAllMessages();
+ assertFalse(mTile.getLifecycle().getCurrentState().isAtLeast(RESUMED));
+ }
+
+ @Test
+ public void testListeningFalse_stateNotDestroyed() {
+ Object o = new Object();
+ mTile.setListening(o, true);
+
+ mTile.setListening(o, false);
+
+ TestableLooper.get(this).processAllMessages();
+ assertNotEquals(DESTROYED, mTile.getLifecycle().getCurrentState());
+ }
+
private void assertEvent(UiEventLogger.UiEventEnum eventType,
UiEventLoggerFake.FakeUiEvent fakeEvent) {
assertEquals(eventType.getId(), fakeEvent.eventId);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
index 23099d783586..e0d268127d90 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
@@ -16,6 +16,8 @@
package com.android.systemui.statusbar;
+import static android.content.pm.UserInfo.FLAG_MANAGED_PROFILE;
+
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertFalse;
@@ -25,17 +27,22 @@ import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.clearInvocations;
+import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
import android.app.Instrumentation;
import android.app.admin.DevicePolicyManager;
import android.app.trust.TrustManager;
+import android.content.BroadcastReceiver;
import android.content.Context;
+import android.content.Intent;
+import android.content.pm.UserInfo;
import android.graphics.Color;
import android.hardware.biometrics.BiometricSourceType;
import android.hardware.face.FaceManager;
@@ -44,6 +51,7 @@ import android.os.BatteryManager;
import android.os.Looper;
import android.os.RemoteException;
import android.os.UserManager;
+import android.view.View;
import android.view.ViewGroup;
import androidx.test.InstrumentationRegistry;
@@ -52,13 +60,16 @@ import androidx.test.runner.AndroidJUnit4;
import com.android.internal.app.IBatteryStats;
import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.settingslib.Utils;
import com.android.settingslib.fuelgauge.BatteryStatus;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dock.DockManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.phone.KeyguardIndicationTextView;
+import com.android.systemui.statusbar.phone.LockIcon;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.wakelock.WakeLockFake;
@@ -71,10 +82,16 @@ import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.util.Collections;
+
@SmallTest
@RunWith(AndroidJUnit4.class)
public class KeyguardIndicationControllerTest extends SysuiTestCase {
+ private static final String ORGANIZATION_NAME = "organization";
+
+ private String mDisclosureWithOrganization;
+
@Mock
private DevicePolicyManager mDevicePolicyManager;
@Mock
@@ -82,6 +99,12 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
@Mock
private KeyguardStateController mKeyguardStateController;
@Mock
+ private KeyguardIndicationTextView mDisclosure;
+ @Mock
+ private BroadcastDispatcher mBroadcastDispatcher;
+ @Mock
+ private LockIcon mLockIcon;
+ @Mock
private StatusBarStateController mStatusBarStateController;
@Mock
private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
@@ -112,11 +135,17 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
mContext.addMockSystemService(UserManager.class, mUserManager);
mContext.addMockSystemService(Context.TRUST_SERVICE, mock(TrustManager.class));
mContext.addMockSystemService(Context.FINGERPRINT_SERVICE, mock(FingerprintManager.class));
+ mDisclosureWithOrganization = mContext.getString(R.string.do_disclosure_with_name,
+ ORGANIZATION_NAME);
when(mKeyguardUpdateMonitor.isUnlockingWithBiometricAllowed(anyBoolean())).thenReturn(true);
when(mKeyguardUpdateMonitor.isScreenOn()).thenReturn(true);
when(mKeyguardUpdateMonitor.isUserUnlocked(anyInt())).thenReturn(true);
+
+ when(mIndicationArea.findViewById(R.id.keyguard_indication_enterprise_disclosure))
+ .thenReturn(mDisclosure);
when(mIndicationArea.findViewById(R.id.keyguard_indication_text)).thenReturn(mTextView);
+ when(mDisclosure.getAlpha()).thenReturn(1f);
mWakeLock = new WakeLockFake();
mWakeLockBuilder = new WakeLockFake.Builder(mContext);
@@ -130,10 +159,12 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
mController = new KeyguardIndicationController(mContext, mWakeLockBuilder,
mKeyguardStateController, mStatusBarStateController, mKeyguardUpdateMonitor,
- mDockManager, mIBatteryStats);
+ mDockManager, mBroadcastDispatcher, mDevicePolicyManager, mIBatteryStats,
+ mUserManager);
mController.setIndicationArea(mIndicationArea);
mController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
clearInvocations(mIBatteryStats);
+ verify(mDisclosure).getAlpha();
}
@Test
@@ -215,6 +246,133 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
}
@Test
+ public void disclosure_unmanaged() {
+ when(mDevicePolicyManager.isDeviceManaged()).thenReturn(false);
+ when(mDevicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile()).thenReturn(false);
+ createController();
+
+ verify(mDisclosure).setVisibility(View.GONE);
+ verifyNoMoreInteractions(mDisclosure);
+ }
+
+ @Test
+ public void disclosure_deviceOwner_noOwnerName() {
+ when(mDevicePolicyManager.isDeviceManaged()).thenReturn(true);
+ when(mDevicePolicyManager.getDeviceOwnerOrganizationName()).thenReturn(null);
+ createController();
+
+ verify(mDisclosure).setVisibility(View.VISIBLE);
+ verify(mDisclosure).switchIndication(R.string.do_disclosure_generic);
+ verifyNoMoreInteractions(mDisclosure);
+ }
+
+ @Test
+ public void disclosure_orgOwnedDeviceWithManagedProfile_noOwnerName() {
+ when(mDevicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile()).thenReturn(true);
+ when(mUserManager.getProfiles(anyInt())).thenReturn(Collections.singletonList(
+ new UserInfo(10, /* name */ null, /* flags */ FLAG_MANAGED_PROFILE)));
+ when(mDevicePolicyManager.getOrganizationNameForUser(eq(10))).thenReturn(null);
+ createController();
+
+ verify(mDisclosure).setVisibility(View.VISIBLE);
+ verify(mDisclosure).switchIndication(R.string.do_disclosure_generic);
+ verifyNoMoreInteractions(mDisclosure);
+ }
+
+ @Test
+ public void disclosure_hiddenWhenDozing() {
+ when(mDevicePolicyManager.isDeviceManaged()).thenReturn(true);
+ when(mDevicePolicyManager.getDeviceOwnerOrganizationName()).thenReturn(null);
+ createController();
+
+ mController.setVisible(true);
+ mController.onDozeAmountChanged(1, 1);
+ mController.setDozing(true);
+
+ verify(mDisclosure).setVisibility(View.VISIBLE);
+ verify(mDisclosure).setAlpha(0f);
+ verify(mDisclosure).switchIndication(R.string.do_disclosure_generic);
+ verifyNoMoreInteractions(mDisclosure);
+ }
+
+ @Test
+ public void disclosure_visibleWhenDozing() {
+ when(mDevicePolicyManager.isDeviceManaged()).thenReturn(true);
+ when(mDevicePolicyManager.getDeviceOwnerOrganizationName()).thenReturn(null);
+ createController();
+
+ mController.setVisible(true);
+ mController.onDozeAmountChanged(0, 0);
+ mController.setDozing(false);
+
+ verify(mDisclosure).setVisibility(View.VISIBLE);
+ verify(mDisclosure).setAlpha(1f);
+ verify(mDisclosure).switchIndication(R.string.do_disclosure_generic);
+ verifyNoMoreInteractions(mDisclosure);
+ }
+
+ @Test
+ public void disclosure_deviceOwner_withOwnerName() {
+ when(mDevicePolicyManager.isDeviceManaged()).thenReturn(true);
+ when(mDevicePolicyManager.getDeviceOwnerOrganizationName()).thenReturn(ORGANIZATION_NAME);
+ createController();
+
+ verify(mDisclosure).setVisibility(View.VISIBLE);
+ verify(mDisclosure).switchIndication(mDisclosureWithOrganization);
+ verifyNoMoreInteractions(mDisclosure);
+ }
+
+ @Test
+ public void disclosure_orgOwnedDeviceWithManagedProfile_withOwnerName() {
+ when(mDevicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile()).thenReturn(true);
+ when(mUserManager.getProfiles(anyInt())).thenReturn(Collections.singletonList(
+ new UserInfo(10, /* name */ null, FLAG_MANAGED_PROFILE)));
+ when(mDevicePolicyManager.getOrganizationNameForUser(eq(10))).thenReturn(ORGANIZATION_NAME);
+ createController();
+
+ verify(mDisclosure).setVisibility(View.VISIBLE);
+ verify(mDisclosure).switchIndication(mDisclosureWithOrganization);
+ verifyNoMoreInteractions(mDisclosure);
+ }
+
+ @Test
+ public void disclosure_updateOnTheFly() {
+ ArgumentCaptor<BroadcastReceiver> receiver = ArgumentCaptor.forClass(
+ BroadcastReceiver.class);
+ doNothing().when(mBroadcastDispatcher).registerReceiver(receiver.capture(), any());
+
+ when(mDevicePolicyManager.isDeviceManaged()).thenReturn(false);
+ createController();
+
+ final KeyguardUpdateMonitorCallback monitor = mController.getKeyguardCallback();
+ reset(mDisclosure);
+
+ when(mDevicePolicyManager.isDeviceManaged()).thenReturn(true);
+ when(mDevicePolicyManager.getDeviceOwnerOrganizationName()).thenReturn(null);
+ receiver.getValue().onReceive(mContext, new Intent());
+
+ verify(mDisclosure).setVisibility(View.VISIBLE);
+ verify(mDisclosure).switchIndication(R.string.do_disclosure_generic);
+ verifyNoMoreInteractions(mDisclosure);
+ reset(mDisclosure);
+
+ when(mDevicePolicyManager.isDeviceManaged()).thenReturn(true);
+ when(mDevicePolicyManager.getDeviceOwnerOrganizationName()).thenReturn(ORGANIZATION_NAME);
+ receiver.getValue().onReceive(mContext, new Intent());
+
+ verify(mDisclosure).setVisibility(View.VISIBLE);
+ verify(mDisclosure).switchIndication(mDisclosureWithOrganization);
+ verifyNoMoreInteractions(mDisclosure);
+ reset(mDisclosure);
+
+ when(mDevicePolicyManager.isDeviceManaged()).thenReturn(false);
+ receiver.getValue().onReceive(mContext, new Intent());
+
+ verify(mDisclosure).setVisibility(View.GONE);
+ verifyNoMoreInteractions(mDisclosure);
+ }
+
+ @Test
public void transientIndication_holdsWakeLock_whenDozing() {
createController();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ForegroundCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/AppOpsCoordinatorTest.java
index 407e1e671f86..314b19140e7a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ForegroundCoordinatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/AppOpsCoordinatorTest.java
@@ -43,6 +43,7 @@ import com.android.systemui.statusbar.notification.collection.NotifPipeline;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
+import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifLifetimeExtender;
import com.android.systemui.util.concurrency.FakeExecutor;
import com.android.systemui.util.time.FakeSystemClock;
@@ -51,7 +52,6 @@ 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;
@@ -60,7 +60,7 @@ import java.util.List;
@SmallTest
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
-public class ForegroundCoordinatorTest extends SysuiTestCase {
+public class AppOpsCoordinatorTest extends SysuiTestCase {
private static final String TEST_PKG = "test_pkg";
private static final int NOTIF_USER_ID = 0;
@@ -68,12 +68,11 @@ public class ForegroundCoordinatorTest extends SysuiTestCase {
@Mock private AppOpsController mAppOpsController;
@Mock private NotifPipeline mNotifPipeline;
- @Captor private ArgumentCaptor<AppOpsController.Callback> mAppOpsCaptor;
-
private NotificationEntry mEntry;
private Notification mNotification;
- private ForegroundCoordinator mForegroundCoordinator;
+ private AppOpsCoordinator mAppOpsCoordinator;
private NotifFilter mForegroundFilter;
+ private NotifCollectionListener mNotifCollectionListener;
private AppOpsController.Callback mAppOpsCallback;
private NotifLifetimeExtender mForegroundNotifLifetimeExtender;
@@ -85,8 +84,8 @@ public class ForegroundCoordinatorTest extends SysuiTestCase {
MockitoAnnotations.initMocks(this);
allowTestableLooperAsMainThread();
- mForegroundCoordinator =
- new ForegroundCoordinator(
+ mAppOpsCoordinator =
+ new AppOpsCoordinator(
mForegroundServiceController,
mAppOpsController,
mExecutor);
@@ -97,19 +96,32 @@ public class ForegroundCoordinatorTest extends SysuiTestCase {
.setNotification(mNotification)
.build();
+ mAppOpsCoordinator.attach(mNotifPipeline);
+
+ // capture filter
ArgumentCaptor<NotifFilter> filterCaptor = ArgumentCaptor.forClass(NotifFilter.class);
+ verify(mNotifPipeline, times(1)).addPreGroupFilter(filterCaptor.capture());
+ mForegroundFilter = filterCaptor.getValue();
+
+ // capture lifetime extender
ArgumentCaptor<NotifLifetimeExtender> lifetimeExtenderCaptor =
ArgumentCaptor.forClass(NotifLifetimeExtender.class);
-
- mForegroundCoordinator.attach(mNotifPipeline);
- verify(mNotifPipeline, times(1)).addPreGroupFilter(filterCaptor.capture());
verify(mNotifPipeline, times(1)).addNotificationLifetimeExtender(
lifetimeExtenderCaptor.capture());
- verify(mAppOpsController).addCallback(any(int[].class), mAppOpsCaptor.capture());
-
- mForegroundFilter = filterCaptor.getValue();
mForegroundNotifLifetimeExtender = lifetimeExtenderCaptor.getValue();
- mAppOpsCallback = mAppOpsCaptor.getValue();
+
+ // capture notifCollectionListener
+ ArgumentCaptor<NotifCollectionListener> notifCollectionCaptor =
+ ArgumentCaptor.forClass(NotifCollectionListener.class);
+ verify(mNotifPipeline, times(1)).addCollectionListener(
+ notifCollectionCaptor.capture());
+ mNotifCollectionListener = notifCollectionCaptor.getValue();
+
+ // capture app ops callback
+ ArgumentCaptor<AppOpsController.Callback> appOpsCaptor =
+ ArgumentCaptor.forClass(AppOpsController.Callback.class);
+ verify(mAppOpsController).addCallback(any(int[].class), appOpsCaptor.capture());
+ mAppOpsCallback = appOpsCaptor.getValue();
}
@Test
@@ -199,15 +211,14 @@ public class ForegroundCoordinatorTest extends SysuiTestCase {
.setNotification(mNotification)
.build();
- // THEN don't extend the lifetime because the extended time exceeds
- // ForegroundCoordinator.MIN_FGS_TIME_MS
+ // THEN don't extend the lifetime because the extended time exceeds MIN_FGS_TIME_MS
assertFalse(mForegroundNotifLifetimeExtender
.shouldExtendLifetime(mEntry, NotificationListenerService.REASON_CLICK));
}
@Test
- public void testAppOpsAreApplied() {
- // GIVEN Three current notifications, two with the same key but from different users
+ public void testAppOpsUpdateOnlyAppliedToRelevantNotificationWithStandardLayout() {
+ // GIVEN three current notifications, two with the same key but from different users
NotificationEntry entry1 = new NotificationEntryBuilder()
.setUser(new UserHandle(NOTIF_USER_ID))
.setPkg(TEST_PKG)
@@ -218,16 +229,16 @@ public class ForegroundCoordinatorTest extends SysuiTestCase {
.setPkg(TEST_PKG)
.setId(2)
.build();
- NotificationEntry entry2Other = new NotificationEntryBuilder()
+ NotificationEntry entry3_diffUser = new NotificationEntryBuilder()
.setUser(new UserHandle(NOTIF_USER_ID + 1))
.setPkg(TEST_PKG)
.setId(2)
.build();
- when(mNotifPipeline.getAllNotifs()).thenReturn(List.of(entry1, entry2, entry2Other));
+ when(mNotifPipeline.getAllNotifs()).thenReturn(List.of(entry1, entry2, entry3_diffUser));
- // GIVEN that entry2 is currently associated with a foreground service
- when(mForegroundServiceController.getStandardLayoutKey(0, TEST_PKG))
- .thenReturn(entry2.getKey());
+ // GIVEN that only entry2 has a standard layout
+ when(mForegroundServiceController.getStandardLayoutKeys(NOTIF_USER_ID, TEST_PKG))
+ .thenReturn(new ArraySet<>(List.of(entry2.getKey())));
// WHEN a new app ops code comes in
mAppOpsCallback.onActiveStateChanged(47, NOTIF_USER_ID, TEST_PKG, true);
@@ -242,7 +253,46 @@ public class ForegroundCoordinatorTest extends SysuiTestCase {
entry2.mActiveAppOps);
assertEquals(
new ArraySet<>(),
- entry2Other.mActiveAppOps);
+ entry3_diffUser.mActiveAppOps);
+ }
+
+ @Test
+ public void testAppOpsUpdateAppliedToAllNotificationsWithStandardLayouts() {
+ // GIVEN three notifications with standard layouts
+ NotificationEntry entry1 = new NotificationEntryBuilder()
+ .setUser(new UserHandle(NOTIF_USER_ID))
+ .setPkg(TEST_PKG)
+ .setId(1)
+ .build();
+ NotificationEntry entry2 = new NotificationEntryBuilder()
+ .setUser(new UserHandle(NOTIF_USER_ID))
+ .setPkg(TEST_PKG)
+ .setId(2)
+ .build();
+ NotificationEntry entry3 = new NotificationEntryBuilder()
+ .setUser(new UserHandle(NOTIF_USER_ID))
+ .setPkg(TEST_PKG)
+ .setId(3)
+ .build();
+ when(mNotifPipeline.getAllNotifs()).thenReturn(List.of(entry1, entry2, entry3));
+ when(mForegroundServiceController.getStandardLayoutKeys(NOTIF_USER_ID, TEST_PKG))
+ .thenReturn(new ArraySet<>(List.of(entry1.getKey(), entry2.getKey(),
+ entry3.getKey())));
+
+ // WHEN a new app ops code comes in
+ mAppOpsCallback.onActiveStateChanged(47, NOTIF_USER_ID, TEST_PKG, true);
+ mExecutor.runAllReady();
+
+ // THEN all entries get updated
+ assertEquals(
+ new ArraySet<>(List.of(47)),
+ entry1.mActiveAppOps);
+ assertEquals(
+ new ArraySet<>(List.of(47)),
+ entry2.mActiveAppOps);
+ assertEquals(
+ new ArraySet<>(List.of(47)),
+ entry3.mActiveAppOps);
}
@Test
@@ -254,8 +304,8 @@ public class ForegroundCoordinatorTest extends SysuiTestCase {
.setId(2)
.build();
when(mNotifPipeline.getAllNotifs()).thenReturn(List.of(entry));
- when(mForegroundServiceController.getStandardLayoutKey(0, TEST_PKG))
- .thenReturn(entry.getKey());
+ when(mForegroundServiceController.getStandardLayoutKeys(0, TEST_PKG))
+ .thenReturn(new ArraySet<>(List.of(entry.getKey())));
// GIVEN that the notification's app ops are already [47, 33]
mAppOpsCallback.onActiveStateChanged(47, NOTIF_USER_ID, TEST_PKG, true);
@@ -274,4 +324,25 @@ public class ForegroundCoordinatorTest extends SysuiTestCase {
new ArraySet<>(List.of(33)),
entry.mActiveAppOps);
}
+
+ @Test
+ public void testNullAppOps() {
+ // GIVEN one notification with app ops
+ NotificationEntry entry = new NotificationEntryBuilder()
+ .setUser(new UserHandle(NOTIF_USER_ID))
+ .setPkg(TEST_PKG)
+ .setId(2)
+ .build();
+ entry.mActiveAppOps.clear();
+ entry.mActiveAppOps.addAll(List.of(47, 33));
+
+ // WHEN the notification is updated and the foreground service controller returns null for
+ // this notification
+ when(mForegroundServiceController.getAppOps(entry.getSbn().getUser().getIdentifier(),
+ entry.getSbn().getPackageName())).thenReturn(null);
+ mNotifCollectionListener.onEntryUpdated(entry);
+
+ // THEN the entry's active app ops is updated to empty
+ assertTrue(entry.mActiveAppOps.isEmpty());
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HideNotifsForOtherUsersCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HideNotifsForOtherUsersCoordinatorTest.java
index 87fc02062ad4..d21053bcd691 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HideNotifsForOtherUsersCoordinatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HideNotifsForOtherUsersCoordinatorTest.java
@@ -51,6 +51,7 @@ public class HideNotifsForOtherUsersCoordinatorTest extends SysuiTestCase {
@Mock private NotificationLockscreenUserManager mLockscreenUserManager;
@Mock private NotifPipeline mNotifPipeline;
@Mock private PluggableListener<NotifFilter> mInvalidationListener;
+ @Mock private SharedCoordinatorLogger mLogger;
@Captor private ArgumentCaptor<UserChangedListener> mUserChangedListenerCaptor;
@Captor private ArgumentCaptor<NotifFilter> mNotifFilterCaptor;
@@ -65,7 +66,7 @@ public class HideNotifsForOtherUsersCoordinatorTest extends SysuiTestCase {
MockitoAnnotations.initMocks(this);
HideNotifsForOtherUsersCoordinator coordinator =
- new HideNotifsForOtherUsersCoordinator(mLockscreenUserManager);
+ new HideNotifsForOtherUsersCoordinator(mLockscreenUserManager, mLogger);
coordinator.attach(mNotifPipeline);
verify(mLockscreenUserManager).addUserChangedListener(mUserChangedListenerCaptor.capture());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerTest.java
index a3a46f67ee40..c979dc637fde 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerTest.java
@@ -16,10 +16,10 @@
package com.android.systemui.statusbar.notification.logging;
-import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManagerKt.BUCKET_ALERTING;
-
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
@@ -42,6 +42,7 @@ import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.statusbar.NotificationVisibility;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.statusbar.NotificationListener;
+import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.StatusBarStateControllerImpl;
import com.android.systemui.statusbar.notification.NotificationEntryListener;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
@@ -163,28 +164,61 @@ public class NotificationLoggerTest extends SysuiTestCase {
mUiBgExecutor.runAllReady();
Mockito.reset(mBarService);
- mLogger.stopNotificationLogging();
+ setStateAsleep();
+ mLogger.onDozingChanged(false); // Wake to lockscreen
+ mLogger.onDozingChanged(true); // And go back to sleep, turning off logging
mUiBgExecutor.runAllReady();
// The visibility objects are recycled by NotificationLogger, so we can't use specific
// matchers here.
verify(mBarService, times(1)).onNotificationVisibilityChanged(any(), any());
}
+ private void setStateAsleep() {
+ mLogger.onPanelExpandedChanged(true);
+ mLogger.onDozingChanged(true);
+ mLogger.onStateChanged(StatusBarState.KEYGUARD);
+ }
+
+ private void setStateAwake() {
+ mLogger.onPanelExpandedChanged(false);
+ mLogger.onDozingChanged(false);
+ mLogger.onStateChanged(StatusBarState.SHADE);
+ }
+
+ @Test
+ public void testLogPanelShownOnWake() {
+ when(mEntryManager.getVisibleNotifications()).thenReturn(Lists.newArrayList(mEntry));
+ setStateAsleep();
+ mLogger.onDozingChanged(false); // Wake to lockscreen
+ assertEquals(1, mNotificationPanelLoggerFake.getCalls().size());
+ assertTrue(mNotificationPanelLoggerFake.get(0).isLockscreen);
+ assertEquals(1, mNotificationPanelLoggerFake.get(0).list.notifications.length);
+ Notifications.Notification n = mNotificationPanelLoggerFake.get(0).list.notifications[0];
+ assertEquals(TEST_PACKAGE_NAME, n.packageName);
+ assertEquals(TEST_UID, n.uid);
+ assertEquals(1, n.instanceId);
+ assertFalse(n.isGroupSummary);
+ assertEquals(Notifications.Notification.SECTION_ALERTING, n.section);
+ }
+
@Test
- public void testLogPanelShownOnLoggingStart() {
+ public void testLogPanelShownOnShadePull() {
when(mEntryManager.getVisibleNotifications()).thenReturn(Lists.newArrayList(mEntry));
- mLogger.startNotificationLogging();
+ setStateAwake();
+ // Now expand panel
+ mLogger.onPanelExpandedChanged(true);
assertEquals(1, mNotificationPanelLoggerFake.getCalls().size());
- assertEquals(false, mNotificationPanelLoggerFake.get(0).isLockscreen);
+ assertFalse(mNotificationPanelLoggerFake.get(0).isLockscreen);
assertEquals(1, mNotificationPanelLoggerFake.get(0).list.notifications.length);
Notifications.Notification n = mNotificationPanelLoggerFake.get(0).list.notifications[0];
assertEquals(TEST_PACKAGE_NAME, n.packageName);
assertEquals(TEST_UID, n.uid);
assertEquals(1, n.instanceId);
- assertEquals(false, n.isGroupSummary);
- assertEquals(1 + BUCKET_ALERTING, n.section);
+ assertFalse(n.isGroupSummary);
+ assertEquals(Notifications.Notification.SECTION_ALERTING, n.section);
}
+
@Test
public void testLogPanelShownHandlesNullInstanceIds() {
// Construct a NotificationEntry like mEntry, but with a null instance id.
@@ -198,7 +232,8 @@ public class NotificationLoggerTest extends SysuiTestCase {
entry.setRow(mRow);
when(mEntryManager.getVisibleNotifications()).thenReturn(Lists.newArrayList(entry));
- mLogger.startNotificationLogging();
+ setStateAsleep();
+ mLogger.onDozingChanged(false); // Wake to lockscreen
assertEquals(1, mNotificationPanelLoggerFake.getCalls().size());
assertEquals(1, mNotificationPanelLoggerFake.get(0).list.notifications.length);
Notifications.Notification n = mNotificationPanelLoggerFake.get(0).list.notifications[0];
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/AppOpsInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/AppOpsInfoTest.java
index ec73a7571969..43d8b50bcf72 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/AppOpsInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/AppOpsInfoTest.java
@@ -49,6 +49,7 @@ import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
+import com.android.internal.logging.testing.UiEventLoggerFake;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
@@ -69,6 +70,7 @@ public class AppOpsInfoTest extends SysuiTestCase {
private final PackageManager mMockPackageManager = mock(PackageManager.class);
private final NotificationGuts mGutsParent = mock(NotificationGuts.class);
private StatusBarNotification mSbn;
+ private UiEventLoggerFake mUiEventLogger = new UiEventLoggerFake();
@Before
public void setUp() throws Exception {
@@ -94,7 +96,7 @@ public class AppOpsInfoTest extends SysuiTestCase {
@Test
public void testBindNotification_SetsTextApplicationName() {
when(mMockPackageManager.getApplicationLabel(any())).thenReturn("App Name");
- mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, new ArraySet<>());
+ mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, mUiEventLogger, new ArraySet<>());
final TextView textView = mAppOpsInfo.findViewById(R.id.pkgname);
assertTrue(textView.getText().toString().contains("App Name"));
}
@@ -104,7 +106,7 @@ public class AppOpsInfoTest extends SysuiTestCase {
final Drawable iconDrawable = mock(Drawable.class);
when(mMockPackageManager.getApplicationIcon(any(ApplicationInfo.class)))
.thenReturn(iconDrawable);
- mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, new ArraySet<>());
+ mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, mUiEventLogger, new ArraySet<>());
final ImageView iconView = mAppOpsInfo.findViewById(R.id.pkgicon);
assertEquals(iconDrawable, iconView.getDrawable());
}
@@ -120,7 +122,7 @@ public class AppOpsInfoTest extends SysuiTestCase {
assertEquals(expectedOps, ops);
assertEquals(TEST_UID, uid);
latch.countDown();
- }, mSbn, expectedOps);
+ }, mSbn, mUiEventLogger, expectedOps);
final View settingsButton = mAppOpsInfo.findViewById(R.id.settings);
settingsButton.performClick();
@@ -129,6 +131,14 @@ public class AppOpsInfoTest extends SysuiTestCase {
}
@Test
+ public void testBindNotification_LogsOpen() throws Exception {
+ mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, mUiEventLogger, new ArraySet<>());
+ assertEquals(1, mUiEventLogger.numLogs());
+ assertEquals(NotificationAppOpsEvent.NOTIFICATION_APP_OPS_OPEN.getId(),
+ mUiEventLogger.eventId(0));
+ }
+
+ @Test
public void testOk() {
ArraySet<Integer> expectedOps = new ArraySet<>();
expectedOps.add(OP_CAMERA);
@@ -139,7 +149,7 @@ public class AppOpsInfoTest extends SysuiTestCase {
assertEquals(expectedOps, ops);
assertEquals(TEST_UID, uid);
latch.countDown();
- }, mSbn, expectedOps);
+ }, mSbn, mUiEventLogger, expectedOps);
final View okButton = mAppOpsInfo.findViewById(R.id.ok);
okButton.performClick();
@@ -151,7 +161,7 @@ public class AppOpsInfoTest extends SysuiTestCase {
public void testPrompt_camera() {
ArraySet<Integer> expectedOps = new ArraySet<>();
expectedOps.add(OP_CAMERA);
- mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, expectedOps);
+ mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, mUiEventLogger, expectedOps);
TextView prompt = mAppOpsInfo.findViewById(R.id.prompt);
assertEquals("This app is using the camera.", prompt.getText());
}
@@ -160,7 +170,7 @@ public class AppOpsInfoTest extends SysuiTestCase {
public void testPrompt_mic() {
ArraySet<Integer> expectedOps = new ArraySet<>();
expectedOps.add(OP_RECORD_AUDIO);
- mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, expectedOps);
+ mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, mUiEventLogger, expectedOps);
TextView prompt = mAppOpsInfo.findViewById(R.id.prompt);
assertEquals("This app is using the microphone.", prompt.getText());
}
@@ -169,7 +179,7 @@ public class AppOpsInfoTest extends SysuiTestCase {
public void testPrompt_overlay() {
ArraySet<Integer> expectedOps = new ArraySet<>();
expectedOps.add(OP_SYSTEM_ALERT_WINDOW);
- mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, expectedOps);
+ mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, mUiEventLogger, expectedOps);
TextView prompt = mAppOpsInfo.findViewById(R.id.prompt);
assertEquals("This app is displaying over other apps on your screen.", prompt.getText());
}
@@ -179,7 +189,7 @@ public class AppOpsInfoTest extends SysuiTestCase {
ArraySet<Integer> expectedOps = new ArraySet<>();
expectedOps.add(OP_CAMERA);
expectedOps.add(OP_RECORD_AUDIO);
- mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, expectedOps);
+ mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, mUiEventLogger, expectedOps);
TextView prompt = mAppOpsInfo.findViewById(R.id.prompt);
assertEquals("This app is using the microphone and camera.", prompt.getText());
}
@@ -190,7 +200,7 @@ public class AppOpsInfoTest extends SysuiTestCase {
expectedOps.add(OP_CAMERA);
expectedOps.add(OP_RECORD_AUDIO);
expectedOps.add(OP_SYSTEM_ALERT_WINDOW);
- mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, expectedOps);
+ mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, mUiEventLogger, expectedOps);
TextView prompt = mAppOpsInfo.findViewById(R.id.prompt);
assertEquals("This app is displaying over other apps on your screen and using"
+ " the microphone and camera.", prompt.getText());
@@ -201,7 +211,7 @@ public class AppOpsInfoTest extends SysuiTestCase {
ArraySet<Integer> expectedOps = new ArraySet<>();
expectedOps.add(OP_CAMERA);
expectedOps.add(OP_SYSTEM_ALERT_WINDOW);
- mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, expectedOps);
+ mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, mUiEventLogger, expectedOps);
TextView prompt = mAppOpsInfo.findViewById(R.id.prompt);
assertEquals("This app is displaying over other apps on your screen and using"
+ " the camera.", prompt.getText());
@@ -212,7 +222,7 @@ public class AppOpsInfoTest extends SysuiTestCase {
ArraySet<Integer> expectedOps = new ArraySet<>();
expectedOps.add(OP_RECORD_AUDIO);
expectedOps.add(OP_SYSTEM_ALERT_WINDOW);
- mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, expectedOps);
+ mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, mUiEventLogger, expectedOps);
TextView prompt = mAppOpsInfo.findViewById(R.id.prompt);
assertEquals("This app is displaying over other apps on your screen and using"
+ " the microphone.", prompt.getText());
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 4122cf5466e2..83fc82634b60 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
@@ -256,7 +256,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mBuilderProvider,
true,
mTestHandler,
- mTestHandler, null);
+ mTestHandler, null, mBubbleController);
final ImageView view = mNotificationInfo.findViewById(R.id.conversation_icon);
assertEquals(mIconDrawable, view.getDrawable());
}
@@ -280,7 +280,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mBuilderProvider,
true,
mTestHandler,
- mTestHandler, null);
+ mTestHandler, null, mBubbleController);
final TextView textView = mNotificationInfo.findViewById(R.id.pkg_name);
assertTrue(textView.getText().toString().contains("App Name"));
assertEquals(VISIBLE, mNotificationInfo.findViewById(R.id.header).getVisibility());
@@ -331,7 +331,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mBuilderProvider,
true,
mTestHandler,
- mTestHandler, null);
+ mTestHandler, null, mBubbleController);
final TextView textView = mNotificationInfo.findViewById(R.id.group_name);
assertTrue(textView.getText().toString().contains(group.getName()));
assertEquals(VISIBLE, mNotificationInfo.findViewById(R.id.header).getVisibility());
@@ -356,7 +356,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mBuilderProvider,
true,
mTestHandler,
- mTestHandler, null);
+ mTestHandler, null, mBubbleController);
final TextView textView = mNotificationInfo.findViewById(R.id.group_name);
assertEquals(VISIBLE, mNotificationInfo.findViewById(R.id.header).getVisibility());
assertEquals(GONE, textView.getVisibility());
@@ -380,7 +380,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mBuilderProvider,
true,
mTestHandler,
- mTestHandler, null);
+ mTestHandler, null, mBubbleController);
final TextView nameView = mNotificationInfo.findViewById(R.id.delegate_name);
assertEquals(GONE, nameView.getVisibility());
}
@@ -415,7 +415,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mBuilderProvider,
true,
mTestHandler,
- mTestHandler, null);
+ mTestHandler, null, mBubbleController);
final TextView nameView = mNotificationInfo.findViewById(R.id.delegate_name);
assertEquals(VISIBLE, nameView.getVisibility());
assertTrue(nameView.getText().toString().contains("Proxied"));
@@ -443,7 +443,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mBuilderProvider,
true,
mTestHandler,
- mTestHandler, null);
+ mTestHandler, null, mBubbleController);
final View settingsButton = mNotificationInfo.findViewById(R.id.info);
settingsButton.performClick();
@@ -469,7 +469,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mBuilderProvider,
true,
mTestHandler,
- mTestHandler, null);
+ mTestHandler, null, mBubbleController);
final View settingsButton = mNotificationInfo.findViewById(R.id.info);
assertTrue(settingsButton.getVisibility() != View.VISIBLE);
}
@@ -496,7 +496,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mBuilderProvider,
false,
mTestHandler,
- mTestHandler, null);
+ mTestHandler, null, mBubbleController);
final View settingsButton = mNotificationInfo.findViewById(R.id.info);
assertTrue(settingsButton.getVisibility() != View.VISIBLE);
}
@@ -521,7 +521,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mBuilderProvider,
true,
mTestHandler,
- mTestHandler, null);
+ mTestHandler, null, mBubbleController);
View view = mNotificationInfo.findViewById(R.id.silence);
assertThat(view.isSelected()).isTrue();
}
@@ -549,7 +549,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mBuilderProvider,
true,
mTestHandler,
- mTestHandler, null);
+ mTestHandler, null, mBubbleController);
View view = mNotificationInfo.findViewById(R.id.default_behavior);
assertThat(view.isSelected()).isTrue();
assertThat(((TextView) view.findViewById(R.id.default_summary)).getText()).isEqualTo(
@@ -580,7 +580,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mBuilderProvider,
true,
mTestHandler,
- mTestHandler, null);
+ mTestHandler, null, mBubbleController);
View view = mNotificationInfo.findViewById(R.id.default_behavior);
assertThat(view.isSelected()).isTrue();
assertThat(((TextView) view.findViewById(R.id.default_summary)).getText()).isEqualTo(
@@ -610,7 +610,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mBuilderProvider,
true,
mTestHandler,
- mTestHandler, null);
+ mTestHandler, null, mBubbleController);
View fave = mNotificationInfo.findViewById(R.id.priority);
fave.performClick();
@@ -654,7 +654,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mBuilderProvider,
true,
mTestHandler,
- mTestHandler, null);
+ mTestHandler, null, mBubbleController);
mNotificationInfo.findViewById(R.id.default_behavior).performClick();
mTestableLooper.processAllMessages();
@@ -697,7 +697,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mBuilderProvider,
true,
mTestHandler,
- mTestHandler, null);
+ mTestHandler, null, mBubbleController);
View silence = mNotificationInfo.findViewById(R.id.silence);
@@ -741,7 +741,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mBuilderProvider,
true,
mTestHandler,
- mTestHandler, null);
+ mTestHandler, null, mBubbleController);
View fave = mNotificationInfo.findViewById(R.id.priority);
fave.performClick();
@@ -778,7 +778,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mBuilderProvider,
true,
mTestHandler,
- mTestHandler, null);
+ mTestHandler, null, mBubbleController);
View fave = mNotificationInfo.findViewById(R.id.priority);
fave.performClick();
@@ -814,7 +814,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mBuilderProvider,
true,
mTestHandler,
- mTestHandler, null);
+ mTestHandler, null, mBubbleController);
View fave = mNotificationInfo.findViewById(R.id.priority);
fave.performClick();
@@ -852,7 +852,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mBuilderProvider,
true,
mTestHandler,
- mTestHandler, null);
+ mTestHandler, null, mBubbleController);
mNotificationInfo.findViewById(R.id.default_behavior).performClick();
mNotificationInfo.findViewById(R.id.done).performClick();
@@ -888,7 +888,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mBuilderProvider,
true,
mTestHandler,
- mTestHandler, null);
+ mTestHandler, null, mBubbleController);
mNotificationInfo.findViewById(R.id.default_behavior).performClick();
mNotificationInfo.findViewById(R.id.done).performClick();
@@ -924,7 +924,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mBuilderProvider,
true,
mTestHandler,
- mTestHandler, null);
+ mTestHandler, null, mBubbleController);
mNotificationInfo.findViewById(R.id.default_behavior).performClick();
mNotificationInfo.findViewById(R.id.done).performClick();
@@ -959,7 +959,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mBuilderProvider,
true,
mTestHandler,
- mTestHandler, null);
+ mTestHandler, null, mBubbleController);
View silence = mNotificationInfo.findViewById(R.id.silence);
silence.performClick();
@@ -993,7 +993,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mBuilderProvider,
true,
mTestHandler,
- mTestHandler, null);
+ mTestHandler, null, mBubbleController);
verify(mMockINotificationManager, times(1)).createConversationNotificationChannelForPackage(
anyString(), anyInt(), anyString(), any(), eq(CONVERSATION_ID));
@@ -1018,7 +1018,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mBuilderProvider,
true,
mTestHandler,
- mTestHandler, null);
+ mTestHandler, null, mBubbleController);
verify(mMockINotificationManager, never()).createConversationNotificationChannelForPackage(
anyString(), anyInt(), anyString(), any(), eq(CONVERSATION_ID));
@@ -1053,7 +1053,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
() -> b,
true,
mTestHandler,
- mTestHandler, null);
+ mTestHandler, null, mBubbleController);
// WHEN user clicks "priority"
mNotificationInfo.setSelectedAction(NotificationConversationInfo.ACTION_FAVORITE);
@@ -1093,7 +1093,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
() -> b,
true,
mTestHandler,
- mTestHandler, null);
+ mTestHandler, null, mBubbleController);
// WHEN user clicks "priority"
mNotificationInfo.setSelectedAction(NotificationConversationInfo.ACTION_FAVORITE);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
index da7d249cc5ef..9dee84347ae1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
@@ -64,7 +64,10 @@ import android.view.accessibility.AccessibilityManager;
import androidx.test.filters.SmallTest;
import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.UiEventLogger;
+import com.android.internal.logging.testing.UiEventLoggerFake;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.bubbles.BubbleController;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
import com.android.systemui.settings.CurrentUserContextTracker;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
@@ -126,6 +129,7 @@ public class NotificationGutsManagerTest extends SysuiTestCase {
@Mock private ChannelEditorDialogController mChannelEditorDialogController;
@Mock private PeopleNotificationIdentifier mPeopleNotificationIdentifier;
@Mock private CurrentUserContextTracker mContextTracker;
+ @Mock private BubbleController mBubbleController;
@Mock(answer = Answers.RETURNS_SELF)
private PriorityOnboardingDialogController.Builder mBuilder;
private Provider<PriorityOnboardingDialogController.Builder> mProvider = () -> mBuilder;
@@ -138,6 +142,7 @@ public class NotificationGutsManagerTest extends SysuiTestCase {
mDeviceProvisionedController);
mDependency.injectTestDependency(MetricsLogger.class, mMetricsLogger);
mDependency.injectTestDependency(VisualStabilityManager.class, mVisualStabilityManager);
+ mDependency.injectTestDependency(BubbleController.class, mBubbleController);
mDependency.injectMockDependency(NotificationLockscreenUserManager.class);
mHandler = Handler.createAsync(mTestableLooper.getLooper());
mHelper = new NotificationTestHelper(mContext, mDependency, TestableLooper.get(this));
@@ -146,7 +151,8 @@ public class NotificationGutsManagerTest extends SysuiTestCase {
mGutsManager = new NotificationGutsManager(mContext, mVisualStabilityManager,
() -> mStatusBar, mHandler, mHandler, mAccessibilityManager, mHighPriorityProvider,
mINotificationManager, mLauncherApps, mShortcutManager,
- mChannelEditorDialogController, mContextTracker, mProvider);
+ mChannelEditorDialogController, mContextTracker, mProvider, mBubbleController,
+ new UiEventLoggerFake());
mGutsManager.setUpWithPresenter(mPresenter, mStackScroller,
mCheckSaveListener, mOnSettingsClickListener);
mGutsManager.setNotificationActivityStarter(mNotificationActivityStarter);
@@ -359,6 +365,7 @@ public class NotificationGutsManagerTest extends SysuiTestCase {
eq(entry),
any(NotificationInfo.OnSettingsClickListener.class),
any(NotificationInfo.OnAppSettingsClickListener.class),
+ any(UiEventLogger.class),
eq(false),
eq(false),
eq(true) /* wasShownHighPriority */);
@@ -391,6 +398,7 @@ public class NotificationGutsManagerTest extends SysuiTestCase {
eq(entry),
any(NotificationInfo.OnSettingsClickListener.class),
any(NotificationInfo.OnAppSettingsClickListener.class),
+ any(UiEventLogger.class),
eq(true),
eq(false),
eq(false) /* wasShownHighPriority */);
@@ -421,6 +429,7 @@ public class NotificationGutsManagerTest extends SysuiTestCase {
eq(entry),
any(NotificationInfo.OnSettingsClickListener.class),
any(NotificationInfo.OnAppSettingsClickListener.class),
+ any(UiEventLogger.class),
eq(false),
eq(false),
eq(false) /* wasShownHighPriority */);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java
index 6bf60721cd8e..ed982ab7d989 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java
@@ -62,6 +62,7 @@ import android.widget.ImageView;
import android.widget.TextView;
import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.testing.UiEventLoggerFake;
import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
@@ -102,6 +103,7 @@ public class NotificationInfoTest extends SysuiTestCase {
private Set<NotificationChannel> mDefaultNotificationChannelSet = new HashSet<>();
private StatusBarNotification mSbn;
private NotificationEntry mEntry;
+ private UiEventLoggerFake mUiEventLogger = new UiEventLoggerFake();
@Rule
public MockitoRule mockito = MockitoJUnit.rule();
@@ -187,6 +189,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry,
null,
null,
+ mUiEventLogger,
true,
false,
true);
@@ -211,6 +214,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry,
null,
null,
+ mUiEventLogger,
true,
false,
true);
@@ -231,6 +235,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry,
null,
null,
+ mUiEventLogger,
true,
false,
true);
@@ -260,6 +265,7 @@ public class NotificationInfoTest extends SysuiTestCase {
entry,
null,
null,
+ mUiEventLogger,
true,
false,
true);
@@ -281,6 +287,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry,
null,
null,
+ mUiEventLogger,
true,
false,
true);
@@ -307,6 +314,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry,
null,
null,
+ mUiEventLogger,
true,
false,
true);
@@ -328,6 +336,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry,
null,
null,
+ mUiEventLogger,
true,
false,
true);
@@ -348,6 +357,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry,
null,
null,
+ mUiEventLogger,
true,
false,
true);
@@ -372,6 +382,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry,
null,
null,
+ mUiEventLogger,
true,
false,
true);
@@ -392,6 +403,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry,
null,
null,
+ mUiEventLogger,
true,
true,
true);
@@ -416,6 +428,7 @@ public class NotificationInfoTest extends SysuiTestCase {
latch.countDown();
},
null,
+ mUiEventLogger,
true,
false,
true);
@@ -439,6 +452,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry,
null,
null,
+ mUiEventLogger,
true,
false,
true);
@@ -462,6 +476,7 @@ public class NotificationInfoTest extends SysuiTestCase {
assertEquals(mNotificationChannel, c);
},
null,
+ mUiEventLogger,
false,
false,
true);
@@ -482,6 +497,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry,
null,
null,
+ mUiEventLogger,
true,
false,
true);
@@ -496,6 +512,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry,
(View v, NotificationChannel c, int appUid) -> { },
null,
+ mUiEventLogger,
true,
false,
true);
@@ -519,6 +536,7 @@ public class NotificationInfoTest extends SysuiTestCase {
latch.countDown();
},
null,
+ mUiEventLogger,
true,
true,
true);
@@ -543,6 +561,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry,
null,
null,
+ mUiEventLogger,
true,
false,
true);
@@ -565,6 +584,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry,
null,
null,
+ mUiEventLogger,
true,
false,
true);
@@ -587,6 +607,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry,
null,
null,
+ mUiEventLogger,
true,
true,
true);
@@ -611,6 +632,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry,
null,
null,
+ mUiEventLogger,
true,
false,
true);
@@ -630,6 +652,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry,
null,
null,
+ mUiEventLogger,
true,
false,
false);
@@ -649,6 +672,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry,
null,
null,
+ mUiEventLogger,
true,
false,
true);
@@ -658,6 +682,28 @@ public class NotificationInfoTest extends SysuiTestCase {
}
@Test
+ public void testBindNotification_LogsOpen() throws Exception {
+ mNotificationInfo.bindNotification(
+ mMockPackageManager,
+ mMockINotificationManager,
+ mVisualStabilityManager,
+ mChannelEditorDialogController,
+ TEST_PACKAGE_NAME,
+ mNotificationChannel,
+ mNotificationChannelSet,
+ mEntry,
+ null,
+ null,
+ mUiEventLogger,
+ true,
+ false,
+ true);
+ assertEquals(1, mUiEventLogger.numLogs());
+ assertEquals(NotificationControlsEvent.NOTIFICATION_CONTROLS_OPEN.getId(),
+ mUiEventLogger.eventId(0));
+ }
+
+ @Test
public void testDoesNotUpdateNotificationChannelAfterImportanceChanged() throws Exception {
mNotificationChannel.setImportance(IMPORTANCE_LOW);
mNotificationInfo.bindNotification(
@@ -671,6 +717,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry,
null,
null,
+ mUiEventLogger,
true,
false,
false);
@@ -696,6 +743,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry,
null,
null,
+ mUiEventLogger,
true,
false,
true);
@@ -721,6 +769,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry,
null,
null,
+ mUiEventLogger,
true,
false,
true);
@@ -730,6 +779,13 @@ public class NotificationInfoTest extends SysuiTestCase {
verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
anyString(), eq(TEST_UID), any());
assertEquals(originalImportance, mNotificationChannel.getImportance());
+
+ assertEquals(2, mUiEventLogger.numLogs());
+ assertEquals(NotificationControlsEvent.NOTIFICATION_CONTROLS_OPEN.getId(),
+ mUiEventLogger.eventId(0));
+ // The SAVE_IMPORTANCE event is logged whenever importance is saved, even if unchanged.
+ assertEquals(NotificationControlsEvent.NOTIFICATION_CONTROLS_SAVE_IMPORTANCE.getId(),
+ mUiEventLogger.eventId(1));
}
@Test
@@ -747,6 +803,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry,
null,
null,
+ mUiEventLogger,
true,
false,
true);
@@ -773,6 +830,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry,
null,
null,
+ mUiEventLogger,
true,
false,
true);
@@ -789,6 +847,12 @@ public class NotificationInfoTest extends SysuiTestCase {
assertTrue((updated.getValue().getUserLockedFields()
& USER_LOCKED_IMPORTANCE) != 0);
assertEquals(IMPORTANCE_LOW, updated.getValue().getImportance());
+
+ assertEquals(2, mUiEventLogger.numLogs());
+ assertEquals(NotificationControlsEvent.NOTIFICATION_CONTROLS_OPEN.getId(),
+ mUiEventLogger.eventId(0));
+ assertEquals(NotificationControlsEvent.NOTIFICATION_CONTROLS_SAVE_IMPORTANCE.getId(),
+ mUiEventLogger.eventId(1));
}
@Test
@@ -805,6 +869,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry,
null,
null,
+ mUiEventLogger,
true,
false,
false);
@@ -838,6 +903,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry,
null,
null,
+ mUiEventLogger,
true,
false,
true);
@@ -871,6 +937,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry,
null,
null,
+ mUiEventLogger,
true,
false,
false);
@@ -907,6 +974,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry,
null,
null,
+ mUiEventLogger,
true,
false,
false);
@@ -942,6 +1010,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry,
null,
null,
+ mUiEventLogger,
true,
false,
true);
@@ -968,6 +1037,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry,
null,
null,
+ mUiEventLogger,
true,
false,
false);
@@ -997,6 +1067,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry,
null,
null,
+ mUiEventLogger,
true,
false,
false);
@@ -1029,6 +1100,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry,
null,
null,
+ mUiEventLogger,
true,
false,
false);
@@ -1040,6 +1112,10 @@ public class NotificationInfoTest extends SysuiTestCase {
mTestableLooper.processAllMessages();
verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
eq(TEST_PACKAGE_NAME), eq(TEST_UID), eq(mNotificationChannel));
+
+ assertEquals(1, mUiEventLogger.numLogs());
+ assertEquals(NotificationControlsEvent.NOTIFICATION_CONTROLS_OPEN.getId(),
+ mUiEventLogger.eventId(0));
}
@Test
@@ -1056,6 +1132,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry,
null,
null,
+ mUiEventLogger,
true,
false,
false
@@ -1088,6 +1165,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry,
null,
null,
+ mUiEventLogger,
true,
false,
false
@@ -1113,6 +1191,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry,
null,
null,
+ mUiEventLogger,
true,
false,
false
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java
index c55391a387d8..243503d1d8a6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java
@@ -403,11 +403,11 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {
enablePeopleFiltering();
setupMockStack(
- PERSON.headsUp(), // personHeaderTarget = 0
- INCOMING_HEADER, // currentIncomingHeaderIdx = 1
- ALERTING.headsUp(), // alertingHeaderTarget = 1
- PEOPLE_HEADER, // currentPeopleHeaderIdx = 3
- PERSON //
+ PERSON.headsUp(),
+ INCOMING_HEADER,
+ ALERTING.headsUp(),
+ PEOPLE_HEADER,
+ PERSON
);
mSectionsManager.updateSectionBoundaries();
@@ -520,6 +520,70 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {
ChildType.GENTLE);
}
+ @Test
+ public void testRemoveIncomingHeader() {
+ enablePeopleFiltering();
+ enableMediaControls();
+
+ setupMockStack(
+ MEDIA_CONTROLS,
+ INCOMING_HEADER,
+ PERSON,
+ ALERTING,
+ PEOPLE_HEADER,
+ ALERTING_HEADER,
+ ALERTING,
+ ALERTING,
+ GENTLE_HEADER,
+ GENTLE,
+ GENTLE
+ );
+
+ mSectionsManager.updateSectionBoundaries();
+
+ verifyMockStack(
+ ChildType.MEDIA_CONTROLS,
+ ChildType.PEOPLE_HEADER,
+ ChildType.PERSON,
+ ChildType.ALERTING_HEADER,
+ ChildType.ALERTING,
+ ChildType.ALERTING,
+ ChildType.ALERTING,
+ ChildType.GENTLE_HEADER,
+ ChildType.GENTLE,
+ ChildType.GENTLE
+ );
+ }
+
+ @Test
+ public void testExpandIncomingSection() {
+ enablePeopleFiltering();
+
+ setupMockStack(
+ INCOMING_HEADER,
+ PERSON,
+ ALERTING,
+ PEOPLE_HEADER,
+ ALERTING,
+ PERSON,
+ ALERTING_HEADER,
+ ALERTING
+ );
+
+ mSectionsManager.updateSectionBoundaries();
+
+ verifyMockStack(
+ ChildType.INCOMING_HEADER,
+ ChildType.HEADS_UP,
+ ChildType.HEADS_UP,
+ ChildType.HEADS_UP,
+ ChildType.PEOPLE_HEADER,
+ ChildType.PERSON,
+ ChildType.ALERTING_HEADER,
+ ChildType.ALERTING
+ );
+ }
+
private void enablePeopleFiltering() {
when(mSectionsFeatureManager.isFilteringEnabled()).thenReturn(true);
}
@@ -657,7 +721,13 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {
final List<View> children = new ArrayList<>();
when(mNssl.getChildCount()).thenAnswer(invocation -> children.size());
when(mNssl.getChildAt(anyInt()))
- .thenAnswer(invocation -> children.get(invocation.getArgument(0)));
+ .thenAnswer(invocation -> {
+ Integer index = invocation.getArgument(0);
+ if (index == null || index < 0 || index >= children.size()) {
+ return null;
+ }
+ return children.get(index);
+ });
when(mNssl.indexOfChild(any()))
.thenAnswer(invocation -> children.indexOf(invocation.getArgument(0)));
doAnswer(invocation -> {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
index c4bd1b281b24..b286f9486e13 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
@@ -53,6 +53,7 @@ import com.android.systemui.ExpandHelper;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.classifier.FalsingManagerFake;
+import com.android.systemui.media.KeyguardMediaController;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
import com.android.systemui.statusbar.EmptyShadeView;
import com.android.systemui.statusbar.FeatureFlags;
@@ -133,6 +134,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
@Mock private MetricsLogger mMetricsLogger;
@Mock private NotificationRoundnessManager mNotificationRoundnessManager;
@Mock private KeyguardBypassController mKeyguardBypassController;
+ @Mock private KeyguardMediaController mKeyguardMediaController;
@Mock private ZenModeController mZenModeController;
@Mock private NotificationSectionsManager mNotificationSectionsManager;
@Mock private NotificationSection mNotificationSection;
@@ -209,6 +211,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
mock(SysuiStatusBarStateController.class),
mHeadsUpManager,
mKeyguardBypassController,
+ mKeyguardMediaController,
new FalsingManagerFake(),
mLockscreenUserManager,
mock(NotificationGutsManager.class),
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 31779cdf9e71..0a959d11d7db 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
@@ -152,9 +152,11 @@ public class AutoTileManagerTest extends SysuiTestCase {
inOrderManagedProfile.verify(mManagedProfileController).removeCallback(any());
inOrderManagedProfile.verify(mManagedProfileController).addCallback(any());
- InOrder inOrderNightDisplay = inOrder(mNightDisplayListener);
- inOrderNightDisplay.verify(mNightDisplayListener).setCallback(isNull());
- inOrderNightDisplay.verify(mNightDisplayListener).setCallback(isNotNull());
+ if (ColorDisplayManager.isNightDisplayAvailable(mContext)) {
+ InOrder inOrderNightDisplay = inOrder(mNightDisplayListener);
+ inOrderNightDisplay.verify(mNightDisplayListener).setCallback(isNull());
+ inOrderNightDisplay.verify(mNightDisplayListener).setCallback(isNotNull());
+ }
InOrder inOrderCast = inOrder(mCastController);
inOrderCast.verify(mCastController).removeCallback(any());
@@ -190,9 +192,11 @@ public class AutoTileManagerTest extends SysuiTestCase {
inOrderManagedProfile.verify(mManagedProfileController).removeCallback(any());
inOrderManagedProfile.verify(mManagedProfileController, never()).addCallback(any());
- InOrder inOrderNightDisplay = inOrder(mNightDisplayListener);
- inOrderNightDisplay.verify(mNightDisplayListener).setCallback(isNull());
- inOrderNightDisplay.verify(mNightDisplayListener).setCallback(isNotNull());
+ if (ColorDisplayManager.isNightDisplayAvailable(mContext)) {
+ InOrder inOrderNightDisplay = inOrder(mNightDisplayListener);
+ inOrderNightDisplay.verify(mNightDisplayListener).setCallback(isNull());
+ inOrderNightDisplay.verify(mNightDisplayListener).setCallback(isNotNull());
+ }
InOrder inOrderCast = inOrder(mCastController);
inOrderCast.verify(mCastController).removeCallback(any());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeSecurityController.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeSecurityController.java
index fee5e32398c4..e8911a2f5d4e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeSecurityController.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeSecurityController.java
@@ -41,6 +41,11 @@ public class FakeSecurityController extends BaseLeakChecker<SecurityControllerCa
}
@Override
+ public boolean isProfileOwnerOfOrganizationOwnedDevice() {
+ return false;
+ }
+
+ @Override
public String getDeviceOwnerName() {
return null;
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeStatusBarIconController.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeStatusBarIconController.java
index 8e34685cceec..2e874a6c2140 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeStatusBarIconController.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeStatusBarIconController.java
@@ -21,6 +21,7 @@ import com.android.systemui.statusbar.phone.StatusBarIconController;
import com.android.systemui.statusbar.phone.StatusBarIconController.IconManager;
import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.MobileIconState;
import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.WifiIconState;
+
import java.util.List;
public class FakeStatusBarIconController extends BaseLeakChecker<IconManager>
@@ -75,4 +76,8 @@ public class FakeStatusBarIconController extends BaseLeakChecker<IconManager>
public void removeAllIconsForSlot(String slot) {
}
+ @Override
+ public void setIconAccessibilityLiveRegion(String slot, int mode) {
+ }
+
}
diff --git a/packages/Tethering/Android.bp b/packages/Tethering/Android.bp
index 32e2b04e8e4f..12daa6142d5c 100644
--- a/packages/Tethering/Android.bp
+++ b/packages/Tethering/Android.bp
@@ -33,6 +33,7 @@ java_defaults {
"net-utils-framework-common",
],
libs: [
+ "framework-statsd.stubs.module_lib",
"framework-tethering.impl",
"framework-wifi",
"unsupportedappusage",
diff --git a/packages/Tethering/OWNERS b/packages/Tethering/OWNERS
new file mode 100644
index 000000000000..5b42d490411e
--- /dev/null
+++ b/packages/Tethering/OWNERS
@@ -0,0 +1,2 @@
+include platform/packages/modules/NetworkStack/:/OWNERS
+markchien@google.com
diff --git a/packages/Tethering/common/TetheringLib/src/android/net/TetheringConstants.java b/packages/Tethering/common/TetheringLib/src/android/net/TetheringConstants.java
index fd6f171487a9..f14def6a3a02 100644
--- a/packages/Tethering/common/TetheringLib/src/android/net/TetheringConstants.java
+++ b/packages/Tethering/common/TetheringLib/src/android/net/TetheringConstants.java
@@ -37,8 +37,8 @@ public final class TetheringConstants {
private TetheringConstants() { }
/**
- * Extra used for communicating with the TetherService. Includes the type of tethering to
- * enable if any.
+ * Extra used for communicating with the TetherService and TetherProvisioningActivity.
+ * Includes the type of tethering to enable if any.
*/
public static final String EXTRA_ADD_TETHER_TYPE = "extraAddTetherType";
/**
@@ -56,8 +56,38 @@ public final class TetheringConstants {
*/
public static final String EXTRA_RUN_PROVISION = "extraRunProvision";
/**
- * Extra used for communicating with the TetherService. Contains the {@link ResultReceiver}
- * which will receive provisioning results. Can be left empty.
+ * Extra used for communicating with the TetherService and TetherProvisioningActivity.
+ * Contains the {@link ResultReceiver} which will receive provisioning results.
+ * Can not be empty.
*/
public static final String EXTRA_PROVISION_CALLBACK = "extraProvisionCallback";
+
+ /**
+ * Extra used for communicating with the TetherService and TetherProvisioningActivity.
+ * Contains the subId of current active cellular upstream.
+ * @hide
+ */
+ public static final String EXTRA_TETHER_SUBID = "android.net.extra.TETHER_SUBID";
+
+ /**
+ * Extra used for telling TetherProvisioningActivity the entitlement package name and class
+ * name to start UI entitlement check.
+ * @hide
+ */
+ public static final String EXTRA_TETHER_UI_PROVISIONING_APP_NAME =
+ "android.net.extra.TETHER_UI_PROVISIONING_APP_NAME";
+
+ /**
+ * Extra used for telling TetherService the intent action to start silent entitlement check.
+ * @hide
+ */
+ public static final String EXTRA_TETHER_SILENT_PROVISIONING_ACTION =
+ "android.net.extra.TETHER_SILENT_PROVISIONING_ACTION";
+
+ /**
+ * Extra used for TetherService to receive the response of provisioning check.
+ * @hide
+ */
+ public static final String EXTRA_TETHER_PROVISIONING_RESPONSE =
+ "android.net.extra.TETHER_PROVISIONING_RESPONSE";
}
diff --git a/packages/Tethering/jarjar-rules.txt b/packages/Tethering/jarjar-rules.txt
index e90a2ccaa2a3..2d3108a0bff1 100644
--- a/packages/Tethering/jarjar-rules.txt
+++ b/packages/Tethering/jarjar-rules.txt
@@ -1,17 +1,11 @@
# These must be kept in sync with the framework-tethering-shared-srcs filegroup.
-# If there are files in that filegroup that do not appear here, the classes in the
+# Classes from the framework-tethering-shared-srcs filegroup.
+# If there are files in that filegroup that are not covered below, the classes in the
# module will be overwritten by the ones in the framework.
-# Don't jar-jar the entire package because tethering still use some internal classes
-# (like TrafficStatsConstants in com.android.internal.util)
-# TODO: simply these when tethering is built as system_current.
-rule com.android.internal.util.BitUtils* com.android.networkstack.tethering.util.BitUtils@1
-rule com.android.internal.util.IndentingPrintWriter.java* com.android.networkstack.tethering.util.IndentingPrintWriter.java@1
-rule com.android.internal.util.IState.java* com.android.networkstack.tethering.util.IState.java@1
-rule com.android.internal.util.MessageUtils* com.android.networkstack.tethering.util.MessageUtils@1
-rule com.android.internal.util.State* com.android.networkstack.tethering.util.State@1
-rule com.android.internal.util.StateMachine* com.android.networkstack.tethering.util.StateMachine@1
-rule com.android.internal.util.TrafficStatsConstants* com.android.networkstack.tethering.util.TrafficStatsConstants@1
-
+rule com.android.internal.util.** com.android.networkstack.tethering.util.@1
rule android.net.LocalLog* com.android.networkstack.tethering.LocalLog@1
rule android.net.shared.Inet4AddressUtils* com.android.networkstack.tethering.shared.Inet4AddressUtils@1
+
+# Classes from net-utils-framework-common
+rule com.android.net.module.util.** com.android.networkstack.tethering.util.@1 \ No newline at end of file
diff --git a/packages/Tethering/src/android/net/dhcp/DhcpServingParamsParcelExt.java b/packages/Tethering/src/android/net/dhcp/DhcpServingParamsParcelExt.java
index 4710a30b2998..aaaec17bf922 100644
--- a/packages/Tethering/src/android/net/dhcp/DhcpServingParamsParcelExt.java
+++ b/packages/Tethering/src/android/net/dhcp/DhcpServingParamsParcelExt.java
@@ -16,7 +16,7 @@
package android.net.dhcp;
-import static android.net.shared.Inet4AddressUtils.inet4AddressToIntHTH;
+import static com.android.net.module.util.Inet4AddressUtils.inet4AddressToIntHTH;
import android.net.LinkAddress;
import android.util.ArraySet;
diff --git a/packages/Tethering/src/android/net/ip/IpServer.java b/packages/Tethering/src/android/net/ip/IpServer.java
index 1671dda4bd57..35c156304c77 100644
--- a/packages/Tethering/src/android/net/ip/IpServer.java
+++ b/packages/Tethering/src/android/net/ip/IpServer.java
@@ -19,13 +19,14 @@ package android.net.ip;
import static android.net.RouteInfo.RTN_UNICAST;
import static android.net.TetheringManager.TetheringRequest.checkStaticAddressConfiguration;
import static android.net.dhcp.IDhcpServer.STATUS_SUCCESS;
-import static android.net.shared.Inet4AddressUtils.intToInet4AddressHTH;
import static android.net.util.NetworkConstants.RFC7421_PREFIX_LENGTH;
import static android.net.util.NetworkConstants.asByte;
import static android.net.util.PrefixUtils.asIpPrefix;
import static android.net.util.TetheringMessageBase.BASE_IPSERVER;
import static android.system.OsConstants.RT_SCOPE_UNIVERSE;
+import static com.android.net.module.util.Inet4AddressUtils.intToInet4AddressHTH;
+
import android.net.INetd;
import android.net.INetworkStackStatusCallback;
import android.net.IpPrefix;
@@ -615,8 +616,9 @@ public class IpServer extends StateMachine {
final Boolean setIfaceUp;
if (mInterfaceType == TetheringManager.TETHERING_WIFI
- || mInterfaceType == TetheringManager.TETHERING_WIFI_P2P) {
- // The WiFi stack has ownership of the interface up/down state.
+ || mInterfaceType == TetheringManager.TETHERING_WIFI_P2P
+ || mInterfaceType == TetheringManager.TETHERING_ETHERNET) {
+ // The WiFi and Ethernet stack has ownership of the interface up/down state.
// It is unclear whether the Bluetooth or USB stacks will manage their own
// state.
setIfaceUp = null;
@@ -1321,6 +1323,7 @@ public class IpServer extends StateMachine {
class UnavailableState extends State {
@Override
public void enter() {
+ mIpNeighborMonitor.stop();
mLastError = TetheringManager.TETHER_ERROR_NO_ERROR;
sendInterfaceState(STATE_UNAVAILABLE);
}
diff --git a/packages/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java b/packages/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java
index fc27b6add052..20f30ea7a460 100644
--- a/packages/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java
+++ b/packages/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java
@@ -25,6 +25,8 @@ import static android.net.NetworkStats.UID_ALL;
import static android.net.NetworkStats.UID_TETHERING;
import static android.net.netstats.provider.NetworkStatsProvider.QUOTA_UNLIMITED;
+import static com.android.networkstack.tethering.TetheringConfiguration.DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS;
+
import android.app.usage.NetworkStatsManager;
import android.net.INetd;
import android.net.MacAddress;
@@ -36,6 +38,7 @@ import android.net.ip.IpServer;
import android.net.netstats.provider.NetworkStatsProvider;
import android.net.util.SharedLog;
import android.net.util.TetheringUtils.ForwardedStats;
+import android.os.ConditionVariable;
import android.os.Handler;
import android.os.RemoteException;
import android.os.ServiceSpecificException;
@@ -47,11 +50,13 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.IndentingPrintWriter;
import java.net.Inet6Address;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
+import java.util.Map;
import java.util.Objects;
/**
@@ -65,8 +70,7 @@ import java.util.Objects;
*/
public class BpfCoordinator {
private static final String TAG = BpfCoordinator.class.getSimpleName();
- @VisibleForTesting
- static final int DEFAULT_PERFORM_POLL_INTERVAL_MS = 5000; // TODO: Make it customizable.
+ private static final int DUMP_TIMEOUT_MS = 10_000;
@VisibleForTesting
enum StatsType {
@@ -85,6 +89,13 @@ public class BpfCoordinator {
@Nullable
private final BpfTetherStatsProvider mStatsProvider;
+ // True if BPF offload is supported, false otherwise. The BPF offload could be disabled by
+ // a runtime resource overlay package or device configuration. This flag is only initialized
+ // in the constructor because it is hard to unwind all existing change once device
+ // configuration is changed. Especially the forwarding rules. Keep the same setting
+ // to make it simpler. See also TetheringConfiguration.
+ private final boolean mIsBpfEnabled;
+
// Tracks whether BPF tethering is started or not. This is set by tethering before it
// starts the first IpServer and is cleared by tethering shortly before the last IpServer
// is stopped. Note that rule updates (especially deletions, but sometimes additions as
@@ -142,22 +153,34 @@ public class BpfCoordinator {
};
@VisibleForTesting
- public static class Dependencies {
- int getPerformPollInterval() {
- // TODO: Consider make this configurable.
- return DEFAULT_PERFORM_POLL_INTERVAL_MS;
- }
+ public abstract static class Dependencies {
+ /** Get handler. */
+ @NonNull public abstract Handler getHandler();
+
+ /** Get netd. */
+ @NonNull public abstract INetd getNetd();
+
+ /** Get network stats manager. */
+ @NonNull public abstract NetworkStatsManager getNetworkStatsManager();
+
+ /** Get shared log. */
+ @NonNull public abstract SharedLog getSharedLog();
+
+ /** Get tethering configuration. */
+ @Nullable public abstract TetheringConfiguration getTetherConfig();
}
@VisibleForTesting
- public BpfCoordinator(@NonNull Handler handler, @NonNull INetd netd,
- @NonNull NetworkStatsManager nsm, @NonNull SharedLog log, @NonNull Dependencies deps) {
- mHandler = handler;
- mNetd = netd;
- mLog = log.forSubComponent(TAG);
+ public BpfCoordinator(@NonNull Dependencies deps) {
+ mDeps = deps;
+ mHandler = mDeps.getHandler();
+ mNetd = mDeps.getNetd();
+ mLog = mDeps.getSharedLog().forSubComponent(TAG);
+ mIsBpfEnabled = isBpfEnabled();
BpfTetherStatsProvider provider = new BpfTetherStatsProvider();
try {
- nsm.registerNetworkStatsProvider(getClass().getSimpleName(), provider);
+ mDeps.getNetworkStatsManager().registerNetworkStatsProvider(
+ getClass().getSimpleName(), provider);
} catch (RuntimeException e) {
// TODO: Perhaps not allow to use BPF offload because the reregistration failure
// implied that no data limit could be applies on a metered upstream if any.
@@ -165,7 +188,6 @@ public class BpfCoordinator {
provider = null;
}
mStatsProvider = provider;
- mDeps = deps;
}
/**
@@ -177,6 +199,11 @@ public class BpfCoordinator {
public void startPolling() {
if (mPollingStarted) return;
+ if (!mIsBpfEnabled) {
+ mLog.i("Offload disabled");
+ return;
+ }
+
mPollingStarted = true;
maybeSchedulePollingStats();
@@ -211,6 +238,8 @@ public class BpfCoordinator {
*/
public void tetherOffloadRuleAdd(
@NonNull final IpServer ipServer, @NonNull final Ipv6ForwardingRule rule) {
+ if (!mIsBpfEnabled) return;
+
try {
// TODO: Perhaps avoid to add a duplicate rule.
mNetd.tetherOffloadRuleAdd(rule.toTetherOffloadRuleParcel());
@@ -250,6 +279,8 @@ public class BpfCoordinator {
*/
public void tetherOffloadRuleRemove(
@NonNull final IpServer ipServer, @NonNull final Ipv6ForwardingRule rule) {
+ if (!mIsBpfEnabled) return;
+
try {
// TODO: Perhaps avoid to remove a non-existent rule.
mNetd.tetherOffloadRuleRemove(rule.toTetherOffloadRuleParcel());
@@ -293,6 +324,8 @@ public class BpfCoordinator {
* Note that this can be only called on handler thread.
*/
public void tetherOffloadRuleClear(@NonNull final IpServer ipServer) {
+ if (!mIsBpfEnabled) return;
+
final LinkedHashMap<Inet6Address, Ipv6ForwardingRule> rules = mIpv6ForwardingRules.get(
ipServer);
if (rules == null) return;
@@ -308,6 +341,8 @@ public class BpfCoordinator {
* Note that this can be only called on handler thread.
*/
public void tetherOffloadRuleUpdate(@NonNull final IpServer ipServer, int newUpstreamIfindex) {
+ if (!mIsBpfEnabled) return;
+
final LinkedHashMap<Inet6Address, Ipv6ForwardingRule> rules = mIpv6ForwardingRules.get(
ipServer);
if (rules == null) return;
@@ -330,6 +365,8 @@ public class BpfCoordinator {
* Note that this can be only called on handler thread.
*/
public void addUpstreamNameToLookupTable(int upstreamIfindex, @NonNull String upstreamIface) {
+ if (!mIsBpfEnabled) return;
+
if (upstreamIfindex == 0 || TextUtils.isEmpty(upstreamIface)) return;
// The same interface index to name mapping may be added by different IpServer objects or
@@ -344,6 +381,77 @@ public class BpfCoordinator {
}
}
+ /**
+ * Dump information.
+ * Block the function until all the data are dumped on the handler thread or timed-out. The
+ * reason is that dumpsys invokes this function on the thread of caller and the data may only
+ * be allowed to be accessed on the handler thread.
+ */
+ public void dump(@NonNull IndentingPrintWriter pw) {
+ final ConditionVariable dumpDone = new ConditionVariable();
+ mHandler.post(() -> {
+ pw.println("mIsBpfEnabled: " + mIsBpfEnabled);
+ pw.println("Polling " + (mPollingStarted ? "started" : "not started"));
+ pw.println("Stats provider " + (mStatsProvider != null
+ ? "registered" : "not registered"));
+ pw.println("Upstream quota: " + mInterfaceQuotas.toString());
+ pw.println("Polling interval: " + getPollingInterval() + " ms");
+
+ pw.println("Forwarding stats:");
+ pw.increaseIndent();
+ if (mStats.size() == 0) {
+ pw.println("<empty>");
+ } else {
+ dumpStats(pw);
+ }
+ pw.decreaseIndent();
+
+ pw.println("Forwarding rules:");
+ pw.increaseIndent();
+ if (mIpv6ForwardingRules.size() == 0) {
+ pw.println("<empty>");
+ } else {
+ dumpIpv6ForwardingRules(pw);
+ }
+ pw.decreaseIndent();
+
+ dumpDone.open();
+ });
+ if (!dumpDone.block(DUMP_TIMEOUT_MS)) {
+ pw.println("... dump timed-out after " + DUMP_TIMEOUT_MS + "ms");
+ }
+ }
+
+ private void dumpStats(@NonNull IndentingPrintWriter pw) {
+ for (int i = 0; i < mStats.size(); i++) {
+ final int upstreamIfindex = mStats.keyAt(i);
+ final ForwardedStats stats = mStats.get(upstreamIfindex);
+ pw.println(String.format("%d(%s) - %s", upstreamIfindex, mInterfaceNames.get(
+ upstreamIfindex), stats.toString()));
+ }
+ }
+
+ private void dumpIpv6ForwardingRules(@NonNull IndentingPrintWriter pw) {
+ for (Map.Entry<IpServer, LinkedHashMap<Inet6Address, Ipv6ForwardingRule>> entry :
+ mIpv6ForwardingRules.entrySet()) {
+ IpServer ipServer = entry.getKey();
+ // The rule downstream interface index is paired with the interface name from
+ // IpServer#interfaceName. See #startIPv6, #updateIpv6ForwardingRules in IpServer.
+ final String downstreamIface = ipServer.interfaceName();
+ pw.println("[" + downstreamIface + "]: iif(iface) oif(iface) v6addr srcmac dstmac");
+
+ pw.increaseIndent();
+ LinkedHashMap<Inet6Address, Ipv6ForwardingRule> rules = entry.getValue();
+ for (Ipv6ForwardingRule rule : rules.values()) {
+ final int upstreamIfindex = rule.upstreamIfindex;
+ pw.println(String.format("%d(%s) %d(%s) %s %s %s", upstreamIfindex,
+ mInterfaceNames.get(upstreamIfindex), rule.downstreamIfindex,
+ downstreamIface, rule.address, rule.srcMac, rule.dstMac));
+ }
+ pw.decreaseIndent();
+ }
+ }
+
/** IPv6 forwarding rule class. */
public static class Ipv6ForwardingRule {
public final int upstreamIfindex;
@@ -474,6 +582,11 @@ public class BpfCoordinator {
}
}
+ private boolean isBpfEnabled() {
+ final TetheringConfiguration config = mDeps.getTetherConfig();
+ return (config != null) ? config.isBpfOffloadEnabled() : true /* default value */;
+ }
+
private int getInterfaceIndexFromRules(@NonNull String ifName) {
for (LinkedHashMap<Inet6Address, Ipv6ForwardingRule> rules : mIpv6ForwardingRules
.values()) {
@@ -625,6 +738,17 @@ public class BpfCoordinator {
updateQuotaAndStatsFromSnapshot(tetherStatsList);
}
+ @VisibleForTesting
+ int getPollingInterval() {
+ // The valid range of interval is DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS..max_long.
+ // Ignore the config value is less than the minimum polling interval. Note that the
+ // minimum interval definition is invoked as OffloadController#isPollingStatsNeeded does.
+ // TODO: Perhaps define a minimum polling interval constant.
+ final TetheringConfiguration config = mDeps.getTetherConfig();
+ final int configInterval = (config != null) ? config.getOffloadPollInterval() : 0;
+ return Math.max(DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS, configInterval);
+ }
+
private void maybeSchedulePollingStats() {
if (!mPollingStarted) return;
@@ -632,6 +756,23 @@ public class BpfCoordinator {
mHandler.removeCallbacks(mScheduledPollingTask);
}
- mHandler.postDelayed(mScheduledPollingTask, mDeps.getPerformPollInterval());
+ mHandler.postDelayed(mScheduledPollingTask, getPollingInterval());
+ }
+
+ // Return forwarding rule map. This is used for testing only.
+ // Note that this can be only called on handler thread.
+ @NonNull
+ @VisibleForTesting
+ final HashMap<IpServer, LinkedHashMap<Inet6Address, Ipv6ForwardingRule>>
+ getForwardingRulesForTesting() {
+ return mIpv6ForwardingRules;
+ }
+
+ // Return upstream interface name map. This is used for testing only.
+ // Note that this can be only called on handler thread.
+ @NonNull
+ @VisibleForTesting
+ final SparseArray<String> getInterfaceNamesForTesting() {
+ return mInterfaceNames;
}
}
diff --git a/packages/Tethering/src/com/android/networkstack/tethering/EntitlementManager.java b/packages/Tethering/src/com/android/networkstack/tethering/EntitlementManager.java
index 3c6e8d88ed13..9dace709d734 100644
--- a/packages/Tethering/src/com/android/networkstack/tethering/EntitlementManager.java
+++ b/packages/Tethering/src/com/android/networkstack/tethering/EntitlementManager.java
@@ -19,6 +19,10 @@ package com.android.networkstack.tethering;
import static android.net.TetheringConstants.EXTRA_ADD_TETHER_TYPE;
import static android.net.TetheringConstants.EXTRA_PROVISION_CALLBACK;
import static android.net.TetheringConstants.EXTRA_RUN_PROVISION;
+import static android.net.TetheringConstants.EXTRA_TETHER_PROVISIONING_RESPONSE;
+import static android.net.TetheringConstants.EXTRA_TETHER_SILENT_PROVISIONING_ACTION;
+import static android.net.TetheringConstants.EXTRA_TETHER_SUBID;
+import static android.net.TetheringConstants.EXTRA_TETHER_UI_PROVISIONING_APP_NAME;
import static android.net.TetheringManager.TETHERING_BLUETOOTH;
import static android.net.TetheringManager.TETHERING_ETHERNET;
import static android.net.TetheringManager.TETHERING_INVALID;
@@ -69,7 +73,6 @@ public class EntitlementManager {
protected static final String DISABLE_PROVISIONING_SYSPROP_KEY = "net.tethering.noprovisioning";
private static final String ACTION_PROVISIONING_ALARM =
"com.android.networkstack.tethering.PROVISIONING_RECHECK_ALARM";
- private static final String EXTRA_SUBID = "subId";
private final ComponentName mSilentProvisioningService;
private static final int MS_PER_HOUR = 60 * 60 * 1000;
@@ -197,9 +200,9 @@ public class EntitlementManager {
// till upstream change to cellular.
if (mUsingCellularAsUpstream) {
if (showProvisioningUi) {
- runUiTetherProvisioning(downstreamType, config.activeDataSubId);
+ runUiTetherProvisioning(downstreamType, config);
} else {
- runSilentTetherProvisioning(downstreamType, config.activeDataSubId);
+ runSilentTetherProvisioning(downstreamType, config);
}
mNeedReRunProvisioningUi = false;
} else {
@@ -262,9 +265,9 @@ public class EntitlementManager {
if (mCurrentEntitlementResults.indexOfKey(downstream) < 0) {
if (mNeedReRunProvisioningUi) {
mNeedReRunProvisioningUi = false;
- runUiTetherProvisioning(downstream, config.activeDataSubId);
+ runUiTetherProvisioning(downstream, config);
} else {
- runSilentTetherProvisioning(downstream, config.activeDataSubId);
+ runSilentTetherProvisioning(downstream, config);
}
}
}
@@ -361,7 +364,7 @@ public class EntitlementManager {
* @param subId default data subscription ID.
*/
@VisibleForTesting
- protected void runSilentTetherProvisioning(int type, int subId) {
+ protected Intent runSilentTetherProvisioning(int type, final TetheringConfiguration config) {
if (DBG) mLog.i("runSilentTetherProvisioning: " + type);
// For silent provisioning, settings would stop tethering when entitlement fail.
ResultReceiver receiver = buildProxyReceiver(type, false/* notifyFail */, null);
@@ -369,17 +372,20 @@ public class EntitlementManager {
Intent intent = new Intent();
intent.putExtra(EXTRA_ADD_TETHER_TYPE, type);
intent.putExtra(EXTRA_RUN_PROVISION, true);
+ intent.putExtra(EXTRA_TETHER_SILENT_PROVISIONING_ACTION, config.provisioningAppNoUi);
+ intent.putExtra(EXTRA_TETHER_PROVISIONING_RESPONSE, config.provisioningResponse);
intent.putExtra(EXTRA_PROVISION_CALLBACK, receiver);
- intent.putExtra(EXTRA_SUBID, subId);
+ intent.putExtra(EXTRA_TETHER_SUBID, config.activeDataSubId);
intent.setComponent(mSilentProvisioningService);
// Only admin user can change tethering and SilentTetherProvisioning don't need to
// show UI, it is fine to always start setting's background service as system user.
mContext.startService(intent);
+ return intent;
}
- private void runUiTetherProvisioning(int type, int subId) {
+ private void runUiTetherProvisioning(int type, final TetheringConfiguration config) {
ResultReceiver receiver = buildProxyReceiver(type, true/* notifyFail */, null);
- runUiTetherProvisioning(type, subId, receiver);
+ runUiTetherProvisioning(type, config, receiver);
}
/**
@@ -389,17 +395,20 @@ public class EntitlementManager {
* @param receiver to receive entitlement check result.
*/
@VisibleForTesting
- protected void runUiTetherProvisioning(int type, int subId, ResultReceiver receiver) {
+ protected Intent runUiTetherProvisioning(int type, final TetheringConfiguration config,
+ ResultReceiver receiver) {
if (DBG) mLog.i("runUiTetherProvisioning: " + type);
Intent intent = new Intent(Settings.ACTION_TETHER_PROVISIONING_UI);
intent.putExtra(EXTRA_ADD_TETHER_TYPE, type);
+ intent.putExtra(EXTRA_TETHER_UI_PROVISIONING_APP_NAME, config.provisioningApp);
intent.putExtra(EXTRA_PROVISION_CALLBACK, receiver);
- intent.putExtra(EXTRA_SUBID, subId);
+ intent.putExtra(EXTRA_TETHER_SUBID, config.activeDataSubId);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// Only launch entitlement UI for system user. Entitlement UI should not appear for other
// user because only admin user is allowed to change tethering.
mContext.startActivity(intent);
+ return intent;
}
// Not needed to check if this don't run on the handler thread because it's private.
@@ -631,7 +640,7 @@ public class EntitlementManager {
receiver.send(cacheValue, null);
} else {
ResultReceiver proxy = buildProxyReceiver(downstream, false/* notifyFail */, receiver);
- runUiTetherProvisioning(downstream, config.activeDataSubId, proxy);
+ runUiTetherProvisioning(downstream, config, proxy);
}
}
}
diff --git a/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java b/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java
index df6745855067..c72ac52740d7 100644
--- a/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java
+++ b/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java
@@ -18,6 +18,7 @@ package com.android.networkstack.tethering;
import static android.Manifest.permission.NETWORK_SETTINGS;
import static android.Manifest.permission.NETWORK_STACK;
+import static android.content.pm.PackageManager.GET_ACTIVITIES;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.hardware.usb.UsbManager.USB_CONFIGURED;
import static android.hardware.usb.UsbManager.USB_CONNECTED;
@@ -62,6 +63,7 @@ import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
import static com.android.networkstack.tethering.TetheringNotificationUpdater.DOWNSTREAM_NONE;
+import android.app.usage.NetworkStatsManager;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothPan;
import android.bluetooth.BluetoothProfile;
@@ -70,6 +72,7 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.pm.PackageManager;
import android.hardware.usb.UsbManager;
import android.net.ConnectivityManager;
import android.net.EthernetManager;
@@ -109,7 +112,6 @@ import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.ServiceSpecificException;
-import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
@@ -285,8 +287,6 @@ public class Tethering {
mUpstreamNetworkMonitor = mDeps.getUpstreamNetworkMonitor(mContext, mTetherMasterSM, mLog,
TetherMasterSM.EVENT_UPSTREAM_CALLBACK);
mForwardedDownstreams = new LinkedHashSet<>();
- mBpfCoordinator = mDeps.getBpfCoordinator(
- mHandler, mNetd, mLog, new BpfCoordinator.Dependencies());
IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_CARRIER_CONFIG_CHANGED);
@@ -324,6 +324,36 @@ public class Tethering {
// Load tethering configuration.
updateConfiguration();
+ // Must be initialized after tethering configuration is loaded because BpfCoordinator
+ // constructor needs to use the configuration.
+ mBpfCoordinator = mDeps.getBpfCoordinator(
+ new BpfCoordinator.Dependencies() {
+ @NonNull
+ public Handler getHandler() {
+ return mHandler;
+ }
+
+ @NonNull
+ public INetd getNetd() {
+ return mNetd;
+ }
+
+ @NonNull
+ public NetworkStatsManager getNetworkStatsManager() {
+ return mContext.getSystemService(NetworkStatsManager.class);
+ }
+
+ @NonNull
+ public SharedLog getSharedLog() {
+ return mLog;
+ }
+
+ @Nullable
+ public TetheringConfiguration getTetherConfig() {
+ return mConfig;
+ }
+ });
+
startStateMachineUpdaters();
}
@@ -782,11 +812,30 @@ public class Tethering {
}
}
+ private boolean isProvisioningNeededButUnavailable() {
+ return isTetherProvisioningRequired() && !doesEntitlementPackageExist();
+ }
+
boolean isTetherProvisioningRequired() {
final TetheringConfiguration cfg = mConfig;
return mEntitlementMgr.isTetherProvisioningRequired(cfg);
}
+ private boolean doesEntitlementPackageExist() {
+ // provisioningApp must contain package and class name.
+ if (mConfig.provisioningApp.length != 2) {
+ return false;
+ }
+
+ final PackageManager pm = mContext.getPackageManager();
+ try {
+ pm.getPackageInfo(mConfig.provisioningApp[0], GET_ACTIVITIES);
+ } catch (PackageManager.NameNotFoundException e) {
+ return false;
+ }
+ return true;
+ }
+
// TODO: Figure out how to update for local hotspot mode interfaces.
private void sendTetherStateChangedBroadcast() {
if (!isTetheringSupported()) return;
@@ -2145,14 +2194,14 @@ public class Tethering {
// gservices could set the secure setting to 1 though to enable it on a build where it
// had previously been turned off.
boolean isTetheringSupported() {
- final int defaultVal =
- SystemProperties.get("ro.tether.denied").equals("true") ? 0 : 1;
+ final int defaultVal = mDeps.isTetheringDenied() ? 0 : 1;
final boolean tetherSupported = Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.TETHER_SUPPORTED, defaultVal) != 0;
final boolean tetherEnabledInSettings = tetherSupported
&& !mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING);
- return tetherEnabledInSettings && hasTetherableConfiguration();
+ return tetherEnabledInSettings && hasTetherableConfiguration()
+ && !isProvisioningNeededButUnavailable();
}
void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter writer, @Nullable String[] args) {
@@ -2216,6 +2265,11 @@ public class Tethering {
mOffloadController.dump(pw);
pw.decreaseIndent();
+ pw.println("BPF offload:");
+ pw.increaseIndent();
+ mBpfCoordinator.dump(pw);
+ pw.decreaseIndent();
+
pw.println("Private address coordinator:");
pw.increaseIndent();
mPrivateAddressCoordinator.dump(pw);
@@ -2350,7 +2404,7 @@ public class Tethering {
final TetherState tetherState = new TetherState(
new IpServer(iface, mLooper, interfaceType, mLog, mNetd, mBpfCoordinator,
makeControlCallback(), mConfig.enableLegacyDhcpServer,
- mConfig.enableBpfOffload, mPrivateAddressCoordinator,
+ mConfig.isBpfOffloadEnabled(), mPrivateAddressCoordinator,
mDeps.getIpServerDependencies()));
mTetherStates.put(iface, tetherState);
tetherState.ipServer.start();
diff --git a/packages/Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java b/packages/Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java
index 48a600dfe6e1..18b2b7804fb0 100644
--- a/packages/Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java
+++ b/packages/Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java
@@ -101,16 +101,17 @@ public class TetheringConfiguration {
public final String[] legacyDhcpRanges;
public final String[] defaultIPv4DNS;
public final boolean enableLegacyDhcpServer;
- // TODO: Add to TetheringConfigurationParcel if required.
- public final boolean enableBpfOffload;
public final String[] provisioningApp;
public final String provisioningAppNoUi;
public final int provisioningCheckPeriod;
+ public final String provisioningResponse;
public final int activeDataSubId;
private final int mOffloadPollInterval;
+ // TODO: Add to TetheringConfigurationParcel if required.
+ private final boolean mEnableBpfOffload;
public TetheringConfiguration(Context ctx, SharedLog log, int id) {
final SharedLog configLog = log.forSubComponent("config");
@@ -137,14 +138,17 @@ public class TetheringConfiguration {
legacyDhcpRanges = getLegacyDhcpRanges(res);
defaultIPv4DNS = copy(DEFAULT_IPV4_DNS);
- enableBpfOffload = getEnableBpfOffload(res);
+ mEnableBpfOffload = getEnableBpfOffload(res);
enableLegacyDhcpServer = getEnableLegacyDhcpServer(res);
provisioningApp = getResourceStringArray(res, R.array.config_mobile_hotspot_provision_app);
- provisioningAppNoUi = getProvisioningAppNoUi(res);
+ provisioningAppNoUi = getResourceString(res,
+ R.string.config_mobile_hotspot_provision_app_no_ui);
provisioningCheckPeriod = getResourceInteger(res,
R.integer.config_mobile_hotspot_provision_check_period,
0 /* No periodic re-check */);
+ provisioningResponse = getResourceString(res,
+ R.string.config_mobile_hotspot_provision_response);
mOffloadPollInterval = getResourceInteger(res,
R.integer.config_tether_offload_poll_interval,
@@ -218,7 +222,7 @@ public class TetheringConfiguration {
pw.println(provisioningAppNoUi);
pw.print("enableBpfOffload: ");
- pw.println(enableBpfOffload);
+ pw.println(mEnableBpfOffload);
pw.print("enableLegacyDhcpServer: ");
pw.println(enableLegacyDhcpServer);
@@ -240,7 +244,7 @@ public class TetheringConfiguration {
toIntArray(preferredUpstreamIfaceTypes)));
sj.add(String.format("provisioningApp:%s", makeString(provisioningApp)));
sj.add(String.format("provisioningAppNoUi:%s", provisioningAppNoUi));
- sj.add(String.format("enableBpfOffload:%s", enableBpfOffload));
+ sj.add(String.format("enableBpfOffload:%s", mEnableBpfOffload));
sj.add(String.format("enableLegacyDhcpServer:%s", enableLegacyDhcpServer));
return String.format("TetheringConfiguration{%s}", sj.toString());
}
@@ -279,6 +283,10 @@ public class TetheringConfiguration {
return mOffloadPollInterval;
}
+ public boolean isBpfOffloadEnabled() {
+ return mEnableBpfOffload;
+ }
+
private static Collection<Integer> getUpstreamIfaceTypes(Resources res, boolean dunRequired) {
final int[] ifaceTypes = res.getIntArray(R.array.config_tether_upstream_types);
final ArrayList<Integer> upstreamIfaceTypes = new ArrayList<>(ifaceTypes.length);
@@ -337,9 +345,9 @@ public class TetheringConfiguration {
return copy(LEGACY_DHCP_DEFAULT_RANGE);
}
- private static String getProvisioningAppNoUi(Resources res) {
+ private static String getResourceString(Resources res, final int resId) {
try {
- return res.getString(R.string.config_mobile_hotspot_provision_app_no_ui);
+ return res.getString(resId);
} catch (Resources.NotFoundException e) {
return "";
}
diff --git a/packages/Tethering/src/com/android/networkstack/tethering/TetheringDependencies.java b/packages/Tethering/src/com/android/networkstack/tethering/TetheringDependencies.java
index d637c8646b4a..131a5fbf2abe 100644
--- a/packages/Tethering/src/com/android/networkstack/tethering/TetheringDependencies.java
+++ b/packages/Tethering/src/com/android/networkstack/tethering/TetheringDependencies.java
@@ -26,6 +26,8 @@ import android.net.util.SharedLog;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
+import android.os.SystemProperties;
+import android.text.TextUtils;
import androidx.annotation.NonNull;
@@ -44,11 +46,8 @@ public abstract class TetheringDependencies {
* Get a reference to the BpfCoordinator to be used by tethering.
*/
public @NonNull BpfCoordinator getBpfCoordinator(
- @NonNull Handler handler, @NonNull INetd netd, @NonNull SharedLog log,
@NonNull BpfCoordinator.Dependencies deps) {
- final NetworkStatsManager statsManager =
- (NetworkStatsManager) getContext().getSystemService(Context.NETWORK_STATS_SERVICE);
- return new BpfCoordinator(handler, netd, statsManager, log, deps);
+ return new BpfCoordinator(deps);
}
/**
@@ -150,4 +149,11 @@ public abstract class TetheringDependencies {
* Get a reference to BluetoothAdapter to be used by tethering.
*/
public abstract BluetoothAdapter getBluetoothAdapter();
+
+ /**
+ * Get SystemProperties which indicate whether tethering is denied.
+ */
+ public boolean isTetheringDenied() {
+ return TextUtils.equals(SystemProperties.get("ro.tether.denied"), "true");
+ }
}
diff --git a/packages/Tethering/tests/unit/src/android/net/ip/IpServerTest.java b/packages/Tethering/tests/unit/src/android/net/ip/IpServerTest.java
index c3bc915a232d..30a9d2252ea6 100644
--- a/packages/Tethering/tests/unit/src/android/net/ip/IpServerTest.java
+++ b/packages/Tethering/tests/unit/src/android/net/ip/IpServerTest.java
@@ -36,7 +36,8 @@ import static android.net.netlink.NetlinkConstants.RTM_NEWNEIGH;
import static android.net.netlink.StructNdMsg.NUD_FAILED;
import static android.net.netlink.StructNdMsg.NUD_REACHABLE;
import static android.net.netlink.StructNdMsg.NUD_STALE;
-import static android.net.shared.Inet4AddressUtils.intToInet4AddressHTH;
+
+import static com.android.net.module.util.Inet4AddressUtils.intToInet4AddressHTH;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -89,12 +90,14 @@ import android.os.test.TestLooper;
import android.text.TextUtils;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import com.android.networkstack.tethering.BpfCoordinator;
import com.android.networkstack.tethering.BpfCoordinator.Ipv6ForwardingRule;
import com.android.networkstack.tethering.PrivateAddressCoordinator;
+import com.android.networkstack.tethering.TetheringConfiguration;
import org.junit.Before;
import org.junit.Test;
@@ -142,6 +145,7 @@ public class IpServerTest {
@Mock private IpServer.Dependencies mDependencies;
@Mock private PrivateAddressCoordinator mAddressCoordinator;
@Mock private NetworkStatsManager mStatsManager;
+ @Mock private TetheringConfiguration mTetherConfig;
@Captor private ArgumentCaptor<DhcpServingParamsParcel> mDhcpParamsCaptor;
@@ -225,10 +229,35 @@ public class IpServerTest {
MockitoAnnotations.initMocks(this);
when(mSharedLog.forSubComponent(anyString())).thenReturn(mSharedLog);
when(mAddressCoordinator.requestDownstreamAddress(any())).thenReturn(mTestAddress);
-
- BpfCoordinator bc = new BpfCoordinator(new Handler(mLooper.getLooper()), mNetd,
- mStatsManager, mSharedLog, new BpfCoordinator.Dependencies());
- mBpfCoordinator = spy(bc);
+ when(mTetherConfig.isBpfOffloadEnabled()).thenReturn(true /* default value */);
+
+ mBpfCoordinator = spy(new BpfCoordinator(
+ new BpfCoordinator.Dependencies() {
+ @NonNull
+ public Handler getHandler() {
+ return new Handler(mLooper.getLooper());
+ }
+
+ @NonNull
+ public INetd getNetd() {
+ return mNetd;
+ }
+
+ @NonNull
+ public NetworkStatsManager getNetworkStatsManager() {
+ return mStatsManager;
+ }
+
+ @NonNull
+ public SharedLog getSharedLog() {
+ return mSharedLog;
+ }
+
+ @Nullable
+ public TetheringConfiguration getTetherConfig() {
+ return mTetherConfig;
+ }
+ }));
}
@Test
@@ -671,18 +700,21 @@ public class IpServerTest {
}
}
- private TetherOffloadRuleParcel matches(
+ @NonNull
+ private static TetherOffloadRuleParcel matches(
int upstreamIfindex, InetAddress dst, MacAddress dstMac) {
return argThat(new TetherOffloadRuleParcelMatcher(upstreamIfindex, dst, dstMac));
}
+ @NonNull
private static Ipv6ForwardingRule makeForwardingRule(
int upstreamIfindex, @NonNull InetAddress dst, @NonNull MacAddress dstMac) {
return new Ipv6ForwardingRule(upstreamIfindex, TEST_IFACE_PARAMS.index,
(Inet6Address) dst, TEST_IFACE_PARAMS.macAddr, dstMac);
}
- private TetherStatsParcel buildEmptyTetherStatsParcel(int ifIndex) {
+ @NonNull
+ private static TetherStatsParcel buildEmptyTetherStatsParcel(int ifIndex) {
TetherStatsParcel parcel = new TetherStatsParcel();
parcel.ifIndex = ifIndex;
return parcel;
@@ -828,6 +860,7 @@ public class IpServerTest {
verify(mBpfCoordinator).tetherOffloadRuleClear(mIpServer);
verify(mNetd).tetherOffloadRuleRemove(matches(UPSTREAM_IFINDEX, neighA, macA));
verify(mNetd).tetherOffloadRuleRemove(matches(UPSTREAM_IFINDEX, neighB, macB));
+ verify(mIpNeighborMonitor).stop();
resetNetdAndBpfCoordinator();
}
diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java
index e2d7aab4e33f..64242ae8255f 100644
--- a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java
+++ b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java
@@ -25,48 +25,76 @@ import static android.net.NetworkStats.UID_ALL;
import static android.net.NetworkStats.UID_TETHERING;
import static android.net.netstats.provider.NetworkStatsProvider.QUOTA_UNLIMITED;
-import static com.android.networkstack.tethering.BpfCoordinator
- .DEFAULT_PERFORM_POLL_INTERVAL_MS;
import static com.android.networkstack.tethering.BpfCoordinator.StatsType;
import static com.android.networkstack.tethering.BpfCoordinator.StatsType.STATS_PER_IFACE;
import static com.android.networkstack.tethering.BpfCoordinator.StatsType.STATS_PER_UID;
-
-import static junit.framework.Assert.assertNotNull;
-
+import static com.android.networkstack.tethering.TetheringConfiguration.DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyLong;
import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.argThat;
import static org.mockito.Mockito.clearInvocations;
+import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import android.annotation.NonNull;
import android.app.usage.NetworkStatsManager;
import android.net.INetd;
+import android.net.InetAddresses;
+import android.net.MacAddress;
import android.net.NetworkStats;
+import android.net.TetherOffloadRuleParcel;
import android.net.TetherStatsParcel;
+import android.net.ip.IpServer;
import android.net.util.SharedLog;
import android.os.Handler;
import android.os.test.TestLooper;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
+import com.android.networkstack.tethering.BpfCoordinator.Ipv6ForwardingRule;
import com.android.testutils.TestableNetworkStatsProviderCbBinder;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
+import org.mockito.ArgumentMatcher;
+import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.net.Inet6Address;
+import java.net.InetAddress;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.LinkedHashMap;
@RunWith(AndroidJUnit4.class)
@SmallTest
public class BpfCoordinatorTest {
+ private static final int DOWNSTREAM_IFINDEX = 10;
+ private static final MacAddress DOWNSTREAM_MAC = MacAddress.ALL_ZEROS_ADDRESS;
+ private static final InetAddress NEIGH_A = InetAddresses.parseNumericAddress("2001:db8::1");
+ private static final InetAddress NEIGH_B = InetAddresses.parseNumericAddress("2001:db8::2");
+ private static final MacAddress MAC_A = MacAddress.fromString("00:00:00:00:00:0a");
+ private static final MacAddress MAC_B = MacAddress.fromString("11:22:33:00:00:0b");
+
@Mock private NetworkStatsManager mStatsManager;
@Mock private INetd mNetd;
+ @Mock private IpServer mIpServer;
+ @Mock private TetheringConfiguration mTetherConfig;
+
// Late init since methods must be called by the thread that created this object.
private TestableNetworkStatsProviderCbBinder mTetherStatsProviderCb;
private BpfCoordinator.BpfTetherStatsProvider mTetherStatsProvider;
@@ -75,14 +103,35 @@ public class BpfCoordinatorTest {
private final TestLooper mTestLooper = new TestLooper();
private BpfCoordinator.Dependencies mDeps =
new BpfCoordinator.Dependencies() {
- @Override
- int getPerformPollInterval() {
- return DEFAULT_PERFORM_POLL_INTERVAL_MS;
+ @NonNull
+ public Handler getHandler() {
+ return new Handler(mTestLooper.getLooper());
+ }
+
+ @NonNull
+ public INetd getNetd() {
+ return mNetd;
+ }
+
+ @NonNull
+ public NetworkStatsManager getNetworkStatsManager() {
+ return mStatsManager;
+ }
+
+ @NonNull
+ public SharedLog getSharedLog() {
+ return new SharedLog("test");
+ }
+
+ @Nullable
+ public TetheringConfiguration getTetherConfig() {
+ return mTetherConfig;
}
};
@Before public void setUp() {
MockitoAnnotations.initMocks(this);
+ when(mTetherConfig.isBpfOffloadEnabled()).thenReturn(true /* default value */);
}
private void waitForIdle() {
@@ -95,9 +144,7 @@ public class BpfCoordinatorTest {
@NonNull
private BpfCoordinator makeBpfCoordinator() throws Exception {
- BpfCoordinator coordinator = new BpfCoordinator(
- new Handler(mTestLooper.getLooper()), mNetd, mStatsManager, new SharedLog("test"),
- mDeps);
+ final BpfCoordinator coordinator = new BpfCoordinator(mDeps);
final ArgumentCaptor<BpfCoordinator.BpfTetherStatsProvider>
tetherStatsProviderCaptor =
ArgumentCaptor.forClass(BpfCoordinator.BpfTetherStatsProvider.class);
@@ -130,9 +177,11 @@ public class BpfCoordinatorTest {
return parcel;
}
+ // Set up specific tether stats list and wait for the stats cache is updated by polling thread
+ // in the coordinator. Beware of that it is only used for the default polling interval.
private void setTetherOffloadStatsList(TetherStatsParcel[] tetherStatsList) throws Exception {
when(mNetd.tetherOffloadGetStats()).thenReturn(tetherStatsList);
- mTestLooper.moveTimeForward(DEFAULT_PERFORM_POLL_INTERVAL_MS);
+ mTestLooper.moveTimeForward(DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS);
waitForIdle();
}
@@ -201,7 +250,7 @@ public class BpfCoordinatorTest {
clearInvocations(mNetd);
// Verify the polling update thread stopped.
- mTestLooper.moveTimeForward(DEFAULT_PERFORM_POLL_INTERVAL_MS);
+ mTestLooper.moveTimeForward(DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS);
waitForIdle();
verify(mNetd, never()).tetherOffloadGetStats();
}
@@ -226,21 +275,333 @@ public class BpfCoordinatorTest {
when(mNetd.tetherOffloadGetStats()).thenReturn(
new TetherStatsParcel[] {buildTestTetherStatsParcel(mobileIfIndex, 0, 0, 0, 0)});
mTetherStatsProvider.onSetAlert(100);
- mTestLooper.moveTimeForward(DEFAULT_PERFORM_POLL_INTERVAL_MS);
+ mTestLooper.moveTimeForward(DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS);
waitForIdle();
mTetherStatsProviderCb.assertNoCallback();
// Verify that notifyAlertReached fired when quota is reached.
when(mNetd.tetherOffloadGetStats()).thenReturn(
new TetherStatsParcel[] {buildTestTetherStatsParcel(mobileIfIndex, 50, 0, 50, 0)});
- mTestLooper.moveTimeForward(DEFAULT_PERFORM_POLL_INTERVAL_MS);
+ mTestLooper.moveTimeForward(DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS);
waitForIdle();
mTetherStatsProviderCb.expectNotifyAlertReached();
// Verify that set quota with UNLIMITED won't trigger any callback.
mTetherStatsProvider.onSetAlert(QUOTA_UNLIMITED);
- mTestLooper.moveTimeForward(DEFAULT_PERFORM_POLL_INTERVAL_MS);
+ mTestLooper.moveTimeForward(DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS);
waitForIdle();
mTetherStatsProviderCb.assertNoCallback();
}
+
+ // The custom ArgumentMatcher simply comes from IpServerTest.
+ // TODO: move both of them into a common utility class for reusing the code.
+ private static class TetherOffloadRuleParcelMatcher implements
+ ArgumentMatcher<TetherOffloadRuleParcel> {
+ public final int upstreamIfindex;
+ public final int downstreamIfindex;
+ public final Inet6Address address;
+ public final MacAddress srcMac;
+ public final MacAddress dstMac;
+
+ TetherOffloadRuleParcelMatcher(@NonNull Ipv6ForwardingRule rule) {
+ upstreamIfindex = rule.upstreamIfindex;
+ downstreamIfindex = rule.downstreamIfindex;
+ address = rule.address;
+ srcMac = rule.srcMac;
+ dstMac = rule.dstMac;
+ }
+
+ public boolean matches(@NonNull TetherOffloadRuleParcel parcel) {
+ return upstreamIfindex == parcel.inputInterfaceIndex
+ && (downstreamIfindex == parcel.outputInterfaceIndex)
+ && Arrays.equals(address.getAddress(), parcel.destination)
+ && (128 == parcel.prefixLength)
+ && Arrays.equals(srcMac.toByteArray(), parcel.srcL2Address)
+ && Arrays.equals(dstMac.toByteArray(), parcel.dstL2Address);
+ }
+
+ public String toString() {
+ return String.format("TetherOffloadRuleParcelMatcher(%d, %d, %s, %s, %s",
+ upstreamIfindex, downstreamIfindex, address.getHostAddress(), srcMac, dstMac);
+ }
+ }
+
+ @NonNull
+ private TetherOffloadRuleParcel matches(@NonNull Ipv6ForwardingRule rule) {
+ return argThat(new TetherOffloadRuleParcelMatcher(rule));
+ }
+
+ @NonNull
+ private static Ipv6ForwardingRule buildTestForwardingRule(
+ int upstreamIfindex, @NonNull InetAddress address, @NonNull MacAddress dstMac) {
+ return new Ipv6ForwardingRule(upstreamIfindex, DOWNSTREAM_IFINDEX, (Inet6Address) address,
+ DOWNSTREAM_MAC, dstMac);
+ }
+
+ @Test
+ public void testSetDataLimit() throws Exception {
+ setupFunctioningNetdInterface();
+
+ final BpfCoordinator coordinator = makeBpfCoordinator();
+
+ final String mobileIface = "rmnet_data0";
+ final Integer mobileIfIndex = 100;
+ coordinator.addUpstreamNameToLookupTable(mobileIfIndex, mobileIface);
+
+ // [1] Default limit.
+ // Set the unlimited quota as default if the service has never applied a data limit for a
+ // given upstream. Note that the data limit only be applied on an upstream which has rules.
+ final Ipv6ForwardingRule rule = buildTestForwardingRule(mobileIfIndex, NEIGH_A, MAC_A);
+ final InOrder inOrder = inOrder(mNetd);
+ coordinator.tetherOffloadRuleAdd(mIpServer, rule);
+ inOrder.verify(mNetd).tetherOffloadRuleAdd(matches(rule));
+ inOrder.verify(mNetd).tetherOffloadSetInterfaceQuota(mobileIfIndex, QUOTA_UNLIMITED);
+ inOrder.verifyNoMoreInteractions();
+
+ // [2] Specific limit.
+ // Applying the data limit boundary {min, 1gb, max, infinity} on current upstream.
+ for (final long quota : new long[] {0, 1048576000, Long.MAX_VALUE, QUOTA_UNLIMITED}) {
+ mTetherStatsProvider.onSetLimit(mobileIface, quota);
+ waitForIdle();
+ inOrder.verify(mNetd).tetherOffloadSetInterfaceQuota(mobileIfIndex, quota);
+ inOrder.verifyNoMoreInteractions();
+ }
+
+ // [3] Invalid limit.
+ // The valid range of quota is 0..max_int64 or -1 (unlimited).
+ final long invalidLimit = Long.MIN_VALUE;
+ try {
+ mTetherStatsProvider.onSetLimit(mobileIface, invalidLimit);
+ waitForIdle();
+ fail("No exception thrown for invalid limit " + invalidLimit + ".");
+ } catch (IllegalArgumentException expected) {
+ assertEquals(expected.getMessage(), "invalid quota value " + invalidLimit);
+ }
+ }
+
+ // TODO: Test the case in which the rules are changed from different IpServer objects.
+ @Test
+ public void testSetDataLimitOnRuleChange() throws Exception {
+ setupFunctioningNetdInterface();
+
+ final BpfCoordinator coordinator = makeBpfCoordinator();
+
+ final String mobileIface = "rmnet_data0";
+ final Integer mobileIfIndex = 100;
+ coordinator.addUpstreamNameToLookupTable(mobileIfIndex, mobileIface);
+
+ // Applying a data limit to the current upstream does not take any immediate action.
+ // The data limit could be only set on an upstream which has rules.
+ final long limit = 12345;
+ final InOrder inOrder = inOrder(mNetd);
+ mTetherStatsProvider.onSetLimit(mobileIface, limit);
+ waitForIdle();
+ inOrder.verify(mNetd, never()).tetherOffloadSetInterfaceQuota(anyInt(), anyLong());
+
+ // Adding the first rule on current upstream immediately sends the quota to netd.
+ final Ipv6ForwardingRule ruleA = buildTestForwardingRule(mobileIfIndex, NEIGH_A, MAC_A);
+ coordinator.tetherOffloadRuleAdd(mIpServer, ruleA);
+ inOrder.verify(mNetd).tetherOffloadRuleAdd(matches(ruleA));
+ inOrder.verify(mNetd).tetherOffloadSetInterfaceQuota(mobileIfIndex, limit);
+ inOrder.verifyNoMoreInteractions();
+
+ // Adding the second rule on current upstream does not send the quota to netd.
+ final Ipv6ForwardingRule ruleB = buildTestForwardingRule(mobileIfIndex, NEIGH_B, MAC_B);
+ coordinator.tetherOffloadRuleAdd(mIpServer, ruleB);
+ inOrder.verify(mNetd).tetherOffloadRuleAdd(matches(ruleB));
+ inOrder.verify(mNetd, never()).tetherOffloadSetInterfaceQuota(anyInt(), anyLong());
+
+ // Removing the second rule on current upstream does not send the quota to netd.
+ coordinator.tetherOffloadRuleRemove(mIpServer, ruleB);
+ inOrder.verify(mNetd).tetherOffloadRuleRemove(matches(ruleB));
+ inOrder.verify(mNetd, never()).tetherOffloadSetInterfaceQuota(anyInt(), anyLong());
+
+ // Removing the last rule on current upstream immediately sends the cleanup stuff to netd.
+ when(mNetd.tetherOffloadGetAndClearStats(mobileIfIndex))
+ .thenReturn(buildTestTetherStatsParcel(mobileIfIndex, 0, 0, 0, 0));
+ coordinator.tetherOffloadRuleRemove(mIpServer, ruleA);
+ inOrder.verify(mNetd).tetherOffloadRuleRemove(matches(ruleA));
+ inOrder.verify(mNetd).tetherOffloadGetAndClearStats(mobileIfIndex);
+ inOrder.verifyNoMoreInteractions();
+ }
+
+ @Test
+ public void testTetherOffloadRuleUpdateAndClear() throws Exception {
+ setupFunctioningNetdInterface();
+
+ final BpfCoordinator coordinator = makeBpfCoordinator();
+
+ final String ethIface = "eth1";
+ final String mobileIface = "rmnet_data0";
+ final Integer ethIfIndex = 100;
+ final Integer mobileIfIndex = 101;
+ coordinator.addUpstreamNameToLookupTable(ethIfIndex, ethIface);
+ coordinator.addUpstreamNameToLookupTable(mobileIfIndex, mobileIface);
+
+ final InOrder inOrder = inOrder(mNetd);
+
+ // Before the rule test, here are the additional actions while the rules are changed.
+ // - After adding the first rule on a given upstream, the coordinator adds a data limit.
+ // If the service has never applied the data limit, set an unlimited quota as default.
+ // - After removing the last rule on a given upstream, the coordinator gets the last stats.
+ // Then, it clears the stats and the limit entry from BPF maps.
+ // See tetherOffloadRule{Add, Remove, Clear, Clean}.
+
+ // [1] Adding rules on the upstream Ethernet.
+ // Note that the default data limit is applied after the first rule is added.
+ final Ipv6ForwardingRule ethernetRuleA = buildTestForwardingRule(
+ ethIfIndex, NEIGH_A, MAC_A);
+ final Ipv6ForwardingRule ethernetRuleB = buildTestForwardingRule(
+ ethIfIndex, NEIGH_B, MAC_B);
+
+ coordinator.tetherOffloadRuleAdd(mIpServer, ethernetRuleA);
+ inOrder.verify(mNetd).tetherOffloadRuleAdd(matches(ethernetRuleA));
+ inOrder.verify(mNetd).tetherOffloadSetInterfaceQuota(ethIfIndex, QUOTA_UNLIMITED);
+
+ coordinator.tetherOffloadRuleAdd(mIpServer, ethernetRuleB);
+ inOrder.verify(mNetd).tetherOffloadRuleAdd(matches(ethernetRuleB));
+
+ // [2] Update the existing rules from Ethernet to cellular.
+ final Ipv6ForwardingRule mobileRuleA = buildTestForwardingRule(
+ mobileIfIndex, NEIGH_A, MAC_A);
+ final Ipv6ForwardingRule mobileRuleB = buildTestForwardingRule(
+ mobileIfIndex, NEIGH_B, MAC_B);
+ when(mNetd.tetherOffloadGetAndClearStats(ethIfIndex))
+ .thenReturn(buildTestTetherStatsParcel(ethIfIndex, 10, 20, 30, 40));
+
+ // Update the existing rules for upstream changes. The rules are removed and re-added one
+ // by one for updating upstream interface index by #tetherOffloadRuleUpdate.
+ coordinator.tetherOffloadRuleUpdate(mIpServer, mobileIfIndex);
+ inOrder.verify(mNetd).tetherOffloadRuleRemove(matches(ethernetRuleA));
+ inOrder.verify(mNetd).tetherOffloadRuleAdd(matches(mobileRuleA));
+ inOrder.verify(mNetd).tetherOffloadSetInterfaceQuota(mobileIfIndex, QUOTA_UNLIMITED);
+ inOrder.verify(mNetd).tetherOffloadRuleRemove(matches(ethernetRuleB));
+ inOrder.verify(mNetd).tetherOffloadGetAndClearStats(ethIfIndex);
+ inOrder.verify(mNetd).tetherOffloadRuleAdd(matches(mobileRuleB));
+
+ // [3] Clear all rules for a given IpServer.
+ when(mNetd.tetherOffloadGetAndClearStats(mobileIfIndex))
+ .thenReturn(buildTestTetherStatsParcel(mobileIfIndex, 50, 60, 70, 80));
+ coordinator.tetherOffloadRuleClear(mIpServer);
+ inOrder.verify(mNetd).tetherOffloadRuleRemove(matches(mobileRuleA));
+ inOrder.verify(mNetd).tetherOffloadRuleRemove(matches(mobileRuleB));
+ inOrder.verify(mNetd).tetherOffloadGetAndClearStats(mobileIfIndex);
+
+ // [4] Force pushing stats update to verify that the last diff of stats is reported on all
+ // upstreams.
+ mTetherStatsProvider.pushTetherStats();
+ mTetherStatsProviderCb.expectNotifyStatsUpdated(
+ new NetworkStats(0L, 2)
+ .addEntry(buildTestEntry(STATS_PER_IFACE, ethIface, 10, 20, 30, 40))
+ .addEntry(buildTestEntry(STATS_PER_IFACE, mobileIface, 50, 60, 70, 80)),
+ new NetworkStats(0L, 2)
+ .addEntry(buildTestEntry(STATS_PER_UID, ethIface, 10, 20, 30, 40))
+ .addEntry(buildTestEntry(STATS_PER_UID, mobileIface, 50, 60, 70, 80)));
+ }
+
+ @Test
+ public void testTetheringConfigDisable() throws Exception {
+ setupFunctioningNetdInterface();
+ when(mTetherConfig.isBpfOffloadEnabled()).thenReturn(false);
+
+ final BpfCoordinator coordinator = makeBpfCoordinator();
+ coordinator.startPolling();
+
+ // The tether stats polling task should not be scheduled.
+ mTestLooper.moveTimeForward(DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS);
+ waitForIdle();
+ verify(mNetd, never()).tetherOffloadGetStats();
+
+ // The interface name lookup table can't be added.
+ final String iface = "rmnet_data0";
+ final Integer ifIndex = 100;
+ coordinator.addUpstreamNameToLookupTable(ifIndex, iface);
+ assertEquals(0, coordinator.getInterfaceNamesForTesting().size());
+
+ // The rule can't be added.
+ final InetAddress neigh = InetAddresses.parseNumericAddress("2001:db8::1");
+ final MacAddress mac = MacAddress.fromString("00:00:00:00:00:0a");
+ final Ipv6ForwardingRule rule = buildTestForwardingRule(ifIndex, neigh, mac);
+ coordinator.tetherOffloadRuleAdd(mIpServer, rule);
+ verify(mNetd, never()).tetherOffloadRuleAdd(any());
+ LinkedHashMap<Inet6Address, Ipv6ForwardingRule> rules =
+ coordinator.getForwardingRulesForTesting().get(mIpServer);
+ assertNull(rules);
+
+ // The rule can't be removed. This is not a realistic case because adding rule is not
+ // allowed. That implies no rule could be removed, cleared or updated. Verify these
+ // cases just in case.
+ rules = new LinkedHashMap<Inet6Address, Ipv6ForwardingRule>();
+ rules.put(rule.address, rule);
+ coordinator.getForwardingRulesForTesting().put(mIpServer, rules);
+ coordinator.tetherOffloadRuleRemove(mIpServer, rule);
+ verify(mNetd, never()).tetherOffloadRuleRemove(any());
+ rules = coordinator.getForwardingRulesForTesting().get(mIpServer);
+ assertNotNull(rules);
+ assertEquals(1, rules.size());
+
+ // The rule can't be cleared.
+ coordinator.tetherOffloadRuleClear(mIpServer);
+ verify(mNetd, never()).tetherOffloadRuleRemove(any());
+ rules = coordinator.getForwardingRulesForTesting().get(mIpServer);
+ assertNotNull(rules);
+ assertEquals(1, rules.size());
+
+ // The rule can't be updated.
+ coordinator.tetherOffloadRuleUpdate(mIpServer, rule.upstreamIfindex + 1 /* new */);
+ verify(mNetd, never()).tetherOffloadRuleRemove(any());
+ verify(mNetd, never()).tetherOffloadRuleAdd(any());
+ rules = coordinator.getForwardingRulesForTesting().get(mIpServer);
+ assertNotNull(rules);
+ assertEquals(1, rules.size());
+ }
+
+ @Test
+ public void testTetheringConfigSetPollingInterval() throws Exception {
+ setupFunctioningNetdInterface();
+
+ final BpfCoordinator coordinator = makeBpfCoordinator();
+
+ // [1] The default polling interval.
+ coordinator.startPolling();
+ assertEquals(DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS, coordinator.getPollingInterval());
+ coordinator.stopPolling();
+
+ // [2] Expect the invalid polling interval isn't applied. The valid range of interval is
+ // DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS..max_long.
+ for (final int interval
+ : new int[] {0, 100, DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS - 1}) {
+ when(mTetherConfig.getOffloadPollInterval()).thenReturn(interval);
+ coordinator.startPolling();
+ assertEquals(DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS, coordinator.getPollingInterval());
+ coordinator.stopPolling();
+ }
+
+ // [3] Set a specific polling interval which is larger than default value.
+ // Use a large polling interval to avoid flaky test because the time forwarding
+ // approximation is used to verify the scheduled time of the polling thread.
+ final int pollingInterval = 100_000;
+ when(mTetherConfig.getOffloadPollInterval()).thenReturn(pollingInterval);
+ coordinator.startPolling();
+
+ // Expect the specific polling interval to be applied.
+ assertEquals(pollingInterval, coordinator.getPollingInterval());
+
+ // Start on a new polling time slot.
+ mTestLooper.moveTimeForward(pollingInterval);
+ waitForIdle();
+ clearInvocations(mNetd);
+
+ // Move time forward to 90% polling interval time. Expect that the polling thread has not
+ // scheduled yet.
+ mTestLooper.moveTimeForward((long) (pollingInterval * 0.9));
+ waitForIdle();
+ verify(mNetd, never()).tetherOffloadGetStats();
+
+ // Move time forward to the remaining 10% polling interval time. Expect that the polling
+ // thread has scheduled.
+ mTestLooper.moveTimeForward((long) (pollingInterval * 0.1));
+ waitForIdle();
+ verify(mNetd).tetherOffloadGetStats();
+ }
}
diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/EntitlementManagerTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/EntitlementManagerTest.java
index 72fa916b9e42..354e75356e9f 100644
--- a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/EntitlementManagerTest.java
+++ b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/EntitlementManagerTest.java
@@ -16,8 +16,16 @@
package com.android.networkstack.tethering;
+import static android.net.TetheringConstants.EXTRA_ADD_TETHER_TYPE;
+import static android.net.TetheringConstants.EXTRA_PROVISION_CALLBACK;
+import static android.net.TetheringConstants.EXTRA_RUN_PROVISION;
+import static android.net.TetheringConstants.EXTRA_TETHER_PROVISIONING_RESPONSE;
+import static android.net.TetheringConstants.EXTRA_TETHER_SILENT_PROVISIONING_ACTION;
+import static android.net.TetheringConstants.EXTRA_TETHER_SUBID;
+import static android.net.TetheringConstants.EXTRA_TETHER_UI_PROVISIONING_APP_NAME;
import static android.net.TetheringManager.TETHERING_BLUETOOTH;
import static android.net.TetheringManager.TETHERING_ETHERNET;
+import static android.net.TetheringManager.TETHERING_INVALID;
import static android.net.TetheringManager.TETHERING_USB;
import static android.net.TetheringManager.TETHERING_WIFI;
import static android.net.TetheringManager.TETHERING_WIFI_P2P;
@@ -44,6 +52,7 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
+import android.content.Intent;
import android.content.res.Resources;
import android.net.util.SharedLog;
import android.os.Bundle;
@@ -53,6 +62,7 @@ import android.os.ResultReceiver;
import android.os.SystemProperties;
import android.os.test.TestLooper;
import android.provider.DeviceConfig;
+import android.provider.Settings;
import android.telephony.CarrierConfigManager;
import androidx.test.filters.SmallTest;
@@ -76,6 +86,7 @@ public final class EntitlementManagerTest {
private static final String[] PROVISIONING_APP_NAME = {"some", "app"};
private static final String PROVISIONING_NO_UI_APP_NAME = "no_ui_app";
+ private static final String PROVISIONING_APP_RESPONSE = "app_response";
@Mock private CarrierConfigManager mCarrierConfigManager;
@Mock private Context mContext;
@@ -122,15 +133,51 @@ public final class EntitlementManagerTest {
}
@Override
- protected void runUiTetherProvisioning(int type, int subId, ResultReceiver receiver) {
+ protected Intent runUiTetherProvisioning(int type,
+ final TetheringConfiguration config, final ResultReceiver receiver) {
+ Intent intent = super.runUiTetherProvisioning(type, config, receiver);
+ assertUiTetherProvisioningIntent(type, config, receiver, intent);
uiProvisionCount++;
receiver.send(fakeEntitlementResult, null);
+ return intent;
+ }
+
+ private void assertUiTetherProvisioningIntent(int type, final TetheringConfiguration config,
+ final ResultReceiver receiver, final Intent intent) {
+ assertEquals(Settings.ACTION_TETHER_PROVISIONING_UI, intent.getAction());
+ assertEquals(type, intent.getIntExtra(EXTRA_ADD_TETHER_TYPE, TETHERING_INVALID));
+ final String[] appName = intent.getStringArrayExtra(
+ EXTRA_TETHER_UI_PROVISIONING_APP_NAME);
+ assertEquals(PROVISIONING_APP_NAME.length, appName.length);
+ for (int i = 0; i < PROVISIONING_APP_NAME.length; i++) {
+ assertEquals(PROVISIONING_APP_NAME[i], appName[i]);
+ }
+ assertEquals(receiver, intent.getParcelableExtra(EXTRA_PROVISION_CALLBACK));
+ assertEquals(config.activeDataSubId,
+ intent.getIntExtra(EXTRA_TETHER_SUBID, INVALID_SUBSCRIPTION_ID));
}
@Override
- protected void runSilentTetherProvisioning(int type, int subId) {
+ protected Intent runSilentTetherProvisioning(int type,
+ final TetheringConfiguration config) {
+ Intent intent = super.runSilentTetherProvisioning(type, config);
+ assertSilentTetherProvisioning(type, config, intent);
silentProvisionCount++;
addDownstreamMapping(type, fakeEntitlementResult);
+ return intent;
+ }
+
+ private void assertSilentTetherProvisioning(int type, final TetheringConfiguration config,
+ final Intent intent) {
+ assertEquals(type, intent.getIntExtra(EXTRA_ADD_TETHER_TYPE, TETHERING_INVALID));
+ assertEquals(true, intent.getBooleanExtra(EXTRA_RUN_PROVISION, false));
+ assertEquals(PROVISIONING_NO_UI_APP_NAME,
+ intent.getStringExtra(EXTRA_TETHER_SILENT_PROVISIONING_ACTION));
+ assertEquals(PROVISIONING_APP_RESPONSE,
+ intent.getStringExtra(EXTRA_TETHER_PROVISIONING_RESPONSE));
+ assertTrue(intent.hasExtra(EXTRA_PROVISION_CALLBACK));
+ assertEquals(config.activeDataSubId,
+ intent.getIntExtra(EXTRA_TETHER_SUBID, INVALID_SUBSCRIPTION_ID));
}
}
@@ -187,6 +234,8 @@ public final class EntitlementManagerTest {
.thenReturn(PROVISIONING_APP_NAME);
when(mResources.getString(R.string.config_mobile_hotspot_provision_app_no_ui))
.thenReturn(PROVISIONING_NO_UI_APP_NAME);
+ when(mResources.getString(R.string.config_mobile_hotspot_provision_response)).thenReturn(
+ PROVISIONING_APP_RESPONSE);
// Act like the CarrierConfigManager is present and ready unless told otherwise.
when(mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE))
.thenReturn(mCarrierConfigManager);
diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringConfigurationTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringConfigurationTest.java
index 1999ad786ed4..a9ac4e2851f3 100644
--- a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringConfigurationTest.java
+++ b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringConfigurationTest.java
@@ -61,6 +61,8 @@ public class TetheringConfigurationTest {
private final SharedLog mLog = new SharedLog("TetheringConfigurationTest");
private static final String[] PROVISIONING_APP_NAME = {"some", "app"};
+ private static final String PROVISIONING_NO_UI_APP_NAME = "no_ui_app";
+ private static final String PROVISIONING_APP_RESPONSE = "app_response";
@Mock private Context mContext;
@Mock private TelephonyManager mTelephonyManager;
@Mock private Resources mResources;
@@ -292,7 +294,7 @@ public class TetheringConfigurationTest {
initializeBpfOffloadConfiguration(true, null /* unset */);
final TetheringConfiguration enableByRes =
new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
- assertTrue(enableByRes.enableBpfOffload);
+ assertTrue(enableByRes.isBpfOffloadEnabled());
}
@Test
@@ -301,7 +303,7 @@ public class TetheringConfigurationTest {
initializeBpfOffloadConfiguration(res, "true");
final TetheringConfiguration enableByDevConOverride =
new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
- assertTrue(enableByDevConOverride.enableBpfOffload);
+ assertTrue(enableByDevConOverride.isBpfOffloadEnabled());
}
}
@@ -310,7 +312,7 @@ public class TetheringConfigurationTest {
initializeBpfOffloadConfiguration(false, null /* unset */);
final TetheringConfiguration disableByRes =
new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
- assertFalse(disableByRes.enableBpfOffload);
+ assertFalse(disableByRes.isBpfOffloadEnabled());
}
@Test
@@ -319,7 +321,7 @@ public class TetheringConfigurationTest {
initializeBpfOffloadConfiguration(res, "false");
final TetheringConfiguration disableByDevConOverride =
new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
- assertFalse(disableByDevConOverride.enableBpfOffload);
+ assertFalse(disableByDevConOverride.isBpfOffloadEnabled());
}
}
@@ -388,6 +390,8 @@ public class TetheringConfigurationTest {
new MockTetheringConfiguration(mMockContext, mLog, anyValidSubId);
assertEquals(mockCfg.provisioningApp[0], PROVISIONING_APP_NAME[0]);
assertEquals(mockCfg.provisioningApp[1], PROVISIONING_APP_NAME[1]);
+ assertEquals(mockCfg.provisioningAppNoUi, PROVISIONING_NO_UI_APP_NAME);
+ assertEquals(mockCfg.provisioningResponse, PROVISIONING_APP_RESPONSE);
}
private void setUpResourceForSubId() {
@@ -403,6 +407,10 @@ public class TetheringConfigurationTest {
new int[0]);
when(mResourcesForSubId.getStringArray(
R.array.config_mobile_hotspot_provision_app)).thenReturn(PROVISIONING_APP_NAME);
+ when(mResourcesForSubId.getString(R.string.config_mobile_hotspot_provision_app_no_ui))
+ .thenReturn(PROVISIONING_NO_UI_APP_NAME);
+ when(mResourcesForSubId.getString(
+ R.string.config_mobile_hotspot_provision_response)).thenReturn(
+ PROVISIONING_APP_RESPONSE);
}
-
}
diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
index 8146a58dddcb..64538c7d97c1 100644
--- a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
+++ b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
@@ -16,6 +16,7 @@
package com.android.networkstack.tethering;
+import static android.content.pm.PackageManager.GET_ACTIVITIES;
import static android.hardware.usb.UsbManager.USB_CONFIGURED;
import static android.hardware.usb.UsbManager.USB_CONNECTED;
import static android.hardware.usb.UsbManager.USB_FUNCTION_NCM;
@@ -39,7 +40,6 @@ import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_FAILED;
import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STARTED;
import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STOPPED;
import static android.net.dhcp.IDhcpServer.STATUS_SUCCESS;
-import static android.net.shared.Inet4AddressUtils.intToInet4AddressHTH;
import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_INTERFACE_NAME;
import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_MODE;
import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_STATE;
@@ -48,6 +48,7 @@ import static android.net.wifi.WifiManager.IFACE_IP_MODE_TETHERED;
import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLED;
import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+import static com.android.net.module.util.Inet4AddressUtils.intToInet4AddressHTH;
import static com.android.networkstack.tethering.TetheringNotificationUpdater.DOWNSTREAM_NONE;
import static com.android.networkstack.tethering.UpstreamNetworkMonitor.EVENT_ON_CAPABILITIES;
@@ -81,6 +82,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.hardware.usb.UsbManager;
import android.net.ConnectivityManager;
@@ -204,6 +206,7 @@ public class TetheringTest {
@Mock private EthernetManager mEm;
@Mock private TetheringNotificationUpdater mNotificationUpdater;
@Mock private BpfCoordinator mBpfCoordinator;
+ @Mock private PackageManager mPackageManager;
private final MockIpServerDependencies mIpServerDependencies =
spy(new MockIpServerDependencies());
@@ -264,6 +267,11 @@ public class TetheringTest {
}
@Override
+ public PackageManager getPackageManager() {
+ return mPackageManager;
+ }
+
+ @Override
public String getSystemServiceName(Class<?> serviceClass) {
if (TelephonyManager.class.equals(serviceClass)) return Context.TELEPHONY_SERVICE;
return super.getSystemServiceName(serviceClass);
@@ -338,8 +346,8 @@ public class TetheringTest {
}
@Override
- public BpfCoordinator getBpfCoordinator(Handler handler, INetd netd,
- SharedLog log, BpfCoordinator.Dependencies deps) {
+ public BpfCoordinator getBpfCoordinator(
+ BpfCoordinator.Dependencies deps) {
return mBpfCoordinator;
}
@@ -425,6 +433,11 @@ public class TetheringTest {
public TetheringNotificationUpdater getNotificationUpdater(Context ctx, Looper looper) {
return mNotificationUpdater;
}
+
+ @Override
+ public boolean isTetheringDenied() {
+ return false;
+ }
}
private static UpstreamNetworkState buildMobileUpstreamState(boolean withIPv4,
@@ -1951,6 +1964,23 @@ public class TetheringTest {
assertEquals(TETHER_ERROR_IFACE_CFG_ERROR, mTethering.getLastTetherError(TEST_ETH_IFNAME));
}
+ @Test
+ public void testProvisioningNeededButUnavailable() throws Exception {
+ assertTrue(mTethering.isTetheringSupported());
+ verify(mPackageManager, never()).getPackageInfo(PROVISIONING_APP_NAME[0], GET_ACTIVITIES);
+
+ setupForRequiredProvisioning();
+ assertTrue(mTethering.isTetheringSupported());
+ verify(mPackageManager).getPackageInfo(PROVISIONING_APP_NAME[0], GET_ACTIVITIES);
+ reset(mPackageManager);
+
+ doThrow(PackageManager.NameNotFoundException.class).when(mPackageManager).getPackageInfo(
+ PROVISIONING_APP_NAME[0], GET_ACTIVITIES);
+ setupForRequiredProvisioning();
+ assertFalse(mTethering.isTetheringSupported());
+ verify(mPackageManager).getPackageInfo(PROVISIONING_APP_NAME[0], GET_ACTIVITIES);
+ }
+
// TODO: Test that a request for hotspot mode doesn't interfere with an
// already operating tethering mode interface.
}
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 7f912a4fc1ce..d2b1bd1a6008 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -56,6 +56,8 @@ import android.content.pm.PackageManagerInternal;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.database.ContentObserver;
+import android.graphics.Point;
+import android.graphics.Rect;
import android.graphics.Region;
import android.hardware.display.DisplayManager;
import android.hardware.fingerprint.IFingerprintService;
@@ -190,6 +192,9 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
private final SimpleStringSplitter mStringColonSplitter =
new SimpleStringSplitter(COMPONENT_NAME_SEPARATOR);
+ private final Rect mTempRect = new Rect();
+ private final Rect mTempRect1 = new Rect();
+
private final PackageManager mPackageManager;
private final PowerManager mPowerManager;
@@ -246,6 +251,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
//TODO: Remove this hack
private boolean mInitialized;
+ private Point mTempPoint;
private boolean mIsAccessibilityButtonShown;
private AccessibilityUserState getCurrentUserStateLocked() {
@@ -1068,6 +1074,18 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
}
/**
+ * Gets a point within the accessibility focused node where we can send down
+ * and up events to perform a click.
+ *
+ * @param outPoint The click point to populate.
+ * @return Whether accessibility a click point was found and set.
+ */
+ // TODO: (multi-display) Make sure this works for multiple displays.
+ public boolean getAccessibilityFocusClickPointInScreen(Point outPoint) {
+ return getInteractionBridge().getAccessibilityFocusClickPointInScreenNotLocked(outPoint);
+ }
+
+ /**
* Perform an accessibility action on the view that currently has accessibility focus.
* Has no effect if no item has accessibility focus, if the item with accessibility
* focus does not expose the specified action, or if the action fails.
@@ -1081,6 +1099,32 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
return getInteractionBridge().performActionOnAccessibilityFocusedItemNotLocked(action);
}
+ /**
+ * Returns true if accessibility focus is confined to the active window.
+ */
+ public boolean accessibilityFocusOnlyInActiveWindow() {
+ synchronized (mLock) {
+ return mA11yWindowManager.isTrackingWindowsLocked();
+ }
+ }
+
+ /**
+ * Gets the bounds of a window.
+ *
+ * @param outBounds The output to which to write the bounds.
+ */
+ boolean getWindowBounds(int windowId, Rect outBounds) {
+ IBinder token;
+ synchronized (mLock) {
+ token = getWindowToken(windowId, mCurrentUserId);
+ }
+ mWindowManagerService.getWindowFrame(token, outBounds);
+ if (!outBounds.isEmpty()) {
+ return true;
+ }
+ return false;
+ }
+
public int getActiveWindowId() {
return mA11yWindowManager.getActiveWindowId(mCurrentUserId);
}
@@ -1824,9 +1868,11 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
for (int i = 0; !observingWindows && (i < boundServiceCount); i++) {
AccessibilityServiceConnection boundService = boundServices.get(i);
if (boundService.canRetrieveInteractiveWindowsLocked()) {
+ userState.setAccessibilityFocusOnlyInActiveWindow(false);
observingWindows = true;
}
}
+ userState.setAccessibilityFocusOnlyInActiveWindow(true);
// Gets all valid displays and start tracking windows of each display if there is at least
// one bound service that can retrieve window content.
@@ -2930,6 +2976,19 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
}
/**
+ * Gets a point within the accessibility focused node where we can send down and up events
+ * to perform a click.
+ *
+ * @param outPoint The click point to populate.
+ * @return Whether accessibility a click point was found and set.
+ */
+ // TODO: (multi-display) Make sure this works for multiple displays.
+ boolean getAccessibilityFocusClickPointInScreen(Point outPoint) {
+ return getInteractionBridge()
+ .getAccessibilityFocusClickPointInScreenNotLocked(outPoint);
+ }
+
+ /**
* Perform an accessibility action on the view that currently has accessibility focus.
* Has no effect if no item has accessibility focus, if the item with accessibility
* focus does not expose the specified action, or if the action fails.
@@ -2947,6 +3006,43 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
return focus.performAction(action.getId());
}
+ public boolean getAccessibilityFocusClickPointInScreenNotLocked(Point outPoint) {
+ AccessibilityNodeInfo focus = getAccessibilityFocusNotLocked();
+ if (focus == null) {
+ return false;
+ }
+
+ synchronized (mLock) {
+ Rect boundsInScreen = mTempRect;
+ focus.getBoundsInScreen(boundsInScreen);
+
+ // Apply magnification if needed.
+ MagnificationSpec spec = getCompatibleMagnificationSpecLocked(focus.getWindowId());
+ if (spec != null && !spec.isNop()) {
+ boundsInScreen.offset((int) -spec.offsetX, (int) -spec.offsetY);
+ boundsInScreen.scale(1 / spec.scale);
+ }
+
+ // Clip to the window bounds.
+ Rect windowBounds = mTempRect1;
+ getWindowBounds(focus.getWindowId(), windowBounds);
+ if (!boundsInScreen.intersect(windowBounds)) {
+ return false;
+ }
+
+ // Clip to the screen bounds.
+ Point screenSize = mTempPoint;
+ mDefaultDisplay.getRealSize(screenSize);
+ if (!boundsInScreen.intersect(0, 0, screenSize.x, screenSize.y)) {
+ return false;
+ }
+
+ outPoint.set(boundsInScreen.centerX(), boundsInScreen.centerY());
+ }
+
+ return true;
+ }
+
private AccessibilityNodeInfo getAccessibilityFocusNotLocked() {
final int focusedWindowId;
synchronized (mLock) {
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java
index 43bb4b384bb2..0845d019c060 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java
@@ -104,6 +104,7 @@ class AccessibilityUserState {
private boolean mIsDisplayMagnificationEnabled;
private boolean mIsFilterKeyEventsEnabled;
private boolean mIsPerformGesturesEnabled;
+ private boolean mAccessibilityFocusOnlyInActiveWindow;
private boolean mIsTextHighContrastEnabled;
private boolean mIsTouchExplorationEnabled;
private boolean mServiceHandlesDoubleTap;
@@ -685,6 +686,13 @@ class AccessibilityUserState {
mIsPerformGesturesEnabled = enabled;
}
+ public boolean isAccessibilityFocusOnlyInActiveWindow() {
+ return mAccessibilityFocusOnlyInActiveWindow;
+ }
+
+ public void setAccessibilityFocusOnlyInActiveWindow(boolean enabled) {
+ mAccessibilityFocusOnlyInActiveWindow = enabled;
+ }
public ComponentName getServiceChangingSoftKeyboardModeLocked() {
return mServiceChangingSoftKeyboardMode;
}
diff --git a/services/accessibility/java/com/android/server/accessibility/gestures/EventDispatcher.java b/services/accessibility/java/com/android/server/accessibility/gestures/EventDispatcher.java
index 667364c9c901..c8cee1079e8e 100644
--- a/services/accessibility/java/com/android/server/accessibility/gestures/EventDispatcher.java
+++ b/services/accessibility/java/com/android/server/accessibility/gestures/EventDispatcher.java
@@ -21,8 +21,11 @@ import static com.android.server.accessibility.gestures.TouchState.ALL_POINTER_I
import static com.android.server.accessibility.gestures.TouchState.MAX_POINTER_COUNT;
import android.content.Context;
+import android.graphics.Point;
import android.util.Slog;
import android.view.MotionEvent;
+import android.view.MotionEvent.PointerCoords;
+import android.view.MotionEvent.PointerProperties;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
@@ -37,19 +40,27 @@ import com.android.server.policy.WindowManagerPolicy;
*/
class EventDispatcher {
private static final String LOG_TAG = "EventDispatcher";
+ private static final int CLICK_LOCATION_NONE = 0;
+ private static final int CLICK_LOCATION_ACCESSIBILITY_FOCUS = 1;
+ private static final int CLICK_LOCATION_LAST_TOUCH_EXPLORED = 2;
private final AccessibilityManagerService mAms;
private Context mContext;
// The receiver of motion events.
private EventStreamTransformation mReceiver;
- // Keep track of which pointers sent to the system are down.
- private int mInjectedPointersDown;
- // The time of the last injected down.
- private long mLastInjectedDownEventTime;
+ // The long pressing pointer id if coordinate remapping is needed for double tap and hold
+ private int mLongPressingPointerId = -1;
+
+ // The long pressing pointer X if coordinate remapping is needed for double tap and hold.
+ private int mLongPressingPointerDeltaX;
+
+ // The long pressing pointer Y if coordinate remapping is needed for double tap and hold.
+ private int mLongPressingPointerDeltaY;
+
+ // Temporary point to avoid instantiation.
+ private final Point mTempPoint = new Point();
- // The last injected hover event.
- private MotionEvent mLastInjectedHoverEvent;
private TouchState mState;
EventDispatcher(
@@ -98,8 +109,18 @@ class EventDispatcher {
if (action == MotionEvent.ACTION_DOWN) {
event.setDownTime(event.getEventTime());
} else {
- event.setDownTime(getLastInjectedDownEventTime());
+ event.setDownTime(mState.getLastInjectedDownEventTime());
+ }
+ // If the user is long pressing but the long pressing pointer
+ // was not exactly over the accessibility focused item we need
+ // to remap the location of that pointer so the user does not
+ // have to explicitly touch explore something to be able to
+ // long press it, or even worse to avoid the user long pressing
+ // on the wrong item since click and long press behave differently.
+ if (mLongPressingPointerId >= 0) {
+ event = offsetEvent(event, -mLongPressingPointerDeltaX, -mLongPressingPointerDeltaY);
}
+
if (DEBUG) {
Slog.d(
LOG_TAG,
@@ -116,7 +137,7 @@ class EventDispatcher {
} else {
Slog.e(LOG_TAG, "Error sending event: no receiver specified.");
}
- updateState(event);
+ mState.onInjectedMotionEvent(event);
if (event != prototype) {
event.recycle();
@@ -145,87 +166,15 @@ class EventDispatcher {
mState.onInjectedAccessibilityEvent(type);
}
- /**
- * Processes an injected {@link MotionEvent} event.
- *
- * @param event The event to process.
- */
- void updateState(MotionEvent event) {
- final int action = event.getActionMasked();
- final int pointerId = event.getPointerId(event.getActionIndex());
- final int pointerFlag = (1 << pointerId);
- switch (action) {
- case MotionEvent.ACTION_DOWN:
- case MotionEvent.ACTION_POINTER_DOWN:
- mInjectedPointersDown |= pointerFlag;
- mLastInjectedDownEventTime = event.getDownTime();
- break;
- case MotionEvent.ACTION_UP:
- case MotionEvent.ACTION_POINTER_UP:
- mInjectedPointersDown &= ~pointerFlag;
- if (mInjectedPointersDown == 0) {
- mLastInjectedDownEventTime = 0;
- }
- break;
- case MotionEvent.ACTION_HOVER_ENTER:
- case MotionEvent.ACTION_HOVER_MOVE:
- case MotionEvent.ACTION_HOVER_EXIT:
- if (mLastInjectedHoverEvent != null) {
- mLastInjectedHoverEvent.recycle();
- }
- mLastInjectedHoverEvent = MotionEvent.obtain(event);
- break;
- }
- if (DEBUG) {
- Slog.i(LOG_TAG, "Injected pointer:\n" + toString());
- }
- }
-
- /** Clears the internals state. */
- public void clear() {
- mInjectedPointersDown = 0;
- }
-
- /** @return The time of the last injected down event. */
- public long getLastInjectedDownEventTime() {
- return mLastInjectedDownEventTime;
- }
-
- /** @return The number of down pointers injected to the view hierarchy. */
- public int getInjectedPointerDownCount() {
- return Integer.bitCount(mInjectedPointersDown);
- }
-
- /** @return The bits of the injected pointers that are down. */
- public int getInjectedPointersDown() {
- return mInjectedPointersDown;
- }
-
- /**
- * Whether an injected pointer is down.
- *
- * @param pointerId The unique pointer id.
- * @return True if the pointer is down.
- */
- public boolean isInjectedPointerDown(int pointerId) {
- final int pointerFlag = (1 << pointerId);
- return (mInjectedPointersDown & pointerFlag) != 0;
- }
-
- /** @return The the last injected hover event. */
- public MotionEvent getLastInjectedHoverEvent() {
- return mLastInjectedHoverEvent;
- }
-
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("=========================");
builder.append("\nDown pointers #");
- builder.append(Integer.bitCount(mInjectedPointersDown));
+ builder.append(Integer.bitCount(mState.getInjectedPointersDown()));
builder.append(" [ ");
for (int i = 0; i < MAX_POINTER_COUNT; i++) {
- if ((mInjectedPointersDown & i) != 0) {
+ if (mState.isInjectedPointerDown(i)) {
builder.append(i);
builder.append(" ");
}
@@ -236,6 +185,48 @@ class EventDispatcher {
}
/**
+ * /** Offsets all pointers in the given event by adding the specified X and Y offsets.
+ *
+ * @param event The event to offset.
+ * @param offsetX The X offset.
+ * @param offsetY The Y offset.
+ * @return An event with the offset pointers or the original event if both offsets are zero.
+ */
+ private MotionEvent offsetEvent(MotionEvent event, int offsetX, int offsetY) {
+ if (offsetX == 0 && offsetY == 0) {
+ return event;
+ }
+ final int remappedIndex = event.findPointerIndex(mLongPressingPointerId);
+ final int pointerCount = event.getPointerCount();
+ PointerProperties[] props = PointerProperties.createArray(pointerCount);
+ PointerCoords[] coords = PointerCoords.createArray(pointerCount);
+ for (int i = 0; i < pointerCount; i++) {
+ event.getPointerProperties(i, props[i]);
+ event.getPointerCoords(i, coords[i]);
+ if (i == remappedIndex) {
+ coords[i].x += offsetX;
+ coords[i].y += offsetY;
+ }
+ }
+ return MotionEvent.obtain(
+ event.getDownTime(),
+ event.getEventTime(),
+ event.getAction(),
+ event.getPointerCount(),
+ props,
+ coords,
+ event.getMetaState(),
+ event.getButtonState(),
+ 1.0f,
+ 1.0f,
+ event.getDeviceId(),
+ event.getEdgeFlags(),
+ event.getSource(),
+ event.getDisplayId(),
+ event.getFlags());
+ }
+
+ /**
* Computes the action for an injected event based on a masked action and a pointer index.
*
* @param actionMasked The masked action.
@@ -247,7 +238,7 @@ class EventDispatcher {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
// Compute the action based on how many down pointers are injected.
- if (getInjectedPointerDownCount() == 0) {
+ if (mState.getInjectedPointerDownCount() == 0) {
return MotionEvent.ACTION_DOWN;
} else {
return (pointerIndex << MotionEvent.ACTION_POINTER_INDEX_SHIFT)
@@ -255,7 +246,7 @@ class EventDispatcher {
}
case MotionEvent.ACTION_POINTER_UP:
// Compute the action based on how many down pointers are injected.
- if (getInjectedPointerDownCount() == 1) {
+ if (mState.getInjectedPointerDownCount() == 1) {
return MotionEvent.ACTION_UP;
} else {
return (pointerIndex << MotionEvent.ACTION_POINTER_INDEX_SHIFT)
@@ -280,7 +271,7 @@ class EventDispatcher {
for (int i = 0; i < pointerCount; i++) {
final int pointerId = prototype.getPointerId(i);
// Do not send event for already delivered pointers.
- if (!isInjectedPointerDown(pointerId)) {
+ if (!mState.isInjectedPointerDown(pointerId)) {
pointerIdBits |= (1 << pointerId);
final int action = computeInjectionAction(MotionEvent.ACTION_DOWN, i);
sendMotionEvent(
@@ -306,7 +297,7 @@ class EventDispatcher {
for (int i = 0; i < pointerCount; i++) {
final int pointerId = prototype.getPointerId(i);
// Skip non injected down pointers.
- if (!isInjectedPointerDown(pointerId)) {
+ if (!mState.isInjectedPointerDown(pointerId)) {
continue;
}
final int action = computeInjectionAction(MotionEvent.ACTION_POINTER_UP, i);
@@ -315,4 +306,97 @@ class EventDispatcher {
pointerIdBits &= ~(1 << pointerId);
}
}
+
+ public boolean longPressWithTouchEvents(MotionEvent event, int policyFlags) {
+ final int pointerIndex = event.getActionIndex();
+ final int pointerId = event.getPointerId(pointerIndex);
+ Point clickLocation = mTempPoint;
+ final int result = computeClickLocation(clickLocation);
+ if (result == CLICK_LOCATION_NONE) {
+ return false;
+ }
+ mLongPressingPointerId = pointerId;
+ mLongPressingPointerDeltaX = (int) event.getX(pointerIndex) - clickLocation.x;
+ mLongPressingPointerDeltaY = (int) event.getY(pointerIndex) - clickLocation.y;
+ sendDownForAllNotInjectedPointers(event, policyFlags);
+ return true;
+ }
+
+ public void clickWithTouchEvents(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
+ final int pointerIndex = event.getActionIndex();
+ final int pointerId = event.getPointerId(pointerIndex);
+ Point clickLocation = mTempPoint;
+ final int result = computeClickLocation(clickLocation);
+ if (result == CLICK_LOCATION_NONE) {
+ Slog.e(LOG_TAG, "Unable to compute click location.");
+ // We can't send a click to no location, but the gesture was still
+ // consumed.
+ return;
+ }
+ // Do the click.
+ PointerProperties[] properties = new PointerProperties[1];
+ properties[0] = new PointerProperties();
+ event.getPointerProperties(pointerIndex, properties[0]);
+ PointerCoords[] coords = new PointerCoords[1];
+ coords[0] = new PointerCoords();
+ coords[0].x = clickLocation.x;
+ coords[0].y = clickLocation.y;
+ MotionEvent clickEvent =
+ MotionEvent.obtain(
+ event.getDownTime(),
+ event.getEventTime(),
+ MotionEvent.ACTION_DOWN,
+ 1,
+ properties,
+ coords,
+ 0,
+ 0,
+ 1.0f,
+ 1.0f,
+ event.getDeviceId(),
+ 0,
+ event.getSource(),
+ event.getDisplayId(),
+ event.getFlags());
+ final boolean targetAccessibilityFocus = (result == CLICK_LOCATION_ACCESSIBILITY_FOCUS);
+ sendActionDownAndUp(clickEvent, rawEvent, policyFlags, targetAccessibilityFocus);
+ clickEvent.recycle();
+ }
+
+ private int computeClickLocation(Point outLocation) {
+ if (mState.getLastInjectedHoverEventForClick() != null) {
+ final int lastExplorePointerIndex =
+ mState.getLastInjectedHoverEventForClick().getActionIndex();
+ outLocation.x =
+ (int) mState.getLastInjectedHoverEventForClick().getX(lastExplorePointerIndex);
+ outLocation.y =
+ (int) mState.getLastInjectedHoverEventForClick().getY(lastExplorePointerIndex);
+ if (!mAms.accessibilityFocusOnlyInActiveWindow()
+ || mState.getLastTouchedWindowId() == mAms.getActiveWindowId()) {
+ if (mAms.getAccessibilityFocusClickPointInScreen(outLocation)) {
+ return CLICK_LOCATION_ACCESSIBILITY_FOCUS;
+ } else {
+ return CLICK_LOCATION_LAST_TOUCH_EXPLORED;
+ }
+ }
+ }
+ if (mAms.getAccessibilityFocusClickPointInScreen(outLocation)) {
+ return CLICK_LOCATION_ACCESSIBILITY_FOCUS;
+ }
+ return CLICK_LOCATION_NONE;
+ }
+
+ private void sendActionDownAndUp(
+ MotionEvent prototype,
+ MotionEvent rawEvent,
+ int policyFlags,
+ boolean targetAccessibilityFocus) {
+ // Tap with the pointer that last explored.
+ final int pointerId = prototype.getPointerId(prototype.getActionIndex());
+ final int pointerIdBits = (1 << pointerId);
+ prototype.setTargetAccessibilityFocus(targetAccessibilityFocus);
+ sendMotionEvent(prototype, MotionEvent.ACTION_DOWN, rawEvent, pointerIdBits, policyFlags);
+ prototype.setTargetAccessibilityFocus(targetAccessibilityFocus);
+ sendMotionEvent(prototype, MotionEvent.ACTION_UP, rawEvent, pointerIdBits, policyFlags);
+ }
}
diff --git a/services/accessibility/java/com/android/server/accessibility/gestures/GestureManifold.java b/services/accessibility/java/com/android/server/accessibility/gestures/GestureManifold.java
index 6d0f069e51ac..e9c70c60a322 100644
--- a/services/accessibility/java/com/android/server/accessibility/gestures/GestureManifold.java
+++ b/services/accessibility/java/com/android/server/accessibility/gestures/GestureManifold.java
@@ -104,6 +104,7 @@ class GestureManifold implements GestureMatcher.StateChangeListener {
mHandler = new Handler(context.getMainLooper());
mListener = listener;
mState = state;
+ mMultiFingerGesturesEnabled = false;
// Set up gestures.
// Start with double tap.
mGestures.add(new MultiTap(context, 2, GESTURE_DOUBLE_TAP, this));
@@ -247,7 +248,7 @@ class GestureManifold implements GestureMatcher.StateChangeListener {
* and hold is dispatched via onGestureCompleted. Otherwise, this method is called when the
* user has performed a double tap and then held down the second tap.
*/
- void onDoubleTapAndHold();
+ void onDoubleTapAndHold(MotionEvent event, MotionEvent rawEvent, int policyFlags);
/**
* When FLAG_SERVICE_HANDLES_DOUBLE_TAP is enabled, this method is not called; double-tap is
@@ -256,7 +257,7 @@ class GestureManifold implements GestureMatcher.StateChangeListener {
*
* @return true if the event is consumed, else false
*/
- boolean onDoubleTap();
+ boolean onDoubleTap(MotionEvent event, MotionEvent rawEvent, int policyFlags);
/**
* Called when the system has decided the event stream is a potential gesture.
@@ -322,7 +323,7 @@ class GestureManifold implements GestureMatcher.StateChangeListener {
new AccessibilityGestureEvent(gestureId, event.getDisplayId());
mListener.onGestureCompleted(gestureEvent);
} else {
- mListener.onDoubleTap();
+ mListener.onDoubleTap(event, rawEvent, policyFlags);
}
clear();
break;
@@ -332,7 +333,7 @@ class GestureManifold implements GestureMatcher.StateChangeListener {
new AccessibilityGestureEvent(gestureId, event.getDisplayId());
mListener.onGestureCompleted(gestureEvent);
} else {
- mListener.onDoubleTapAndHold();
+ mListener.onDoubleTapAndHold(event, rawEvent, policyFlags);
}
clear();
break;
diff --git a/services/accessibility/java/com/android/server/accessibility/gestures/MultiFingerMultiTap.java b/services/accessibility/java/com/android/server/accessibility/gestures/MultiFingerMultiTap.java
index 642a841257bf..09e060570c93 100644
--- a/services/accessibility/java/com/android/server/accessibility/gestures/MultiFingerMultiTap.java
+++ b/services/accessibility/java/com/android/server/accessibility/gestures/MultiFingerMultiTap.java
@@ -67,8 +67,8 @@ class MultiFingerMultiTap extends GestureMatcher {
Preconditions.checkArgumentPositive(taps, "Tap count must greater than 0.");
mTargetTapCount = taps;
mTargetFingerCount = fingers;
- mDoubleTapSlop = ViewConfiguration.get(context).getScaledDoubleTapSlop();
- mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
+ mDoubleTapSlop = ViewConfiguration.get(context).getScaledDoubleTapSlop() * fingers;
+ mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop() * fingers;
mBases = new PointF[mTargetFingerCount];
for (int i = 0; i < mBases.length; i++) {
diff --git a/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java b/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java
index 4fee672a8803..373d47ed366b 100644
--- a/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java
+++ b/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java
@@ -22,7 +22,6 @@ import static com.android.server.accessibility.gestures.TouchState.ALL_POINTER_I
import android.accessibilityservice.AccessibilityGestureEvent;
import android.content.Context;
-import android.graphics.Point;
import android.graphics.Region;
import android.os.Handler;
import android.util.Slog;
@@ -86,6 +85,7 @@ public class TouchExplorer extends BaseEventStreamTransformation
// The ID of the pointer used for dragging.
private int mDraggingPointerId;
+
// Handler for performing asynchronous operations.
private final Handler mHandler;
@@ -115,8 +115,6 @@ public class TouchExplorer extends BaseEventStreamTransformation
// Handle to the accessibility manager service.
private final AccessibilityManagerService mAms;
- // Temporary point to avoid instantiation.
- private final Point mTempPoint = new Point();
// Context in which this explorer operates.
private final Context mContext;
@@ -277,6 +275,7 @@ public class TouchExplorer extends BaseEventStreamTransformation
if (eventType == AccessibilityEvent.TYPE_VIEW_HOVER_EXIT) {
sendsPendingA11yEventsIfNeed();
}
+ mState.onReceivedAccessibilityEvent(event);
super.onAccessibilityEvent(event);
}
@@ -309,16 +308,20 @@ public class TouchExplorer extends BaseEventStreamTransformation
}
@Override
- public void onDoubleTapAndHold() {
+ public void onDoubleTapAndHold(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
// Try to use the standard accessibility API to long click
if (!mAms.performActionOnAccessibilityFocusedItem(
AccessibilityNodeInfo.AccessibilityAction.ACTION_LONG_CLICK)) {
Slog.e(LOG_TAG, "ACTION_LONG_CLICK failed.");
+ if (mDispatcher.longPressWithTouchEvents(event, policyFlags)) {
+ sendHoverExitAndTouchExplorationGestureEndIfNeeded(policyFlags);
+ mState.startDelegating();
+ }
}
}
@Override
- public boolean onDoubleTap() {
+ public boolean onDoubleTap(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
mAms.onTouchInteractionEnd();
// Remove pending event deliveries.
mSendHoverEnterAndMoveDelayed.cancel();
@@ -334,7 +337,10 @@ public class TouchExplorer extends BaseEventStreamTransformation
// Try to use the standard accessibility API to click
if (!mAms.performActionOnAccessibilityFocusedItem(
AccessibilityNodeInfo.AccessibilityAction.ACTION_CLICK)) {
- Slog.e(LOG_TAG, "ACTION_CLICK failed.");
+ Slog.e(LOG_TAG, "ACTION_CLICK failed. Dispatching motion events to simulate click.");
+
+ mDispatcher.clickWithTouchEvents(event, rawEvent, policyFlags);
+ return true;
}
return true;
}
@@ -840,7 +846,7 @@ public class TouchExplorer extends BaseEventStreamTransformation
* @param policyFlags The policy flags associated with the event.
*/
private void sendHoverExitAndTouchExplorationGestureEndIfNeeded(int policyFlags) {
- MotionEvent event = mDispatcher.getLastInjectedHoverEvent();
+ MotionEvent event = mState.getLastInjectedHoverEvent();
if (event != null && event.getActionMasked() != MotionEvent.ACTION_HOVER_EXIT) {
final int pointerIdBits = event.getPointerIdBits();
if (!mSendTouchExplorationEndDelayed.isPending()) {
@@ -862,7 +868,7 @@ public class TouchExplorer extends BaseEventStreamTransformation
* @param policyFlags The policy flags associated with the event.
*/
private void sendTouchExplorationGestureStartAndHoverEnterIfNeeded(int policyFlags) {
- MotionEvent event = mDispatcher.getLastInjectedHoverEvent();
+ MotionEvent event = mState.getLastInjectedHoverEvent();
if (event != null && event.getActionMasked() == MotionEvent.ACTION_HOVER_EXIT) {
final int pointerIdBits = event.getPointerIdBits();
mDispatcher.sendMotionEvent(
@@ -1188,7 +1194,6 @@ public class TouchExplorer extends BaseEventStreamTransformation
+ ", mDetermineUserIntentTimeout: " + mDetermineUserIntentTimeout
+ ", mDoubleTapSlop: " + mDoubleTapSlop
+ ", mDraggingPointerId: " + mDraggingPointerId
- + ", mTempPoint: " + mTempPoint
+ " }";
}
}
diff --git a/services/accessibility/java/com/android/server/accessibility/gestures/TouchState.java b/services/accessibility/java/com/android/server/accessibility/gestures/TouchState.java
index d23dbbefd325..7a39bc29e8e5 100644
--- a/services/accessibility/java/com/android/server/accessibility/gestures/TouchState.java
+++ b/services/accessibility/java/com/android/server/accessibility/gestures/TouchState.java
@@ -75,6 +75,16 @@ public class TouchState {
private MotionEvent mLastReceivedEvent;
// The accompanying raw event without any transformations.
private MotionEvent mLastReceivedRawEvent;
+ // The id of the last touch explored window.
+ private int mLastTouchedWindowId;
+ // The last injected hover event.
+ private MotionEvent mLastInjectedHoverEvent;
+ // The last injected hover event used for performing clicks.
+ private MotionEvent mLastInjectedHoverEventForClick;
+ // The time of the last injected down.
+ private long mLastInjectedDownEventTime;
+ // Keep track of which pointers sent to the system are down.
+ private int mInjectedPointersDown;
public TouchState() {
mReceivedPointerTracker = new ReceivedPointerTracker();
@@ -88,7 +98,9 @@ public class TouchState {
mLastReceivedEvent.recycle();
mLastReceivedEvent = null;
}
+ mLastTouchedWindowId = -1;
mReceivedPointerTracker.clear();
+ mInjectedPointersDown = 0;
}
/**
@@ -107,6 +119,71 @@ public class TouchState {
mReceivedPointerTracker.onMotionEvent(rawEvent);
}
+ /**
+ * Processes an injected {@link MotionEvent} event.
+ *
+ * @param event The event to process.
+ */
+ void onInjectedMotionEvent(MotionEvent event) {
+ final int action = event.getActionMasked();
+ final int pointerId = event.getPointerId(event.getActionIndex());
+ final int pointerFlag = (1 << pointerId);
+ switch (action) {
+ case MotionEvent.ACTION_DOWN:
+ case MotionEvent.ACTION_POINTER_DOWN:
+ mInjectedPointersDown |= pointerFlag;
+ mLastInjectedDownEventTime = event.getDownTime();
+ break;
+ case MotionEvent.ACTION_UP:
+ case MotionEvent.ACTION_POINTER_UP:
+ mInjectedPointersDown &= ~pointerFlag;
+ if (mInjectedPointersDown == 0) {
+ mLastInjectedDownEventTime = 0;
+ }
+ break;
+ case MotionEvent.ACTION_HOVER_ENTER:
+ case MotionEvent.ACTION_HOVER_MOVE:
+ if (mLastInjectedHoverEvent != null) {
+ mLastInjectedHoverEvent.recycle();
+ }
+ mLastInjectedHoverEvent = MotionEvent.obtain(event);
+ break;
+ case MotionEvent.ACTION_HOVER_EXIT:
+ if (mLastInjectedHoverEvent != null) {
+ mLastInjectedHoverEvent.recycle();
+ }
+ mLastInjectedHoverEvent = MotionEvent.obtain(event);
+ if (mLastInjectedHoverEventForClick != null) {
+ mLastInjectedHoverEventForClick.recycle();
+ }
+ mLastInjectedHoverEventForClick = MotionEvent.obtain(event);
+ break;
+ }
+ if (DEBUG) {
+ Slog.i(LOG_TAG, "Injected pointer:\n" + toString());
+ }
+ }
+
+ /** Updates state in response to an accessibility event received from the outside. */
+ public void onReceivedAccessibilityEvent(AccessibilityEvent event) {
+ // If a new window opens or the accessibility focus moves we no longer
+ // want to click/long press on the last touch explored location.
+ switch (event.getEventType()) {
+ case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:
+ case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED:
+ if (mLastInjectedHoverEventForClick != null) {
+ mLastInjectedHoverEventForClick.recycle();
+ mLastInjectedHoverEventForClick = null;
+ }
+ mLastTouchedWindowId = -1;
+ break;
+ case AccessibilityEvent.TYPE_VIEW_HOVER_ENTER:
+ case AccessibilityEvent.TYPE_VIEW_HOVER_EXIT:
+ mLastTouchedWindowId = event.getWindowId();
+ break;
+ }
+ }
+
public void onInjectedAccessibilityEvent(int type) {
// The below state transitions go here because the related events are often sent on a
// delay.
@@ -236,6 +313,46 @@ public class TouchState {
return mLastReceivedEvent;
}
+ /** @return The the last injected hover event. */
+ public MotionEvent getLastInjectedHoverEvent() {
+ return mLastInjectedHoverEvent;
+ }
+
+ /** @return The time of the last injected down event. */
+ public long getLastInjectedDownEventTime() {
+ return mLastInjectedDownEventTime;
+ }
+
+ public int getLastTouchedWindowId() {
+ return mLastTouchedWindowId;
+ }
+
+ /** @return The number of down pointers injected to the view hierarchy. */
+ public int getInjectedPointerDownCount() {
+ return Integer.bitCount(mInjectedPointersDown);
+ }
+
+ /** @return The bits of the injected pointers that are down. */
+ public int getInjectedPointersDown() {
+ return mInjectedPointersDown;
+ }
+
+ /**
+ * Whether an injected pointer is down.
+ *
+ * @param pointerId The unique pointer id.
+ * @return True if the pointer is down.
+ */
+ public boolean isInjectedPointerDown(int pointerId) {
+ final int pointerFlag = (1 << pointerId);
+ return (mInjectedPointersDown & pointerFlag) != 0;
+ }
+
+ /** @return The the last injected hover event used for a click. */
+ public MotionEvent getLastInjectedHoverEventForClick() {
+ return mLastInjectedHoverEventForClick;
+ }
+
/** This class tracks where and when a pointer went down. It does not track its movement. */
class ReceivedPointerTracker {
private static final String LOG_TAG_RECEIVED_POINTER_TRACKER = "ReceivedPointerTracker";
diff --git a/services/autofill/java/com/android/server/autofill/AutofillInlineSessionController.java b/services/autofill/java/com/android/server/autofill/AutofillInlineSessionController.java
index 0ec8654f2a20..19248ca54611 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillInlineSessionController.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillInlineSessionController.java
@@ -45,6 +45,8 @@ final class AutofillInlineSessionController {
private final Object mLock;
@NonNull
private final Handler mHandler;
+ @NonNull
+ private final InlineFillUi.InlineUiEventCallback mUiCallback;
@Nullable
@GuardedBy("mLock")
@@ -54,12 +56,14 @@ final class AutofillInlineSessionController {
private InlineFillUi mInlineFillUi;
AutofillInlineSessionController(InputMethodManagerInternal inputMethodManagerInternal,
- int userId, ComponentName componentName, Handler handler, Object lock) {
+ int userId, ComponentName componentName, Handler handler, Object lock,
+ InlineFillUi.InlineUiEventCallback callback) {
mInputMethodManagerInternal = inputMethodManagerInternal;
mUserId = userId;
mComponentName = componentName;
mHandler = handler;
mLock = lock;
+ mUiCallback = callback;
}
@@ -77,16 +81,33 @@ final class AutofillInlineSessionController {
if (mSession != null) {
// Destroy the existing session.
mSession.destroySessionLocked();
- mInlineFillUi = null;
}
+ mInlineFillUi = null;
// TODO(b/151123764): consider reusing the same AutofillInlineSession object for the
// same field.
mSession = new AutofillInlineSuggestionsRequestSession(mInputMethodManagerInternal, mUserId,
- mComponentName, mHandler, mLock, autofillId, requestConsumer, uiExtras);
+ mComponentName, mHandler, mLock, autofillId, requestConsumer, uiExtras,
+ mUiCallback);
mSession.onCreateInlineSuggestionsRequestLocked();
}
/**
+ * Destroys the current session. May send an empty response to IME to clear the suggestions if
+ * the focus didn't change to a different field.
+ *
+ * @param autofillId the currently focused view from the autofill session
+ */
+ @GuardedBy("mLock")
+ void destroyLocked(@NonNull AutofillId autofillId) {
+ if (mSession != null) {
+ mSession.onInlineSuggestionsResponseLocked(InlineFillUi.emptyUi(autofillId));
+ mSession.destroySessionLocked();
+ mSession = null;
+ }
+ mInlineFillUi = null;
+ }
+
+ /**
* Returns the {@link InlineSuggestionsRequest} provided by IME for the last request.
*
* <p> The caller is responsible for making sure Autofill hears back from IME before calling
diff --git a/services/autofill/java/com/android/server/autofill/AutofillInlineSuggestionsRequestSession.java b/services/autofill/java/com/android/server/autofill/AutofillInlineSuggestionsRequestSession.java
index 48895ad42e99..68eeb0a3ca2e 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillInlineSuggestionsRequestSession.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillInlineSuggestionsRequestSession.java
@@ -29,6 +29,7 @@ import android.os.Handler;
import android.os.RemoteException;
import android.util.Slog;
import android.view.autofill.AutofillId;
+import android.view.inputmethod.InlineSuggestion;
import android.view.inputmethod.InlineSuggestionsRequest;
import android.view.inputmethod.InlineSuggestionsResponse;
@@ -40,6 +41,7 @@ import com.android.server.autofill.ui.InlineFillUi;
import com.android.server.inputmethod.InputMethodManagerInternal;
import java.lang.ref.WeakReference;
+import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;
@@ -65,6 +67,8 @@ final class AutofillInlineSuggestionsRequestSession {
private final Handler mHandler;
@NonNull
private final Bundle mUiExtras;
+ @NonNull
+ private final InlineFillUi.InlineUiEventCallback mUiCallback;
@GuardedBy("mLock")
@NonNull
@@ -97,18 +101,22 @@ final class AutofillInlineSuggestionsRequestSession {
@GuardedBy("mLock")
private boolean mDestroyed = false;
+ @GuardedBy("mLock")
+ private boolean mPreviousHasNonPinSuggestionShow;
AutofillInlineSuggestionsRequestSession(
@NonNull InputMethodManagerInternal inputMethodManagerInternal, int userId,
@NonNull ComponentName componentName, @NonNull Handler handler, @NonNull Object lock,
@NonNull AutofillId autofillId,
- @NonNull Consumer<InlineSuggestionsRequest> requestConsumer, @NonNull Bundle uiExtras) {
+ @NonNull Consumer<InlineSuggestionsRequest> requestConsumer, @NonNull Bundle uiExtras,
+ @NonNull InlineFillUi.InlineUiEventCallback callback) {
mInputMethodManagerInternal = inputMethodManagerInternal;
mUserId = userId;
mComponentName = componentName;
mHandler = handler;
mLock = lock;
mUiExtras = uiExtras;
+ mUiCallback = callback;
mAutofillId = autofillId;
mImeRequestConsumer = requestConsumer;
@@ -217,6 +225,7 @@ final class AutofillInlineSuggestionsRequestSession {
// No-op if both the previous response and current response are empty.
return;
}
+ maybeNotifyFillUiEventLocked(response.getInlineSuggestions());
updateResponseToImeUncheckLocked(response);
mPreviousResponseIsNotEmpty = !isEmptyResponse;
}
@@ -238,6 +247,38 @@ final class AutofillInlineSuggestionsRequestSession {
}
}
+ @GuardedBy("mLock")
+ private void maybeNotifyFillUiEventLocked(@NonNull List<InlineSuggestion> suggestions) {
+ if (mDestroyed) {
+ return;
+ }
+ boolean hasSuggestionToShow = false;
+ for (int i = 0; i < suggestions.size(); i++) {
+ InlineSuggestion suggestion = suggestions.get(i);
+ // It is possible we don't have any match result but we still have pinned
+ // suggestions. Only notify we have non-pinned suggestions to show
+ if (!suggestion.getInfo().isPinned()) {
+ hasSuggestionToShow = true;
+ break;
+ }
+ }
+ if (sDebug) {
+ Slog.d(TAG, "maybeNotifyFillUiEventLoked(): hasSuggestionToShow=" + hasSuggestionToShow
+ + ", mPreviousHasNonPinSuggestionShow=" + mPreviousHasNonPinSuggestionShow);
+ }
+ // Use mPreviousHasNonPinSuggestionShow to save previous status, if the display status
+ // change, we can notify the event.
+ if (hasSuggestionToShow && !mPreviousHasNonPinSuggestionShow) {
+ // From no suggestion to has suggestions to show
+ mUiCallback.notifyInlineUiShown(mAutofillId);
+ } else if (!hasSuggestionToShow && mPreviousHasNonPinSuggestionShow) {
+ // From has suggestions to no suggestions to show
+ mUiCallback.notifyInlineUiHidden(mAutofillId);
+ }
+ // Update the latest status
+ mPreviousHasNonPinSuggestionShow = hasSuggestionToShow;
+ }
+
/**
* Handles the {@code request} and {@code callback} received from the IME.
*
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index 96b593d9682f..57ffe0498a88 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -815,6 +815,19 @@ final class AutofillManagerServiceImpl
}
}
+ void logAugmentedAutofillAuthenticationSelected(int sessionId, @Nullable String selectedDataset,
+ @Nullable Bundle clientState) {
+ synchronized (mLock) {
+ if (mAugmentedAutofillEventHistory == null
+ || mAugmentedAutofillEventHistory.getSessionId() != sessionId) {
+ return;
+ }
+ mAugmentedAutofillEventHistory.addEvent(
+ new Event(Event.TYPE_DATASET_AUTHENTICATION_SELECTED, selectedDataset,
+ clientState, null, null, null, null, null, null, null, null));
+ }
+ }
+
void logAugmentedAutofillSelected(int sessionId, @Nullable String suggestionId,
@Nullable Bundle clientState) {
synchronized (mLock) {
@@ -1199,6 +1212,14 @@ final class AutofillManagerServiceImpl
}
@Override
+ public void logAugmentedAutofillAuthenticationSelected(int sessionId,
+ String suggestionId, Bundle clientState) {
+ AutofillManagerServiceImpl.this
+ .logAugmentedAutofillAuthenticationSelected(
+ sessionId, suggestionId, clientState);
+ }
+
+ @Override
public void onServiceDied(@NonNull RemoteAugmentedAutofillService service) {
Slog.w(TAG, "remote augmented autofill service died");
final RemoteAugmentedAutofillService remoteService =
diff --git a/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java b/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java
index a7d0061cc043..11f901538868 100644
--- a/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java
+++ b/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java
@@ -167,14 +167,16 @@ final class RemoteAugmentedAutofillService
new IFillCallback.Stub() {
@Override
public void onSuccess(@Nullable List<Dataset> inlineSuggestionsData,
- @Nullable Bundle clientState) {
+ @Nullable Bundle clientState, boolean showingFillWindow) {
mCallbacks.resetLastResponse();
maybeRequestShowInlineSuggestions(sessionId,
inlineSuggestionsRequest, inlineSuggestionsData,
clientState, focusedId, focusedValue,
inlineSuggestionsCallback,
client, onErrorCallback, remoteRenderService);
- requestAutofill.complete(null);
+ if (!showingFillWindow) {
+ requestAutofill.complete(null);
+ }
}
@Override
@@ -263,7 +265,28 @@ final class RemoteAugmentedAutofillService
request, inlineSuggestionsData, focusedId, filterText,
new InlineFillUi.InlineSuggestionUiCallback() {
@Override
- public void autofill(Dataset dataset) {
+ public void autofill(Dataset dataset, int datasetIndex) {
+ if (dataset.getAuthentication() != null) {
+ mCallbacks.logAugmentedAutofillAuthenticationSelected(sessionId,
+ dataset.getId(), clientState);
+ final IntentSender action = dataset.getAuthentication();
+ final int authenticationId =
+ AutofillManager.makeAuthenticationId(
+ Session.AUGMENTED_AUTOFILL_REQUEST_ID,
+ datasetIndex);
+ final Intent fillInIntent = new Intent();
+ fillInIntent.putExtra(AutofillManager.EXTRA_CLIENT_STATE,
+ clientState);
+ try {
+ client.authenticate(sessionId, authenticationId, action,
+ fillInIntent, false);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Error starting auth flow");
+ inlineSuggestionsCallback.apply(
+ InlineFillUi.emptyUi(focusedId));
+ }
+ return;
+ }
mCallbacks.logAugmentedAutofillSelected(sessionId,
dataset.getId(), clientState);
try {
@@ -319,5 +342,8 @@ final class RemoteAugmentedAutofillService
void logAugmentedAutofillSelected(int sessionId, @Nullable String suggestionId,
@Nullable Bundle clientState);
+
+ void logAugmentedAutofillAuthenticationSelected(int sessionId,
+ @Nullable String suggestionId, @Nullable Bundle clientState);
}
}
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index a9a0ab69f633..2b9ce2f07c70 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -144,7 +144,9 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
private final MetricsLogger mMetricsLogger = new MetricsLogger();
- private static AtomicInteger sIdCounter = new AtomicInteger();
+ static final int AUGMENTED_AUTOFILL_REQUEST_ID = 1;
+
+ private static AtomicInteger sIdCounter = new AtomicInteger(2);
/**
* ID of the session.
@@ -313,18 +315,28 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
private final AssistDataReceiverImpl mAssistReceiver = new AssistDataReceiverImpl();
void onSwitchInputMethodLocked() {
+ // One caveat is that for the case where the focus is on a field for which regular autofill
+ // returns null, and augmented autofill is triggered, and then the user switches the input
+ // method. Tapping on the field again will not trigger a new augmented autofill request.
+ // This may be fixed by adding more checks such as whether mCurrentViewId is null.
if (mExpiredResponse) {
return;
}
-
- if (shouldExpireResponseOnInputMethodSwitch()) {
+ if (shouldResetSessionStateOnInputMethodSwitch()) {
// Set the old response expired, so the next action (ACTION_VIEW_ENTERED) can trigger
// a new fill request.
mExpiredResponse = true;
+ // Clear the augmented autofillable ids so augmented autofill will trigger again.
+ mAugmentedAutofillableIds = null;
+ // In case the field is augmented autofill only, we clear the current view id, so that
+ // we won't skip view entered due to same view entered, for the augmented autofill.
+ if (mForAugmentedAutofillOnly) {
+ mCurrentViewId = null;
+ }
}
}
- private boolean shouldExpireResponseOnInputMethodSwitch() {
+ private boolean shouldResetSessionStateOnInputMethodSwitch() {
// One of below cases will need a new fill request to update the inline spec for the new
// input method.
// 1. The autofill provider supports inline suggestion and the render service is available.
@@ -726,7 +738,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
viewState.setState(newState);
int requestId;
-
+ // TODO(b/158623971): Update this to prevent possible overflow
do {
requestId = sIdCounter.getAndIncrement();
} while (requestId == INVALID_REQUEST_ID);
@@ -831,7 +843,18 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
setClientLocked(client);
mInlineSessionController = new AutofillInlineSessionController(inputMethodManagerInternal,
- userId, componentName, handler, mLock);
+ userId, componentName, handler, mLock,
+ new InlineFillUi.InlineUiEventCallback() {
+ @Override
+ public void notifyInlineUiShown(AutofillId autofillId) {
+ notifyFillUiShown(autofillId);
+ }
+
+ @Override
+ public void notifyInlineUiHidden(AutofillId autofillId) {
+ notifyFillUiHidden(autofillId);
+ }
+ });
mMetricsLogger.write(newLogMaker(MetricsEvent.AUTOFILL_SESSION_STARTED)
.addTaggedData(MetricsEvent.FIELD_AUTOFILL_FLAGS, flags));
@@ -982,6 +1005,10 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|| disableDuration > 0) {
// Response is "empty" from an UI point of view, need to notify client.
notifyUnavailableToClient(sessionFinishedState, /* autofillableIds= */ null);
+ synchronized (mLock) {
+ mInlineSessionController.setInlineFillUiLocked(
+ InlineFillUi.emptyUi(mCurrentViewId));
+ }
}
if (requestLog != null) {
@@ -1317,6 +1344,26 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
this, intentSender, intent));
}
+ private void notifyFillUiHidden(@NonNull AutofillId autofillId) {
+ synchronized (mLock) {
+ try {
+ mClient.notifyFillUiHidden(this.id, autofillId);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Error sending fill UI hidden notification", e);
+ }
+ }
+ }
+
+ private void notifyFillUiShown(@NonNull AutofillId autofillId) {
+ synchronized (mLock) {
+ try {
+ mClient.notifyFillUiShown(this.id, autofillId);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Error sending fill UI shown notification", e);
+ }
+ }
+ }
+
private void doStartIntentSender(IntentSender intentSender, Intent intent) {
try {
synchronized (mLock) {
@@ -1334,6 +1381,11 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
+ id + " destroyed");
return;
}
+ final int requestId = AutofillManager.getRequestIdFromAuthenticationId(authenticationId);
+ if (requestId == AUGMENTED_AUTOFILL_REQUEST_ID) {
+ setAuthenticationResultForAugmentedAutofillLocked(data, authenticationId);
+ return;
+ }
if (mResponses == null) {
// Typically happens when app explicitly called cancel() while the service was showing
// the auth UI.
@@ -1341,7 +1393,6 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
removeSelf();
return;
}
- final int requestId = AutofillManager.getRequestIdFromAuthenticationId(authenticationId);
final FillResponse authenticatedResponse = mResponses.get(requestId);
if (authenticatedResponse == null || data == null) {
Slog.w(TAG, "no authenticated response");
@@ -1401,6 +1452,58 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
}
@GuardedBy("mLock")
+ void setAuthenticationResultForAugmentedAutofillLocked(Bundle data, int authId) {
+ final Dataset dataset = (data == null) ? null :
+ data.getParcelable(AutofillManager.EXTRA_AUTHENTICATION_RESULT);
+ if (sDebug) {
+ Slog.d(TAG, "Auth result for augmented autofill: sessionId=" + id
+ + ", authId=" + authId + ", dataset=" + dataset);
+ }
+ if (dataset == null
+ || dataset.getFieldIds().size() != 1
+ || dataset.getFieldIds().get(0) == null
+ || dataset.getFieldValues().size() != 1
+ || dataset.getFieldValues().get(0) == null) {
+ if (sDebug) {
+ Slog.d(TAG, "Rejecting empty/invalid auth result");
+ }
+ mService.resetLastAugmentedAutofillResponse();
+ removeSelfLocked();
+ return;
+ }
+ final List<AutofillId> fieldIds = dataset.getFieldIds();
+ final List<AutofillValue> autofillValues = dataset.getFieldValues();
+ final AutofillId fieldId = fieldIds.get(0);
+ final AutofillValue value = autofillValues.get(0);
+
+ // Update state to ensure that after filling the field here we don't end up firing another
+ // autofill request that will end up showing the same suggestions to the user again. When
+ // the auth activity came up, the field for which the suggestions were shown lost focus and
+ // mCurrentViewId was cleared. We need to set mCurrentViewId back to the id of the field
+ // that we are filling.
+ fieldId.setSessionId(id);
+ mCurrentViewId = fieldId;
+
+ // Notify the Augmented Autofill provider of the dataset that was selected.
+ final Bundle clientState = data.getBundle(AutofillManager.EXTRA_CLIENT_STATE);
+ mService.logAugmentedAutofillSelected(id, dataset.getId(), clientState);
+
+ // Fill the value into the field.
+ if (sDebug) {
+ Slog.d(TAG, "Filling after auth: fieldId=" + fieldId + ", value=" + value);
+ }
+ try {
+ mClient.autofill(id, fieldIds, autofillValues, true);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Error filling after auth: fieldId=" + fieldId + ", value=" + value
+ + ", error=" + e);
+ }
+
+ // Clear the suggestions since the user already accepted one of them.
+ mInlineSessionController.setInlineFillUiLocked(InlineFillUi.emptyUi(fieldId));
+ }
+
+ @GuardedBy("mLock")
void setHasCallbackLocked(boolean hasIt) {
if (mDestroyed) {
Slog.w(TAG, "Call to Session#setHasCallbackLocked() rejected - session: "
@@ -2496,6 +2599,10 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
+ actionAsString(action) + ", flags=" + flags);
}
ViewState viewState = mViewStates.get(id);
+ if (sVerbose) {
+ Slog.v(TAG, "updateLocked(" + this.id + "): mCurrentViewId=" + mCurrentViewId
+ + ", mExpiredResponse=" + mExpiredResponse + ", viewState=" + viewState);
+ }
if (viewState == null) {
if (action == ACTION_START_SESSION || action == ACTION_VALUE_CHANGED
@@ -2588,15 +2695,14 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
id)) {
// Regular autofill handled the view and returned null response, but it
// triggered augmented autofill
- if (!isSameViewEntered || mExpiredResponse) {
+ if (!isSameViewEntered) {
if (sDebug) Slog.d(TAG, "trigger augmented autofill.");
triggerAugmentedAutofillLocked(flags);
} else {
if (sDebug) Slog.d(TAG, "skip augmented autofill for same view.");
}
return;
- } else if (mForAugmentedAutofillOnly && isSameViewEntered
- && !mExpiredResponse) {
+ } else if (mForAugmentedAutofillOnly && isSameViewEntered) {
// Regular autofill is disabled.
if (sDebug) Slog.d(TAG, "skip augmented autofill for same view.");
return;
@@ -2698,11 +2804,6 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
// TODO(b/156099633): remove this once framework gets out of business of resending
// inline suggestions when IME visibility changes.
mInlineSessionController.hideInlineSuggestionsUiLocked(viewState.id);
- try {
- mClient.notifyFillUiHidden(this.id, viewState.id);
- } catch (RemoteException e) {
- Slog.e(TAG, "Error requesting to hide fill UI", e);
- }
viewState.resetState(ViewState.STATE_CHANGED);
return;
} else if ((viewState.id.equals(this.mCurrentViewId))
@@ -2729,11 +2830,6 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
// TODO: we should be able to replace this with controller#filterInlineFillUiLocked
// to accomplish filtering for augmented autofill.
mInlineSessionController.hideInlineSuggestionsUiLocked(mCurrentViewId);
- try {
- mClient.notifyFillUiHidden(this.id, mCurrentViewId);
- } catch (RemoteException e) {
- Slog.e(TAG, "Error sending fill UI hidden notification", e);
- }
}
}
@@ -2819,11 +2915,6 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
if (requestShowInlineSuggestionsLocked(response, filterText)) {
final ViewState currentView = mViewStates.get(mCurrentViewId);
currentView.setState(ViewState.STATE_INLINE_SHOWN);
- try {
- mClient.notifyFillUiShown(this.id, mCurrentViewId);
- } catch (RemoteException e) {
- Slog.e(TAG, "Error sending fill UI shown notification", e);
- }
//TODO(b/137800469): Fix it to log showed only when IME asks for inflation,
// rather than here where framework sends back the response.
mService.logDatasetShown(id, mClientState);
@@ -2892,13 +2983,8 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
inlineSuggestionsRequest.get(), response, focusedId, filterText,
/*uiCallback*/this, /*onErrorCallback*/ () -> {
synchronized (mLock) {
- mInlineSessionController.hideInlineSuggestionsUiLocked(
- focusedId);
- try {
- mClient.notifyFillUiHidden(this.id, focusedId);
- } catch (RemoteException e) {
- Slog.e(TAG, "Error sending fill UI hidden notification", e);
- }
+ mInlineSessionController.setInlineFillUiLocked(
+ InlineFillUi.emptyUi(focusedId));
}
}, remoteRenderService);
return mInlineSessionController.setInlineFillUiLocked(inlineFillUi);
@@ -3084,12 +3170,15 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
notifyUnavailableToClient(AutofillManager.STATE_FINISHED, autofillableIds);
removeSelf();
} else {
- if (sVerbose) {
- if ((flags & FLAG_PASSWORD_INPUT_TYPE) != 0) {
+ if ((flags & FLAG_PASSWORD_INPUT_TYPE) != 0) {
+ if (sVerbose) {
Slog.v(TAG, "keeping session " + id + " when service returned null and "
+ "augmented service is disabled for password fields. "
+ "AutofillableIds: " + autofillableIds);
- } else {
+ }
+ mInlineSessionController.hideInlineSuggestionsUiLocked(mCurrentViewId);
+ } else {
+ if (sVerbose) {
Slog.v(TAG, "keeping session " + id + " when service returned null but "
+ "it can be augmented. AutofillableIds: " + autofillableIds);
}
@@ -3115,7 +3204,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
// non-null response but without datasets (for example, just SaveInfo)
@GuardedBy("mLock")
private Runnable triggerAugmentedAutofillLocked(int flags) {
- // (TODO: b/141703197) Fix later by passing info to service.
+ // TODO: (b/141703197) Fix later by passing info to service.
if ((flags & FLAG_PASSWORD_INPUT_TYPE) != 0) {
return null;
}
@@ -3160,7 +3249,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
+ ComponentName.flattenToShortString(mComponentName) + " not whitelisted ");
}
logAugmentedAutofillRequestLocked(mode, remoteService.getComponentName(),
- mCurrentViewId, isWhitelisted, /*isInline*/null);
+ mCurrentViewId, isWhitelisted, /* isInline= */ null);
return null;
}
@@ -3202,22 +3291,29 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
/*onErrorCallback=*/ () -> {
synchronized (mLock) {
cancelAugmentedAutofillLocked();
+
+ // Also cancel augmented in IME
+ mInlineSessionController.setInlineFillUiLocked(
+ InlineFillUi.emptyUi(mCurrentViewId));
}
}, mService.getRemoteInlineSuggestionRenderServiceLocked());
}
};
// When the inline suggestion render service is available and the view is focused, there
- // are 2 cases when augmented autofill should ask IME for inline suggestion request,
+ // are 3 cases when augmented autofill should ask IME for inline suggestion request,
// because standard autofill flow didn't:
// 1. the field is augmented autofill only (when standard autofill provider is None or
// when it returns null response)
// 2. standard autofill provider doesn't support inline suggestion
+ // 3. we re-entered the autofill session and standard autofill was not re-triggered, this is
+ // recognized by seeing mExpiredResponse == true
final RemoteInlineSuggestionRenderService remoteRenderService =
mService.getRemoteInlineSuggestionRenderServiceLocked();
if (remoteRenderService != null
&& (mForAugmentedAutofillOnly
- || !isInlineSuggestionsEnabledByAutofillProviderLocked())
+ || !isInlineSuggestionsEnabledByAutofillProviderLocked()
+ || mExpiredResponse)
&& isViewFocusedLocked(flags)) {
if (sDebug) Slog.d(TAG, "Create inline request for augmented autofill");
remoteRenderService.getInlineSuggestionsRendererInfo(new RemoteCallback(
@@ -3410,11 +3506,6 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
}
if (mCurrentViewId != null) {
mInlineSessionController.hideInlineSuggestionsUiLocked(mCurrentViewId);
- try {
- mClient.notifyFillUiHidden(this.id, mCurrentViewId);
- } catch (RemoteException e) {
- Slog.e(TAG, "Error sending fill UI hidden notification", e);
- }
}
autoFillApp(dataset);
return;
@@ -3702,6 +3793,9 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
unlinkClientVultureLocked();
mUi.destroyAll(mPendingSaveUi, this, true);
mUi.clearCallback(this);
+ if (mCurrentViewId != null) {
+ mInlineSessionController.destroyLocked(mCurrentViewId);
+ }
mDestroyed = true;
// Log metrics
diff --git a/services/autofill/java/com/android/server/autofill/ui/InlineFillUi.java b/services/autofill/java/com/android/server/autofill/ui/InlineFillUi.java
index a3d0fb955da4..627c0733b078 100644
--- a/services/autofill/java/com/android/server/autofill/ui/InlineFillUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/InlineFillUi.java
@@ -290,11 +290,26 @@ public final class InlineFillUi {
/**
* Callback to autofill a dataset to the client app.
*/
- void autofill(@NonNull Dataset dataset);
+ void autofill(@NonNull Dataset dataset, int datasetIndex);
/**
* Callback to start Intent in client app.
*/
void startIntentSender(@NonNull IntentSender intentSender, @NonNull Intent intent);
}
+
+ /**
+ * Callback for inline suggestion Ui related events.
+ */
+ public interface InlineUiEventCallback {
+ /**
+ * Callback to notify inline ui is shown.
+ */
+ void notifyInlineUiShown(@NonNull AutofillId autofillId);
+
+ /**
+ * Callback to notify inline ui is hidden.
+ */
+ void notifyInlineUiHidden(@NonNull AutofillId autofillId);
+ }
}
diff --git a/services/autofill/java/com/android/server/autofill/ui/InlineSuggestionFactory.java b/services/autofill/java/com/android/server/autofill/ui/InlineSuggestionFactory.java
index c8485b7c2b38..462ffd668e2e 100644
--- a/services/autofill/java/com/android/server/autofill/ui/InlineSuggestionFactory.java
+++ b/services/autofill/java/com/android/server/autofill/ui/InlineSuggestionFactory.java
@@ -109,7 +109,7 @@ final class InlineSuggestionFactory {
return createInlineSuggestionsInternal(/* isAugmented= */ true, request,
datasets, autofillId, onErrorCallback,
(dataset, datasetIndex) ->
- inlineSuggestionUiCallback.autofill(dataset),
+ inlineSuggestionUiCallback.autofill(dataset, datasetIndex),
(intentSender) ->
inlineSuggestionUiCallback.startIntentSender(intentSender, new Intent()),
remoteRenderService);
diff --git a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
index 507e98369855..1c3116699b2d 100644
--- a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
@@ -33,6 +33,7 @@ import android.graphics.drawable.Drawable;
import android.metrics.LogMaker;
import android.os.Handler;
import android.os.IBinder;
+import android.os.UserHandle;
import android.service.autofill.BatchUpdates;
import android.service.autofill.CustomDescription;
import android.service.autofill.InternalOnClickAction;
@@ -196,7 +197,9 @@ final class SaveUi {
}
intent.putExtra(AutofillManager.EXTRA_RESTORE_CROSS_ACTIVITY, true);
- PendingIntent p = PendingIntent.getActivity(this, 0, intent, 0);
+ PendingIntent p = PendingIntent.getActivityAsUser(
+ this, /* requestCode= */ 0, intent, /* flags= */ 0, /* options= */ null,
+ UserHandle.CURRENT);
if (sDebug) {
Slog.d(TAG, "startActivity add save UI restored with intent=" + intent);
}
diff --git a/services/backup/java/com/android/server/backup/UserBackupManagerService.java b/services/backup/java/com/android/server/backup/UserBackupManagerService.java
index dc35c774f71e..f6c4918a7dfe 100644
--- a/services/backup/java/com/android/server/backup/UserBackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/UserBackupManagerService.java
@@ -318,7 +318,7 @@ public class UserBackupManagerService {
private static final String SERIAL_ID_FILE = "serial_id";
- private static final String SKIP_USER_FACING_DATA = "backup_skip_user_facing_data";
+ private static final String SKIP_USER_FACING_PACKAGES = "backup_skip_user_facing_packages";
private static final String WALLPAPER_PACKAGE = "com.android.wallpaperbackup";
private final @UserIdInt int mUserId;
@@ -3557,7 +3557,7 @@ public class UserBackupManagerService {
}
/**
- * We want to skip backup/restore of certain packages if 'backup_skip_user_facing_data' is
+ * We want to skip backup/restore of certain packages if 'backup_skip_user_facing_packages' is
* set to true in secure settings. See b/153940088 for details.
*
* TODO(b/154822946): Remove this logic in the next release.
@@ -3581,7 +3581,7 @@ public class UserBackupManagerService {
@VisibleForTesting
public boolean shouldSkipUserFacingData() {
- return Settings.Secure.getInt(mContext.getContentResolver(), SKIP_USER_FACING_DATA,
+ return Settings.Secure.getInt(mContext.getContentResolver(), SKIP_USER_FACING_PACKAGES,
/* def */ 0) != 0;
}
diff --git a/services/backup/java/com/android/server/backup/restore/FullRestoreEngineThread.java b/services/backup/java/com/android/server/backup/restore/FullRestoreEngineThread.java
index 7075608674a1..71f1dbf35008 100644
--- a/services/backup/java/com/android/server/backup/restore/FullRestoreEngineThread.java
+++ b/services/backup/java/com/android/server/backup/restore/FullRestoreEngineThread.java
@@ -1,10 +1,10 @@
package com.android.server.backup.restore;
import android.os.ParcelFileDescriptor;
+import android.os.ParcelFileDescriptor.AutoCloseInputStream;
import libcore.io.IoUtils;
-import java.io.FileInputStream;
import java.io.InputStream;
class FullRestoreEngineThread implements Runnable {
@@ -19,7 +19,7 @@ class FullRestoreEngineThread implements Runnable {
// We *do* want this FileInputStream to own the underlying fd, so that
// when we are finished with it, it closes this end of the pipe in a way
// that signals its other end.
- mEngineStream = new FileInputStream(engineSocket.getFileDescriptor(), true);
+ mEngineStream = new AutoCloseInputStream(engineSocket);
// Tell it to be sure to leave the agent instance up after finishing
mMustKillAgent = false;
}
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
index 6ccdf245b271..d6759b3e2cca 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
@@ -22,10 +22,14 @@ import static com.android.internal.util.FunctionalUtils.uncheckExceptions;
import static com.android.internal.util.Preconditions.checkArgument;
import static com.android.internal.util.Preconditions.checkNotNull;
import static com.android.internal.util.Preconditions.checkState;
+import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
import static com.android.internal.util.function.pooled.PooledLambda.obtainRunnable;
+import static java.util.concurrent.TimeUnit.MINUTES;
+
import android.annotation.CheckResult;
import android.annotation.Nullable;
+import android.app.AppOpsManager;
import android.app.PendingIntent;
import android.companion.Association;
import android.companion.AssociationRequest;
@@ -36,6 +40,7 @@ import android.companion.IFindDeviceCallback;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.SharedPreferences;
import android.content.pm.FeatureInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageItemInfo;
@@ -55,6 +60,7 @@ import android.os.ServiceManager;
import android.os.ShellCallback;
import android.os.ShellCommand;
import android.os.UserHandle;
+import android.os.UserManagerInternal;
import android.provider.Settings;
import android.provider.SettingsStringUtil.ComponentNameSet;
import android.text.BidiFormatter;
@@ -71,6 +77,7 @@ import com.android.internal.infra.AndroidFuture;
import com.android.internal.infra.PerUser;
import com.android.internal.infra.ServiceConnector;
import com.android.internal.notification.NotificationAccessConfirmationActivityContract;
+import com.android.internal.os.BackgroundThread;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.CollectionUtils;
import com.android.internal.util.function.pooled.PooledLambda;
@@ -112,6 +119,9 @@ public class CompanionDeviceManagerService extends SystemService implements Bind
private static final boolean DEBUG = false;
private static final String LOG_TAG = "CompanionDeviceManagerService";
+ private static final String PREF_FILE_NAME = "companion_device_preferences.xml";
+ private static final String PREF_KEY_AUTO_REVOKE_GRANTS_DONE = "auto_revoke_grants_done";
+
private static final String XML_TAG_ASSOCIATIONS = "associations";
private static final String XML_TAG_ASSOCIATION = "association";
private static final String XML_ATTR_PACKAGE = "package";
@@ -150,7 +160,6 @@ public class CompanionDeviceManagerService extends SystemService implements Bind
}
};
-
registerPackageMonitor();
}
@@ -195,6 +204,39 @@ public class CompanionDeviceManagerService extends SystemService implements Bind
if (atmInternal != null) {
atmInternal.setCompanionAppPackages(userHandle, companionAppPackages);
}
+
+ BackgroundThread.getHandler().sendMessageDelayed(
+ obtainMessage(CompanionDeviceManagerService::maybeGrantAutoRevokeExemptions, this),
+ MINUTES.toMillis(10));
+ }
+
+ void maybeGrantAutoRevokeExemptions() {
+ PackageManager pm = getContext().getPackageManager();
+ for (int userId : LocalServices.getService(UserManagerInternal.class).getUserIds()) {
+ SharedPreferences pref = getContext().getSharedPreferences(
+ new File(Environment.getUserSystemDirectory(userId), PREF_FILE_NAME),
+ Context.MODE_PRIVATE);
+ if (pref.getBoolean(PREF_KEY_AUTO_REVOKE_GRANTS_DONE, false)) {
+ continue;
+ }
+
+ try {
+ Set<Association> associations = readAllAssociations(userId);
+ if (associations == null) {
+ continue;
+ }
+ for (Association a : associations) {
+ try {
+ int uid = pm.getPackageUidAsUser(a.companionAppPackage, userId);
+ exemptFromAutoRevoke(a.companionAppPackage, uid);
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.w(LOG_TAG, "Unknown companion package: " + a.companionAppPackage, e);
+ }
+ }
+ } finally {
+ pref.edit().putBoolean(PREF_KEY_AUTO_REVOKE_GRANTS_DONE, true).apply();
+ }
+ }
}
@Override
@@ -294,8 +336,10 @@ public class CompanionDeviceManagerService extends SystemService implements Bind
@Override
public List<String> getAssociations(String callingPackage, int userId)
throws RemoteException {
- checkCallerIsSystemOr(callingPackage, userId);
- checkUsesFeature(callingPackage, getCallingUserId());
+ if (!callerCanManageCompanionDevices()) {
+ checkCallerIsSystemOr(callingPackage, userId);
+ checkUsesFeature(callingPackage, getCallingUserId());
+ }
return new ArrayList<>(CollectionUtils.map(
readAllAssociations(userId, callingPackage),
a -> a.deviceAddress));
@@ -311,6 +355,12 @@ public class CompanionDeviceManagerService extends SystemService implements Bind
removeAssociation(getCallingUserId(), callingPackage, deviceMacAddress);
}
+ private boolean callerCanManageCompanionDevices() {
+ return getContext().checkCallingOrSelfPermission(
+ android.Manifest.permission.MANAGE_COMPANION_DEVICES)
+ == PackageManager.PERMISSION_GRANTED;
+ }
+
private void checkCallerIsSystemOr(String pkg) throws RemoteException {
checkCallerIsSystemOr(pkg, getCallingUserId());
}
@@ -469,6 +519,21 @@ public class CompanionDeviceManagerService extends SystemService implements Bind
packageInfo.applicationInfo.uid,
NetworkPolicyManager.POLICY_ALLOW_METERED_BACKGROUND);
}
+
+ exemptFromAutoRevoke(packageInfo.packageName, packageInfo.applicationInfo.uid);
+ }
+
+ private void exemptFromAutoRevoke(String packageName, int uid) {
+ try {
+ mAppOpsManager.setMode(
+ AppOpsManager.OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED,
+ uid,
+ packageName,
+ AppOpsManager.MODE_IGNORED);
+ } catch (RemoteException e) {
+ Log.w(LOG_TAG,
+ "Error while granting auto revoke exemption for " + packageName, e);
+ }
}
private static <T> boolean containsEither(T[] array, T a, T b) {
diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
index 13e5ab451cfc..ea94ad0b3c20 100644
--- a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
+++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
@@ -26,6 +26,15 @@ import static android.view.contentcapture.ContentCaptureManager.RESULT_CODE_SECU
import static android.view.contentcapture.ContentCaptureManager.RESULT_CODE_TRUE;
import static android.view.contentcapture.ContentCaptureSession.STATE_DISABLED;
+import static com.android.internal.util.FrameworkStatsLog.CONTENT_CAPTURE_SERVICE_EVENTS__EVENT__ACCEPT_DATA_SHARE_REQUEST;
+import static com.android.internal.util.FrameworkStatsLog.CONTENT_CAPTURE_SERVICE_EVENTS__EVENT__DATA_SHARE_ERROR_CLIENT_PIPE_FAIL;
+import static com.android.internal.util.FrameworkStatsLog.CONTENT_CAPTURE_SERVICE_EVENTS__EVENT__DATA_SHARE_ERROR_CONCURRENT_REQUEST;
+import static com.android.internal.util.FrameworkStatsLog.CONTENT_CAPTURE_SERVICE_EVENTS__EVENT__DATA_SHARE_ERROR_EMPTY_DATA;
+import static com.android.internal.util.FrameworkStatsLog.CONTENT_CAPTURE_SERVICE_EVENTS__EVENT__DATA_SHARE_ERROR_IOEXCEPTION;
+import static com.android.internal.util.FrameworkStatsLog.CONTENT_CAPTURE_SERVICE_EVENTS__EVENT__DATA_SHARE_ERROR_SERVICE_PIPE_FAIL;
+import static com.android.internal.util.FrameworkStatsLog.CONTENT_CAPTURE_SERVICE_EVENTS__EVENT__DATA_SHARE_ERROR_TIMEOUT_INTERRUPTED;
+import static com.android.internal.util.FrameworkStatsLog.CONTENT_CAPTURE_SERVICE_EVENTS__EVENT__DATA_SHARE_WRITE_FINISHED;
+import static com.android.internal.util.FrameworkStatsLog.CONTENT_CAPTURE_SERVICE_EVENTS__EVENT__REJECT_DATA_SHARE_REQUEST;
import static com.android.internal.util.SyncResultReceiver.bundleFor;
import android.annotation.NonNull;
@@ -95,6 +104,7 @@ import java.util.List;
import java.util.Set;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
+import java.util.concurrent.atomic.AtomicBoolean;
/**
* A service used to observe the contents of the screen.
@@ -114,6 +124,14 @@ public final class ContentCaptureManagerService extends
private static final int MAX_CONCURRENT_FILE_SHARING_REQUESTS = 10;
private static final int DATA_SHARE_BYTE_BUFFER_LENGTH = 1_024;
+ // Needed to pass checkstyle_hook as names are too long for one line.
+ private static final int EVENT__DATA_SHARE_ERROR_CONCURRENT_REQUEST =
+ CONTENT_CAPTURE_SERVICE_EVENTS__EVENT__DATA_SHARE_ERROR_CONCURRENT_REQUEST;
+ private static final int EVENT__DATA_SHARE_ERROR_TIMEOUT_INTERRUPTED =
+ CONTENT_CAPTURE_SERVICE_EVENTS__EVENT__DATA_SHARE_ERROR_TIMEOUT_INTERRUPTED;
+ private static final int EVENT__DATA_SHARE_WRITE_FINISHED =
+ CONTENT_CAPTURE_SERVICE_EVENTS__EVENT__DATA_SHARE_WRITE_FINISHED;
+
private final LocalService mLocalService = new LocalService();
@Nullable
@@ -657,6 +675,10 @@ public final class ContentCaptureManagerService extends
if (mPackagesWithShareRequests.size() >= MAX_CONCURRENT_FILE_SHARING_REQUESTS
|| mPackagesWithShareRequests.contains(request.getPackageName())) {
try {
+ String serviceName = mServiceNameResolver.getServiceName(userId);
+ ContentCaptureMetricsLogger.writeServiceEvent(
+ EVENT__DATA_SHARE_ERROR_CONCURRENT_REQUEST,
+ serviceName, request.getPackageName());
clientAdapter.error(
ContentCaptureManager.DATA_SHARE_ERROR_CONCURRENT_REQUEST);
} catch (RemoteException e) {
@@ -920,6 +942,7 @@ public final class ContentCaptureManagerService extends
@NonNull private final DataShareRequest mDataShareRequest;
@NonNull private final IDataShareWriteAdapter mClientAdapter;
@NonNull private final ContentCaptureManagerService mParentService;
+ @NonNull private final AtomicBoolean mLoggedWriteFinish = new AtomicBoolean(false);
DataShareCallbackDelegate(@NonNull DataShareRequest dataShareRequest,
@NonNull IDataShareWriteAdapter clientAdapter,
@@ -930,13 +953,16 @@ public final class ContentCaptureManagerService extends
}
@Override
- public void accept(@NonNull IDataShareReadAdapter serviceAdapter) throws RemoteException {
+ public void accept(@NonNull IDataShareReadAdapter serviceAdapter) {
Slog.i(TAG, "Data share request accepted by Content Capture service");
+ logServiceEvent(CONTENT_CAPTURE_SERVICE_EVENTS__EVENT__ACCEPT_DATA_SHARE_REQUEST);
Pair<ParcelFileDescriptor, ParcelFileDescriptor> clientPipe = createPipe();
if (clientPipe == null) {
- mClientAdapter.error(ContentCaptureManager.DATA_SHARE_ERROR_UNKNOWN);
- serviceAdapter.error(ContentCaptureManager.DATA_SHARE_ERROR_UNKNOWN);
+ logServiceEvent(
+ CONTENT_CAPTURE_SERVICE_EVENTS__EVENT__DATA_SHARE_ERROR_CLIENT_PIPE_FAIL);
+ sendErrorSignal(mClientAdapter, serviceAdapter,
+ ContentCaptureManager.DATA_SHARE_ERROR_UNKNOWN);
return;
}
@@ -945,10 +971,12 @@ public final class ContentCaptureManagerService extends
Pair<ParcelFileDescriptor, ParcelFileDescriptor> servicePipe = createPipe();
if (servicePipe == null) {
+ logServiceEvent(
+ CONTENT_CAPTURE_SERVICE_EVENTS__EVENT__DATA_SHARE_ERROR_SERVICE_PIPE_FAIL);
bestEffortCloseFileDescriptors(sourceIn, sinkIn);
- mClientAdapter.error(ContentCaptureManager.DATA_SHARE_ERROR_UNKNOWN);
- serviceAdapter.error(ContentCaptureManager.DATA_SHARE_ERROR_UNKNOWN);
+ sendErrorSignal(mClientAdapter, serviceAdapter,
+ ContentCaptureManager.DATA_SHARE_ERROR_UNKNOWN);
return;
}
@@ -957,8 +985,26 @@ public final class ContentCaptureManagerService extends
mParentService.mPackagesWithShareRequests.add(mDataShareRequest.getPackageName());
- mClientAdapter.write(sourceIn);
- serviceAdapter.start(sinkOut);
+ try {
+ mClientAdapter.write(sourceIn);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Failed to call write() the client operation", e);
+ sendErrorSignal(mClientAdapter, serviceAdapter,
+ ContentCaptureManager.DATA_SHARE_ERROR_UNKNOWN);
+ logServiceEvent(
+ CONTENT_CAPTURE_SERVICE_EVENTS__EVENT__DATA_SHARE_ERROR_CLIENT_PIPE_FAIL);
+ return;
+ }
+ try {
+ serviceAdapter.start(sinkOut);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Failed to call start() the service operation", e);
+ sendErrorSignal(mClientAdapter, serviceAdapter,
+ ContentCaptureManager.DATA_SHARE_ERROR_UNKNOWN);
+ logServiceEvent(
+ CONTENT_CAPTURE_SERVICE_EVENTS__EVENT__DATA_SHARE_ERROR_SERVICE_PIPE_FAIL);
+ return;
+ }
// File descriptors received by remote apps will be copies of the current one. Close
// the ones that belong to the system server, so there's only 1 open left for the
@@ -987,6 +1033,8 @@ public final class ContentCaptureManagerService extends
}
} catch (IOException e) {
Slog.e(TAG, "Failed to pipe client and service streams", e);
+ logServiceEvent(
+ CONTENT_CAPTURE_SERVICE_EVENTS__EVENT__DATA_SHARE_ERROR_IOEXCEPTION);
sendErrorSignal(mClientAdapter, serviceAdapter,
ContentCaptureManager.DATA_SHARE_ERROR_UNKNOWN);
@@ -996,6 +1044,10 @@ public final class ContentCaptureManagerService extends
.remove(mDataShareRequest.getPackageName());
}
if (receivedData) {
+ if (!mLoggedWriteFinish.get()) {
+ logServiceEvent(EVENT__DATA_SHARE_WRITE_FINISHED);
+ mLoggedWriteFinish.set(true);
+ }
try {
mClientAdapter.finish();
} catch (RemoteException e) {
@@ -1008,6 +1060,8 @@ public final class ContentCaptureManagerService extends
}
} else {
// Client or service may have crashed before sending.
+ logServiceEvent(
+ CONTENT_CAPTURE_SERVICE_EVENTS__EVENT__DATA_SHARE_ERROR_EMPTY_DATA);
sendErrorSignal(mClientAdapter, serviceAdapter,
ContentCaptureManager.DATA_SHARE_ERROR_UNKNOWN);
}
@@ -1025,10 +1079,20 @@ public final class ContentCaptureManagerService extends
}
@Override
- public void reject() throws RemoteException {
+ public void reject() {
Slog.i(TAG, "Data share request rejected by Content Capture service");
+ logServiceEvent(CONTENT_CAPTURE_SERVICE_EVENTS__EVENT__REJECT_DATA_SHARE_REQUEST);
- mClientAdapter.rejected();
+ try {
+ mClientAdapter.rejected();
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Failed to call rejected() the client operation", e);
+ try {
+ mClientAdapter.error(ContentCaptureManager.DATA_SHARE_ERROR_UNKNOWN);
+ } catch (RemoteException e2) {
+ Slog.w(TAG, "Failed to call error() the client operation", e2);
+ }
+ }
}
private void enforceDataSharingTtl(ParcelFileDescriptor sourceIn,
@@ -1048,11 +1112,16 @@ public final class ContentCaptureManagerService extends
&& !sourceOut.getFileDescriptor().valid();
if (finishedSuccessfully) {
+ if (!mLoggedWriteFinish.get()) {
+ logServiceEvent(EVENT__DATA_SHARE_WRITE_FINISHED);
+ mLoggedWriteFinish.set(true);
+ }
Slog.i(TAG, "Content capture data sharing session terminated "
+ "successfully for package '"
+ mDataShareRequest.getPackageName()
+ "'");
} else {
+ logServiceEvent(EVENT__DATA_SHARE_ERROR_TIMEOUT_INTERRUPTED);
Slog.i(TAG, "Reached the timeout of Content Capture data sharing session "
+ "for package '"
+ mDataShareRequest.getPackageName()
@@ -1123,5 +1192,12 @@ public final class ContentCaptureManagerService extends
Slog.e(TAG, "Failed to call error() the service operation", e);
}
}
+
+ private void logServiceEvent(int eventType) {
+ int userId = UserHandle.getCallingUserId();
+ String serviceName = mParentService.mServiceNameResolver.getServiceName(userId);
+ ContentCaptureMetricsLogger.writeServiceEvent(eventType, serviceName,
+ mDataShareRequest.getPackageName());
+ }
}
}
diff --git a/services/contentcapture/java/com/android/server/contentcapture/RemoteContentCaptureService.java b/services/contentcapture/java/com/android/server/contentcapture/RemoteContentCaptureService.java
index 0b9bf3962562..08e6a0550f69 100644
--- a/services/contentcapture/java/com/android/server/contentcapture/RemoteContentCaptureService.java
+++ b/services/contentcapture/java/com/android/server/contentcapture/RemoteContentCaptureService.java
@@ -156,6 +156,9 @@ final class RemoteContentCaptureService
public void onDataShareRequest(@NonNull DataShareRequest request,
@NonNull IDataShareCallback.Stub dataShareCallback) {
scheduleAsyncRequest((s) -> s.onDataShared(request, dataShareCallback));
+ writeServiceEvent(
+ FrameworkStatsLog.CONTENT_CAPTURE_SERVICE_EVENTS__EVENT__ON_DATA_SHARE_REQUEST,
+ mComponentName, request.getPackageName());
}
/**
diff --git a/services/core/java/android/os/UserManagerInternal.java b/services/core/java/android/os/UserManagerInternal.java
index 94f5741fe828..fbe8c04bd59c 100644
--- a/services/core/java/android/os/UserManagerInternal.java
+++ b/services/core/java/android/os/UserManagerInternal.java
@@ -27,6 +27,7 @@ import com.android.server.pm.RestrictionsSet;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.List;
/**
* @hide Only for use within the system server.
@@ -219,6 +220,13 @@ public abstract class UserManagerInternal {
public abstract int[] getUserIds();
/**
+ * Internal implementation of getUsers does not check permissions.
+ * This improves performance for calls from inside system server which already have permissions
+ * checked.
+ */
+ public abstract @NonNull List<UserInfo> getUsers(boolean excludeDying);
+
+ /**
* Checks if the {@code callingUserId} and {@code targetUserId} are same or in same group
* and that the {@code callingUserId} is not a profile and {@code targetUserId} is enabled.
*
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index 4009cafd04fb..d51ca6e9ab42 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -104,6 +104,7 @@ import com.android.server.usage.AppStandbyInternal.AppIdleStateChangeListener;
import java.io.ByteArrayOutputStream;
import java.io.FileDescriptor;
import java.io.PrintWriter;
+import java.io.StringWriter;
import java.text.SimpleDateFormat;
import java.time.DateTimeException;
import java.util.ArrayList;
@@ -146,6 +147,12 @@ class AlarmManagerService extends SystemService {
static final boolean DEBUG_WAKELOCK = localLOGV || false;
static final boolean DEBUG_BG_LIMIT = localLOGV || false;
static final boolean DEBUG_STANDBY = localLOGV || false;
+
+ // TODO (b/157782538): Turn off once bug is fixed.
+ static final boolean DEBUG_PER_UID_LIMIT = true;
+ // TODO (b/157782538): Turn off once bug is fixed.
+ static final boolean WARN_SYSTEM_ON_ALARM_LIMIT = true;
+
static final boolean RECORD_ALARMS_IN_HISTORY = true;
static final boolean RECORD_DEVICE_IDLE_ALARMS = false;
static final String TIMEZONE_PROPERTY = "persist.sys.timezone";
@@ -1767,7 +1774,21 @@ class AlarmManagerService extends SystemService {
"Maximum limit of concurrent alarms " + mConstants.MAX_ALARMS_PER_UID
+ " reached for uid: " + UserHandle.formatUid(callingUid)
+ ", callingPackage: " + callingPackage;
- Slog.w(TAG, errorMsg);
+
+ if (WARN_SYSTEM_ON_ALARM_LIMIT && UserHandle.isCore(callingUid)) {
+ final StringWriter logWriter = new StringWriter();
+ final PrintWriter pw = new PrintWriter(logWriter);
+ pw.println(errorMsg);
+ pw.println("Next 20 alarms for " + callingUid + ":");
+ dumpUpcomingNAlarmsForUid(pw, callingUid, 20);
+ pw.flush();
+ Slog.wtf(TAG, logWriter.toString());
+ } else {
+ Slog.w(TAG, errorMsg);
+ }
+ if (DEBUG_PER_UID_LIMIT) {
+ logAllAlarmsForUidLocked(callingUid);
+ }
throw new IllegalStateException(errorMsg);
}
setImplLocked(type, triggerAtTime, triggerElapsed, windowLength, maxElapsed,
@@ -1776,6 +1797,36 @@ class AlarmManagerService extends SystemService {
}
}
+ private void logAllAlarmsForUidLocked(int uid) {
+ final StringWriter logWriter = new StringWriter();
+ final PrintWriter pw = new PrintWriter(logWriter);
+
+ pw.println("List of all pending alarms for " + UserHandle.formatUid(uid) + ":");
+ dumpUpcomingNAlarmsForUid(pw, uid, mConstants.MAX_ALARMS_PER_UID);
+ pw.flush();
+ Slog.d(TAG, logWriter.toString());
+ }
+
+ private void dumpUpcomingNAlarmsForUid(PrintWriter pw, int uid, int n) {
+ final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ final long nowElapsed = mInjector.getElapsedRealtime();
+ final long nowRtc = mInjector.getCurrentTimeMillis();
+
+ int count = 0;
+ for (int i = 0; i < mAlarmBatches.size() && count < n; i++) {
+ final Batch b = mAlarmBatches.get(i);
+ for (int j = 0; j < b.size() && count < n; j++) {
+ final Alarm a = b.get(j);
+ if (a.uid == uid) {
+ final String label = labelForType(a.type);
+ pw.print(label + " #" + (++count) + ": ");
+ pw.println(a);
+ a.dump(pw, " ", nowElapsed, nowRtc, sdf);
+ }
+ }
+ }
+ }
+
private void setImplLocked(int type, long when, long whenElapsed, long windowLength,
long maxWhen, long interval, PendingIntent operation, IAlarmListener directReceiver,
String listenerTag, int flags, boolean doValidate, WorkSource workSource,
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 2958fd2ae63a..01b2e691d43a 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -67,6 +67,7 @@ import android.app.BroadcastOptions;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
+import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
@@ -1698,6 +1699,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
return newNc;
}
+ // Allow VPNs to see ownership of their own VPN networks - not location sensitive.
+ if (nc.hasTransport(TRANSPORT_VPN)) {
+ // Owner UIDs already checked above. No need to re-check.
+ return newNc;
+ }
+
Binder.withCleanCallingIdentity(
() -> {
if (!mLocationPermissionChecker.checkLocationPermission(
@@ -2481,10 +2488,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
final List<NetworkDiagnostics> netDiags = new ArrayList<NetworkDiagnostics>();
final long DIAG_TIME_MS = 5000;
for (NetworkAgentInfo nai : networksSortedById()) {
+ PrivateDnsConfig privateDnsCfg = mDnsManager.getPrivateDnsConfig(nai.network);
// Start gathering diagnostic information.
netDiags.add(new NetworkDiagnostics(
nai.network,
new LinkProperties(nai.linkProperties), // Must be a copy.
+ privateDnsCfg,
DIAG_TIME_MS));
}
@@ -3069,7 +3078,11 @@ public class ConnectivityService extends IConnectivityManager.Stub
// Only the system server can register notifications with package "android"
final long token = Binder.clearCallingIdentity();
try {
- pendingIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0);
+ pendingIntent = PendingIntent.getBroadcast(
+ mContext,
+ 0 /* requestCode */,
+ intent,
+ PendingIntent.FLAG_IMMUTABLE);
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -3925,6 +3938,15 @@ public class ConnectivityService extends IConnectivityManager.Stub
pw.decreaseIndent();
}
+ // TODO: This method is copied from TetheringNotificationUpdater. Should have a utility class to
+ // unify the method.
+ private static @NonNull String getSettingsPackageName(@NonNull final PackageManager pm) {
+ final Intent settingsIntent = new Intent(Settings.ACTION_SETTINGS);
+ final ComponentName settingsComponent = settingsIntent.resolveActivity(pm);
+ return settingsComponent != null
+ ? settingsComponent.getPackageName() : "com.android.settings";
+ }
+
private void showNetworkNotification(NetworkAgentInfo nai, NotificationType type) {
final String action;
final boolean highPriority;
@@ -3959,12 +3981,20 @@ public class ConnectivityService extends IConnectivityManager.Stub
if (type != NotificationType.PRIVATE_DNS_BROKEN) {
intent.setData(Uri.fromParts("netId", Integer.toString(nai.network.netId), null));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- intent.setClassName("com.android.settings",
- "com.android.settings.wifi.WifiNoInternetDialog");
+ // Some OEMs have their own Settings package. Thus, need to get the current using
+ // Settings package name instead of just use default name "com.android.settings".
+ final String settingsPkgName = getSettingsPackageName(mContext.getPackageManager());
+ intent.setClassName(settingsPkgName,
+ settingsPkgName + ".wifi.WifiNoInternetDialog");
}
PendingIntent pendingIntent = PendingIntent.getActivityAsUser(
- mContext, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT);
+ mContext,
+ 0 /* requestCode */,
+ intent,
+ PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE,
+ null /* options */,
+ UserHandle.CURRENT);
mNotifier.showNotification(nai.network.netId, type, nai, null, pendingIntent, highPriority);
}
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index 1ce3dfe9f3a0..6e8eca3f46cf 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -52,7 +52,6 @@ import static com.android.internal.util.XmlUtils.readStringAttribute;
import static com.android.internal.util.XmlUtils.writeIntAttribute;
import static com.android.internal.util.XmlUtils.writeLongAttribute;
import static com.android.internal.util.XmlUtils.writeStringAttribute;
-import static com.android.server.storage.StorageUserConnection.REMOTE_TIMEOUT_SECONDS;
import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
import static org.xmlpull.v1.XmlPullParser.START_TAG;
@@ -224,6 +223,9 @@ class StorageManagerService extends IStorageManager.Stub
private static final String ANDROID_VOLD_APP_DATA_ISOLATION_ENABLED_PROPERTY =
"persist.sys.vold_app_data_isolation_enabled";
+ // How long we wait to reset storage, if we failed to call onMount on the
+ // external storage service.
+ public static final int FAILED_MOUNT_RESET_TIMEOUT_SECONDS = 10;
/**
* If {@code 1}, enables the isolated storage feature. If {@code -1},
* disables the isolated storage feature. If {@code 0}, uses the default
@@ -456,6 +458,12 @@ class StorageManagerService extends IStorageManager.Stub
"(?i)(^/storage/[^/]+/(?:([0-9]+)/)?Android/(?:data|media|obb|sandbox)/)([^/]+)(/.*)?");
+ /** Automotive device unlockes users before system boot complete and this requires special
+ * handling as vold reset can lead into race conditions. When this is set, all users unlocked
+ * in {@code UserManager} level are unlocked after vold reset.
+ */
+ private final boolean mIsAutomotive;
+
private VolumeInfo findVolumeByIdOrThrow(String id) {
synchronized (mLock) {
final VolumeInfo vol = mVolumes.get(id);
@@ -1080,17 +1088,22 @@ class StorageManagerService extends IStorageManager.Stub
Slog.d(TAG, "Thinking about reset, mBootCompleted=" + mBootCompleted
+ ", mDaemonConnected=" + mDaemonConnected);
if (mBootCompleted && mDaemonConnected) {
- final List<UserInfo> users = mContext.getSystemService(UserManager.class).getUsers();
+ final UserManager userManager = mContext.getSystemService(UserManager.class);
+ final List<UserInfo> users = userManager.getUsers();
if (mIsFuseEnabled) {
- mStorageSessionController.onReset(mVold, mHandler);
+ mStorageSessionController.onReset(mVold, () -> {
+ mHandler.removeCallbacksAndMessages(null);
+ });
} else {
killMediaProvider(users);
}
final int[] systemUnlockedUsers;
synchronized (mLock) {
- systemUnlockedUsers = mSystemUnlockedUsers;
+ // make copy as sorting can change order
+ systemUnlockedUsers = Arrays.copyOf(mSystemUnlockedUsers,
+ mSystemUnlockedUsers.length);
mDisks.clear();
mVolumes.clear();
@@ -1112,6 +1125,9 @@ class StorageManagerService extends IStorageManager.Stub
mVold.onUserStarted(userId);
mStoraged.onUserStarted(userId);
}
+ if (mIsAutomotive) {
+ restoreAllUnlockedUsers(userManager, users, systemUnlockedUsers);
+ }
mVold.onSecureKeyguardStateChanged(mSecureKeyguardShowing);
mStorageManagerInternal.onReset(mVold);
} catch (Exception e) {
@@ -1120,6 +1136,29 @@ class StorageManagerService extends IStorageManager.Stub
}
}
+ private void restoreAllUnlockedUsers(UserManager userManager, List<UserInfo> allUsers,
+ int[] systemUnlockedUsers) throws Exception {
+ Arrays.sort(systemUnlockedUsers);
+ UserManager.invalidateIsUserUnlockedCache();
+ for (UserInfo user : allUsers) {
+ int userId = user.id;
+ if (!userManager.isUserRunning(userId)) {
+ continue;
+ }
+ if (Arrays.binarySearch(systemUnlockedUsers, userId) >= 0) {
+ continue;
+ }
+ boolean unlockingOrUnlocked = userManager.isUserUnlockingOrUnlocked(userId);
+ if (!unlockingOrUnlocked) {
+ continue;
+ }
+ Slog.w(TAG, "UNLOCK_USER lost from vold reset, will retry, user:" + userId);
+ mVold.onUserStarted(userId);
+ mStoraged.onUserStarted(userId);
+ mHandler.obtainMessage(H_COMPLETE_UNLOCK_USER, userId).sendToTarget();
+ }
+ }
+
private void onUnlockUser(int userId) {
Slog.d(TAG, "onUnlockUser " + userId);
@@ -1134,8 +1173,6 @@ class StorageManagerService extends IStorageManager.Stub
Slog.wtf(TAG, e);
}
- onKeyguardStateChanged(false);
-
mHandler.obtainMessage(H_COMPLETE_UNLOCK_USER, userId).sendToTarget();
}
@@ -1147,9 +1184,20 @@ class StorageManagerService extends IStorageManager.Stub
mPmInternal.migrateLegacyObbData();
}
+ onKeyguardStateChanged(false);
+
// Record user as started so newly mounted volumes kick off events
// correctly, then synthesize events for any already-mounted volumes.
synchronized (mLock) {
+ if (mIsAutomotive) {
+ for (int unlockedUser : mSystemUnlockedUsers) {
+ if (unlockedUser == userId) {
+ // This can happen as restoreAllUnlockedUsers can double post the message.
+ Log.i(TAG, "completeUnlockUser called for already unlocked user:" + userId);
+ return;
+ }
+ }
+ }
for (int i = 0; i < mVolumes.size(); i++) {
final VolumeInfo vol = mVolumes.valueAt(i);
if (vol.isVisibleForRead(userId) && vol.isMountedReadable()) {
@@ -1815,6 +1863,9 @@ class StorageManagerService extends IStorageManager.Stub
if (WATCHDOG_ENABLE) {
Watchdog.getInstance().addMonitor(this);
}
+
+ mIsAutomotive = context.getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_AUTOMOTIVE);
}
/**
@@ -2202,7 +2253,7 @@ class StorageManagerService extends IStorageManager.Stub
} catch (ExternalStorageServiceException e) {
Slog.e(TAG, "Failed to mount volume " + vol, e);
- int nextResetSeconds = REMOTE_TIMEOUT_SECONDS * 2;
+ int nextResetSeconds = FAILED_MOUNT_RESET_TIMEOUT_SECONDS;
Slog.i(TAG, "Scheduling reset in " + nextResetSeconds + "s");
mHandler.removeMessages(H_RESET);
mHandler.sendMessageDelayed(mHandler.obtainMessage(H_RESET),
@@ -2252,8 +2303,15 @@ class StorageManagerService extends IStorageManager.Stub
enforcePermission(android.Manifest.permission.MOUNT_FORMAT_FILESYSTEMS);
final VolumeInfo vol = findVolumeByIdOrThrow(volId);
+ final String fsUuid = vol.fsUuid;
try {
mVold.format(vol.id, "auto");
+
+ // After a successful format above, we should forget about any
+ // records for the old partition, since it'll never appear again
+ if (!TextUtils.isEmpty(fsUuid)) {
+ forgetVolume(fsUuid);
+ }
} catch (Exception e) {
Slog.wtf(TAG, e);
}
@@ -3535,6 +3593,13 @@ class StorageManagerService extends IStorageManager.Stub
// point
final boolean systemUserUnlocked = isSystemUnlocked(UserHandle.USER_SYSTEM);
+ // When the caller is the app actually hosting external storage, we
+ // should never attempt to augment the actual storage volume state,
+ // otherwise we risk confusing it with race conditions as users go
+ // through various unlocked states
+ final boolean callerIsMediaStore = UserHandle.isSameApp(Binder.getCallingUid(),
+ mMediaStoreAuthorityAppId);
+
final boolean userIsDemo;
final boolean userKeyUnlocked;
final boolean storagePermission;
@@ -3554,6 +3619,7 @@ class StorageManagerService extends IStorageManager.Stub
final ArraySet<String> resUuids = new ArraySet<>();
synchronized (mLock) {
for (int i = 0; i < mVolumes.size(); i++) {
+ final String volId = mVolumes.keyAt(i);
final VolumeInfo vol = mVolumes.valueAt(i);
switch (vol.getType()) {
case VolumeInfo.TYPE_PUBLIC:
@@ -3578,11 +3644,19 @@ class StorageManagerService extends IStorageManager.Stub
if (!match) continue;
boolean reportUnmounted = false;
- if (!systemUserUnlocked) {
+ if (callerIsMediaStore) {
+ // When the caller is the app actually hosting external storage, we
+ // should never attempt to augment the actual storage volume state,
+ // otherwise we risk confusing it with race conditions as users go
+ // through various unlocked states
+ } else if (!systemUserUnlocked) {
reportUnmounted = true;
+ Slog.w(TAG, "Reporting " + volId + " unmounted due to system locked");
} else if ((vol.getType() == VolumeInfo.TYPE_EMULATED) && !userKeyUnlocked) {
reportUnmounted = true;
+ Slog.w(TAG, "Reporting " + volId + "unmounted due to " + userId + " locked");
} else if (!storagePermission && !realState) {
+ Slog.w(TAG, "Reporting " + volId + "unmounted due to missing permissions");
reportUnmounted = true;
}
@@ -4447,6 +4521,7 @@ class StorageManagerService extends IStorageManager.Stub
pw.println("Forced scoped storage app list: "
+ DeviceConfig.getProperty(DeviceConfig.NAMESPACE_STORAGE_NATIVE_BOOT,
PROP_FORCED_SCOPED_STORAGE_WHITELIST));
+ pw.println("isAutomotive:" + mIsAutomotive);
}
synchronized (mObbMounts) {
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index a3c164d63605..23bf955ba9a6 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -310,27 +310,30 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
private List<Map<Integer, PreciseDataConnectionState>> mPreciseDataConnectionStates =
new ArrayList<Map<Integer, PreciseDataConnectionState>>();
- // Nothing here yet, but putting it here in case we want to add more in the future.
- static final int ENFORCE_COARSE_LOCATION_PERMISSION_MASK = 0;
+ static final int ENFORCE_COARSE_LOCATION_PERMISSION_MASK =
+ PhoneStateListener.LISTEN_REGISTRATION_FAILURE
+ | PhoneStateListener.LISTEN_BARRING_INFO;
static final int ENFORCE_FINE_LOCATION_PERMISSION_MASK =
PhoneStateListener.LISTEN_CELL_LOCATION
- | PhoneStateListener.LISTEN_CELL_INFO;
+ | PhoneStateListener.LISTEN_CELL_INFO
+ | PhoneStateListener.LISTEN_REGISTRATION_FAILURE
+ | PhoneStateListener.LISTEN_BARRING_INFO;
static final int ENFORCE_PHONE_STATE_PERMISSION_MASK =
- PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR
- | PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR
- | PhoneStateListener.LISTEN_EMERGENCY_NUMBER_LIST
- | PhoneStateListener.LISTEN_DISPLAY_INFO_CHANGED;
+ PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR
+ | PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR
+ | PhoneStateListener.LISTEN_EMERGENCY_NUMBER_LIST
+ | PhoneStateListener.LISTEN_DISPLAY_INFO_CHANGED;
static final int ENFORCE_PRECISE_PHONE_STATE_PERMISSION_MASK =
- PhoneStateListener.LISTEN_PRECISE_CALL_STATE
- | PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE
- | PhoneStateListener.LISTEN_CALL_DISCONNECT_CAUSES
- | PhoneStateListener.LISTEN_CALL_ATTRIBUTES_CHANGED
- | PhoneStateListener.LISTEN_IMS_CALL_DISCONNECT_CAUSES
- | PhoneStateListener.LISTEN_REGISTRATION_FAILURE
- | PhoneStateListener.LISTEN_BARRING_INFO;
+ PhoneStateListener.LISTEN_PRECISE_CALL_STATE
+ | PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE
+ | PhoneStateListener.LISTEN_CALL_DISCONNECT_CAUSES
+ | PhoneStateListener.LISTEN_CALL_ATTRIBUTES_CHANGED
+ | PhoneStateListener.LISTEN_IMS_CALL_DISCONNECT_CAUSES
+ | PhoneStateListener.LISTEN_REGISTRATION_FAILURE
+ | PhoneStateListener.LISTEN_BARRING_INFO;
static final int READ_ACTIVE_EMERGENCY_SESSION_PERMISSION_MASK =
PhoneStateListener.LISTEN_OUTGOING_EMERGENCY_CALL
@@ -338,9 +341,9 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
static final int READ_PRIVILEGED_PHONE_STATE_PERMISSION_MASK =
PhoneStateListener.LISTEN_OEM_HOOK_RAW_EVENT
- | PhoneStateListener.LISTEN_SRVCC_STATE_CHANGED
- | PhoneStateListener.LISTEN_RADIO_POWER_STATE_CHANGED
- | PhoneStateListener.LISTEN_VOICE_ACTIVATION_STATE;
+ | PhoneStateListener.LISTEN_SRVCC_STATE_CHANGED
+ | PhoneStateListener.LISTEN_RADIO_POWER_STATE_CHANGED
+ | PhoneStateListener.LISTEN_VOICE_ACTIVATION_STATE;
private static final int MSG_USER_SWITCHED = 1;
private static final int MSG_UPDATE_DEFAULT_SUB = 2;
diff --git a/services/core/java/com/android/server/UiModeManagerService.java b/services/core/java/com/android/server/UiModeManagerService.java
index 35936babf3cb..be080e5cce62 100644
--- a/services/core/java/com/android/server/UiModeManagerService.java
+++ b/services/core/java/com/android/server/UiModeManagerService.java
@@ -233,7 +233,7 @@ final class UiModeManagerService extends SystemService {
public void onTwilightStateChanged(@Nullable TwilightState state) {
synchronized (mLock) {
if (mNightMode == UiModeManager.MODE_NIGHT_AUTO && mSystemReady) {
- if (mCar) {
+ if (shouldApplyAutomaticChangesImmediately()) {
updateLocked(0, 0);
} else {
registerScreenOffEventLocked();
@@ -1155,7 +1155,6 @@ final class UiModeManagerService extends SystemService {
void updateLocked(int enableFlags, int disableFlags) {
String action = null;
String oldAction = null;
- boolean originalComputedNightMode = mComputedNightMode;
if (mLastBroadcastState == Intent.EXTRA_DOCK_STATE_CAR) {
adjustStatusBarCarModeLocked();
oldAction = UiModeManager.ACTION_EXIT_CAR_MODE;
@@ -1236,16 +1235,11 @@ final class UiModeManagerService extends SystemService {
sendConfigurationAndStartDreamOrDockAppLocked(category);
}
- // reset overrides if mComputedNightMode changes
- if (originalComputedNightMode != mComputedNightMode) {
- resetNightModeOverrideLocked();
- }
-
// keep screen on when charging and in car mode
boolean keepScreenOn = mCharging &&
((mCarModeEnabled && mCarModeKeepsScreenOn &&
- (mCarModeEnableFlags & UiModeManager.ENABLE_CAR_MODE_ALLOW_SLEEP) == 0) ||
- (mCurUiMode == Configuration.UI_MODE_TYPE_DESK && mDeskModeKeepsScreenOn));
+ (mCarModeEnableFlags & UiModeManager.ENABLE_CAR_MODE_ALLOW_SLEEP) == 0) ||
+ (mCurUiMode == Configuration.UI_MODE_TYPE_DESK && mDeskModeKeepsScreenOn));
if (keepScreenOn != mWakeLock.isHeld()) {
if (keepScreenOn) {
mWakeLock.acquire();
@@ -1403,6 +1397,7 @@ final class UiModeManagerService extends SystemService {
mComputedNightMode = false;
return;
}
+ resetNightModeOverrideLocked();
}
private boolean resetNightModeOverrideLocked() {
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index a7bf98280af8..56953708e383 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -622,7 +622,7 @@ public final class ActiveServices {
}
mAm.mAppOpsService.startOperation(AppOpsManager.getToken(mAm.mAppOpsService),
AppOpsManager.OP_START_FOREGROUND, r.appInfo.uid, r.packageName, null,
- true, false, null);
+ true, false, null, false);
}
final ServiceMap smap = getServiceMapLocked(r.userId);
@@ -1464,7 +1464,7 @@ public final class ActiveServices {
mAm.mAppOpsService.startOperation(
AppOpsManager.getToken(mAm.mAppOpsService),
AppOpsManager.OP_START_FOREGROUND, r.appInfo.uid, r.packageName,
- null, true, false, "");
+ null, true, false, "", false);
FrameworkStatsLog.write(FrameworkStatsLog.FOREGROUND_SERVICE_STATE_CHANGED,
r.appInfo.uid, r.shortInstanceName,
FrameworkStatsLog.FOREGROUND_SERVICE_STATE_CHANGED__STATE__ENTER,
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 079512275797..157feb30c24d 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -24,8 +24,8 @@ import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
import static android.Manifest.permission.REMOVE_TASKS;
import static android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND;
import static android.app.ActivityManager.INSTR_FLAG_DISABLE_HIDDEN_API_CHECKS;
+import static android.app.ActivityManager.INSTR_FLAG_DISABLE_ISOLATED_STORAGE;
import static android.app.ActivityManager.INSTR_FLAG_DISABLE_TEST_API_CHECKS;
-import static android.app.ActivityManager.INSTR_FLAG_MOUNT_EXTERNAL_STORAGE_FULL;
import static android.app.ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
import static android.app.ActivityManager.PROCESS_STATE_TOP;
@@ -335,7 +335,7 @@ import com.android.internal.util.FastPrintWriter;
import com.android.internal.util.FrameworkStatsLog;
import com.android.internal.util.MemInfoReader;
import com.android.internal.util.Preconditions;
-import com.android.internal.util.function.HexFunction;
+import com.android.internal.util.function.HeptFunction;
import com.android.internal.util.function.QuadFunction;
import com.android.internal.util.function.TriFunction;
import com.android.server.AlarmManagerInternal;
@@ -405,9 +405,7 @@ import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
-import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
@@ -3272,7 +3270,7 @@ public class ActivityManagerService extends IActivityManager.Stub
private boolean hasUsageStatsPermission(String callingPackage) {
final int mode = mAppOpsService.noteOperation(AppOpsManager.OP_GET_USAGE_STATS,
- Binder.getCallingUid(), callingPackage, null, false, "");
+ Binder.getCallingUid(), callingPackage, null, false, "", false);
if (mode == AppOpsManager.MODE_DEFAULT) {
return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
== PackageManager.PERMISSION_GRANTED;
@@ -6100,7 +6098,7 @@ public class ActivityManagerService extends IActivityManager.Stub
// TODO moltmann: Allow to specify featureId
return mActivityManagerService.mAppOpsService
.noteOperation(AppOpsManager.strOpToOp(op), uid, packageName, null,
- false, "");
+ false, "", false);
}
@Override
@@ -15788,9 +15786,10 @@ public class ActivityManagerService extends IActivityManager.Stub
}
if (receivers != null && broadcastWhitelist != null) {
for (int i = receivers.size() - 1; i >= 0; i--) {
- final int uid = receivers.get(i).activityInfo.applicationInfo.uid;
- if (uid >= Process.FIRST_APPLICATION_UID
- && Arrays.binarySearch(broadcastWhitelist, UserHandle.getAppId(uid)) < 0) {
+ final int receiverAppId = UserHandle.getAppId(
+ receivers.get(i).activityInfo.applicationInfo.uid);
+ if (receiverAppId >= Process.FIRST_APPLICATION_UID
+ && Arrays.binarySearch(broadcastWhitelist, receiverAppId) < 0) {
receivers.remove(i);
}
}
@@ -16436,9 +16435,9 @@ public class ActivityManagerService extends IActivityManager.Stub
// if a uid whitelist was provided, remove anything in the application space that wasn't
// in it.
for (int i = registeredReceivers.size() - 1; i >= 0; i--) {
- final int uid = registeredReceivers.get(i).owningUid;
- if (uid >= Process.FIRST_APPLICATION_UID
- && Arrays.binarySearch(broadcastWhitelist, UserHandle.getAppId(uid)) < 0) {
+ final int owningAppId = UserHandle.getAppId(registeredReceivers.get(i).owningUid);
+ if (owningAppId >= Process.FIRST_APPLICATION_UID
+ && Arrays.binarySearch(broadcastWhitelist, owningAppId) < 0) {
registeredReceivers.remove(i);
}
}
@@ -16911,8 +16910,9 @@ public class ActivityManagerService extends IActivityManager.Stub
"disable hidden API checks");
}
+ // TODO(b/158750470): remove
final boolean mountExtStorageFull = isCallerShell()
- && (flags & INSTR_FLAG_MOUNT_EXTERNAL_STORAGE_FULL) != 0;
+ && (flags & INSTR_FLAG_DISABLE_ISOLATED_STORAGE) != 0;
final long origId = Binder.clearCallingIdentity();
// Instrumentation can kill and relaunch even persistent processes
@@ -16934,6 +16934,13 @@ public class ActivityManagerService extends IActivityManager.Stub
if (!mActiveInstrumentation.contains(activeInstr)) {
mActiveInstrumentation.add(activeInstr);
}
+
+ if ((flags & INSTR_FLAG_DISABLE_ISOLATED_STORAGE) != 0) {
+ // Allow OP_NO_ISOLATED_STORAGE app op for the package running instrumentation with
+ // --no-isolated-storage flag.
+ mAppOpsService.setMode(AppOpsManager.OP_NO_ISOLATED_STORAGE, ai.uid,
+ ii.packageName, AppOpsManager.MODE_ALLOWED);
+ }
Binder.restoreCallingIdentity(origId);
}
@@ -17024,6 +17031,9 @@ public class ActivityManagerService extends IActivityManager.Stub
// Can't call out of the system process with a lock held, so post a message.
if (instr.mUiAutomationConnection != null) {
+ // Go back to the default mode of denying OP_NO_ISOLATED_STORAGE app op.
+ mAppOpsService.setMode(AppOpsManager.OP_NO_ISOLATED_STORAGE, app.uid,
+ app.info.packageName, AppOpsManager.MODE_ERRORED);
mAppOpsService.setAppOpsServiceDelegate(null);
getPermissionManagerInternalLocked().setCheckPermissionDelegate(null);
mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
@@ -20131,8 +20141,8 @@ public class ActivityManagerService extends IActivityManager.Stub
private final int mTargetUid;
private @Nullable String[] mPermissions;
- ShellDelegate(String targetPacakgeName, int targetUid, @Nullable String[] permissions) {
- mTargetPackageName = targetPacakgeName;
+ ShellDelegate(String targetPackageName, int targetUid, @Nullable String[] permissions) {
+ mTargetPackageName = targetPackageName;
mTargetUid = targetUid;
mPermissions = permissions;
}
@@ -20179,20 +20189,20 @@ public class ActivityManagerService extends IActivityManager.Stub
@Override
public int noteOperation(int code, int uid, @Nullable String packageName,
@Nullable String featureId, boolean shouldCollectAsyncNotedOp,
- @Nullable String message,
- @NonNull HexFunction<Integer, Integer, String, String, Boolean, String, Integer>
- superImpl) {
+ @Nullable String message, boolean shouldCollectMessage,
+ @NonNull HeptFunction<Integer, Integer, String, String, Boolean, String, Boolean,
+ Integer> superImpl) {
if (uid == mTargetUid && isTargetOp(code)) {
final long identity = Binder.clearCallingIdentity();
try {
return superImpl.apply(code, Process.SHELL_UID, "com.android.shell", featureId,
- shouldCollectAsyncNotedOp, message);
+ shouldCollectAsyncNotedOp, message, shouldCollectMessage);
} finally {
Binder.restoreCallingIdentity(identity);
}
}
return superImpl.apply(code, uid, packageName, featureId, shouldCollectAsyncNotedOp,
- message);
+ message, shouldCollectMessage);
}
@Override
diff --git a/services/core/java/com/android/server/am/ProcessStatsService.java b/services/core/java/com/android/server/am/ProcessStatsService.java
index a0349493edbc..a168af5ad842 100644
--- a/services/core/java/com/android/server/am/ProcessStatsService.java
+++ b/services/core/java/com/android/server/am/ProcessStatsService.java
@@ -1269,12 +1269,12 @@ public final class ProcessStatsService extends IProcessStats.Stub {
* Dump proto for the statsd, mainly for testing.
*/
private void dumpProtoForStatsd(FileDescriptor fd) {
- final ProtoOutputStream proto = new ProtoOutputStream(fd);
+ final ProtoOutputStream[] protos = {new ProtoOutputStream(fd)};
ProcessStats procStats = new ProcessStats(false);
getCommittedStatsMerged(0, 0, true, null, procStats);
- procStats.dumpAggregatedProtoForStatsd(proto);
+ procStats.dumpAggregatedProtoForStatsd(protos, 999999 /* max bytes per shard */);
- proto.flush();
+ protos[0].flush();
}
}
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index f2c4e4428af2..2d8d2c32a4c3 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -348,6 +348,17 @@ class UserController implements Handler.Callback {
@GuardedBy("mUserIdToUserJourneyMap")
private final SparseArray<UserJourneySession> mUserIdToUserJourneyMap = new SparseArray<>();
+ /**
+ * Sets on {@link #setInitialConfig(boolean, int, boolean)}, which is called by
+ * {@code ActivityManager} when the system is started.
+ *
+ * <p>It's useful to ignore external operations (i.e., originated outside {@code system_server},
+ * like from {@code adb shell am switch-user})) that could happen before such call is made and
+ * the system is ready.
+ */
+ @GuardedBy("mLock")
+ private boolean mInitialized;
+
UserController(ActivityManagerService service) {
this(new Injector(service));
}
@@ -372,6 +383,7 @@ class UserController implements Handler.Callback {
mUserSwitchUiEnabled = userSwitchUiEnabled;
mMaxRunningUsers = maxRunningUsers;
mDelayUserDataLocking = delayUserDataLocking;
+ mInitialized = true;
}
}
@@ -1587,6 +1599,11 @@ class UserController implements Handler.Callback {
}
boolean userSwitchUiEnabled;
synchronized (mLock) {
+ if (!mInitialized) {
+ Slog.e(TAG, "Cannot switch to User #" + targetUserId
+ + ": UserController not ready yet");
+ return false;
+ }
mTargetUserId = targetUserId;
userSwitchUiEnabled = mUserSwitchUiEnabled;
}
@@ -2422,6 +2439,7 @@ class UserController implements Handler.Callback {
pw.println(" mDelayUserDataLocking:" + mDelayUserDataLocking);
pw.println(" mMaxRunningUsers:" + mMaxRunningUsers);
pw.println(" mUserSwitchUiEnabled:" + mUserSwitchUiEnabled);
+ pw.println(" mInitialized:" + mInitialized);
}
}
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index 73c98da6aa56..b5c173c91a53 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -1724,12 +1724,12 @@ public class AppOpsService extends IAppOpsService.Stub {
return Zygote.MOUNT_EXTERNAL_NONE;
}
if (noteOperation(AppOpsManager.OP_READ_EXTERNAL_STORAGE, uid,
- packageName, null, true, "External storage policy")
+ packageName, null, true, "External storage policy", true)
!= AppOpsManager.MODE_ALLOWED) {
return Zygote.MOUNT_EXTERNAL_NONE;
}
if (noteOperation(AppOpsManager.OP_WRITE_EXTERNAL_STORAGE, uid,
- packageName, null, true, "External storage policy")
+ packageName, null, true, "External storage policy", true)
!= AppOpsManager.MODE_ALLOWED) {
return Zygote.MOUNT_EXTERNAL_READ;
}
@@ -2955,7 +2955,8 @@ public class AppOpsService extends IAppOpsService.Stub {
@Override
public int noteProxyOperation(int code, int proxiedUid, String proxiedPackageName,
String proxiedAttributionTag, int proxyUid, String proxyPackageName,
- String proxyAttributionTag, boolean shouldCollectAsyncNotedOp, String message) {
+ String proxyAttributionTag, boolean shouldCollectAsyncNotedOp, String message,
+ boolean shouldCollectMessage) {
verifyIncomingUid(proxyUid);
verifyIncomingOp(code);
@@ -2972,7 +2973,7 @@ public class AppOpsService extends IAppOpsService.Stub {
: AppOpsManager.OP_FLAG_UNTRUSTED_PROXY;
final int proxyMode = noteOperationUnchecked(code, proxyUid, resolveProxyPackageName,
proxyAttributionTag, Process.INVALID_UID, null, null, proxyFlags,
- !isProxyTrusted, "proxy " + message);
+ !isProxyTrusted, "proxy " + message, shouldCollectMessage);
if (proxyMode != AppOpsManager.MODE_ALLOWED || Binder.getCallingUid() == proxiedUid) {
return proxyMode;
}
@@ -2985,27 +2986,28 @@ public class AppOpsService extends IAppOpsService.Stub {
: AppOpsManager.OP_FLAG_UNTRUSTED_PROXIED;
return noteOperationUnchecked(code, proxiedUid, resolveProxiedPackageName,
proxiedAttributionTag, proxyUid, resolveProxyPackageName, proxyAttributionTag,
- proxiedFlags, shouldCollectAsyncNotedOp, message);
+ proxiedFlags, shouldCollectAsyncNotedOp, message, shouldCollectMessage);
}
@Override
public int noteOperation(int code, int uid, String packageName, String attributionTag,
- boolean shouldCollectAsyncNotedOp, String message) {
+ boolean shouldCollectAsyncNotedOp, String message, boolean shouldCollectMessage) {
final CheckOpsDelegate delegate;
synchronized (this) {
delegate = mCheckOpsDelegate;
}
if (delegate == null) {
return noteOperationImpl(code, uid, packageName, attributionTag,
- shouldCollectAsyncNotedOp, message);
+ shouldCollectAsyncNotedOp, message, shouldCollectMessage);
}
return delegate.noteOperation(code, uid, packageName, attributionTag,
- shouldCollectAsyncNotedOp, message, AppOpsService.this::noteOperationImpl);
+ shouldCollectAsyncNotedOp, message, shouldCollectMessage,
+ AppOpsService.this::noteOperationImpl);
}
private int noteOperationImpl(int code, int uid, @Nullable String packageName,
@Nullable String attributionTag, boolean shouldCollectAsyncNotedOp,
- @Nullable String message) {
+ @Nullable String message, boolean shouldCollectMessage) {
verifyIncomingUid(uid);
verifyIncomingOp(code);
String resolvedPackageName = resolvePackageName(uid, packageName);
@@ -3014,13 +3016,14 @@ public class AppOpsService extends IAppOpsService.Stub {
}
return noteOperationUnchecked(code, uid, resolvedPackageName, attributionTag,
Process.INVALID_UID, null, null, AppOpsManager.OP_FLAG_SELF,
- shouldCollectAsyncNotedOp, message);
+ shouldCollectAsyncNotedOp, message, shouldCollectMessage);
}
private int noteOperationUnchecked(int code, int uid, @NonNull String packageName,
@Nullable String attributionTag, int proxyUid, String proxyPackageName,
@Nullable String proxyAttributionTag, @OpFlags int flags,
- boolean shouldCollectAsyncNotedOp, @Nullable String message) {
+ boolean shouldCollectAsyncNotedOp, @Nullable String message,
+ boolean shouldCollectMessage) {
RestrictionBypass bypass;
try {
bypass = verifyAndGetBypass(uid, packageName, attributionTag);
@@ -3090,7 +3093,8 @@ public class AppOpsService extends IAppOpsService.Stub {
flags);
if (shouldCollectAsyncNotedOp) {
- collectAsyncNotedOp(uid, packageName, code, attributionTag, message);
+ collectAsyncNotedOp(uid, packageName, code, attributionTag, flags, message,
+ shouldCollectMessage);
}
return AppOpsManager.MODE_ALLOWED;
@@ -3247,7 +3251,8 @@ public class AppOpsService extends IAppOpsService.Stub {
* @param message The message for the op noting
*/
private void collectAsyncNotedOp(int uid, @NonNull String packageName, int opCode,
- @Nullable String attributionTag, @NonNull String message) {
+ @Nullable String attributionTag, @OpFlags int flags, @NonNull String message,
+ boolean shouldCollectMessage) {
Objects.requireNonNull(message);
int callingUid = Binder.getCallingUid();
@@ -3262,8 +3267,11 @@ public class AppOpsService extends IAppOpsService.Stub {
attributionTag, message, System.currentTimeMillis());
final boolean[] wasNoteForwarded = {false};
- reportRuntimeAppOpAccessMessageAsyncLocked(uid, packageName, opCode, attributionTag,
- message);
+ if ((flags & (OP_FLAG_SELF | OP_FLAG_TRUSTED_PROXIED)) != 0
+ && shouldCollectMessage) {
+ reportRuntimeAppOpAccessMessageAsyncLocked(uid, packageName, opCode,
+ attributionTag, message);
+ }
if (callbacks != null) {
callbacks.broadcast((cb) -> {
@@ -3376,7 +3384,7 @@ public class AppOpsService extends IAppOpsService.Stub {
@Override
public int startOperation(IBinder clientId, int code, int uid, String packageName,
String attributionTag, boolean startIfModeDefault, boolean shouldCollectAsyncNotedOp,
- String message) {
+ String message, boolean shouldCollectMessage) {
verifyIncomingUid(uid);
verifyIncomingOp(code);
String resolvedPackageName = resolvePackageName(uid, packageName);
@@ -3447,7 +3455,8 @@ public class AppOpsService extends IAppOpsService.Stub {
}
if (shouldCollectAsyncNotedOp) {
- collectAsyncNotedOp(uid, packageName, code, attributionTag, message);
+ collectAsyncNotedOp(uid, packageName, code, attributionTag, AppOpsManager.OP_FLAG_SELF,
+ message, shouldCollectMessage);
}
return AppOpsManager.MODE_ALLOWED;
@@ -3735,7 +3744,7 @@ public class AppOpsService extends IAppOpsService.Stub {
mHandler.sendMessage(PooledLambda.obtainMessage(
AppOpsService::notifyOpChangedForAllPkgsInUid,
this, code, uidState.uid, true, null));
- } else {
+ } else if (uidState.pkgOps != null) {
final ArraySet<ModeCallback> callbacks = mOpModeWatchers.get(code);
if (callbacks != null) {
for (int cbi = callbacks.size() - 1; cbi >= 0; cbi--) {
@@ -4910,7 +4919,7 @@ public class AppOpsService extends IAppOpsService.Stub {
if (shell.packageName != null) {
shell.mInterface.startOperation(shell.mToken, shell.op, shell.packageUid,
shell.packageName, shell.attributionTag, true, true,
- "appops start shell command");
+ "appops start shell command", true);
} else {
return -1;
}
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 36272278e0e4..f8ab6f4a8b54 100755
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -413,6 +413,13 @@ public class AudioService extends IAudioService.Stub
AppOpsManager.OP_AUDIO_MEDIA_VOLUME // STREAM_ASSISTANT
};
+ private static Set<Integer> sDeviceVolumeBehaviorSupportedDeviceOutSet = new HashSet<>(
+ Arrays.asList(
+ AudioSystem.DEVICE_OUT_HDMI,
+ AudioSystem.DEVICE_OUT_HDMI_ARC,
+ AudioSystem.DEVICE_OUT_SPDIF,
+ AudioSystem.DEVICE_OUT_LINE));
+
private final boolean mUseFixedVolume;
/**
@@ -525,7 +532,6 @@ public class AudioService extends IAudioService.Stub
// Devices for which the volume is fixed (volume is either max or muted)
Set<Integer> mFixedVolumeDevices = new HashSet<>(Arrays.asList(
- AudioSystem.DEVICE_OUT_HDMI,
AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET,
AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET,
AudioSystem.DEVICE_OUT_HDMI_ARC,
@@ -920,6 +926,8 @@ public class AudioService extends IAudioService.Stub
if (mHdmiManager != null) {
mHdmiManager.addHdmiControlStatusChangeListener(
mHdmiControlStatusChangeListenerCallback);
+ mHdmiManager.addHdmiCecVolumeControlFeatureListener(mContext.getMainExecutor(),
+ mMyHdmiCecVolumeControlFeatureListener);
}
mHdmiTvClient = mHdmiManager.getTvClient();
if (mHdmiTvClient != null) {
@@ -927,11 +935,6 @@ public class AudioService extends IAudioService.Stub
AudioSystem.DEVICE_ALL_HDMI_SYSTEM_AUDIO_AND_SPEAKER_SET);
}
mHdmiPlaybackClient = mHdmiManager.getPlaybackClient();
- if (mHdmiPlaybackClient != null) {
- // not a television: HDMI output will be always at max
- mFixedVolumeDevices.remove(AudioSystem.DEVICE_OUT_HDMI);
- mFullVolumeDevices.add(AudioSystem.DEVICE_OUT_HDMI);
- }
mHdmiAudioSystemClient = mHdmiManager.getAudioSystemClient();
}
}
@@ -2248,6 +2251,7 @@ public class AudioService extends IAudioService.Stub
if (mHdmiManager != null) {
// mHdmiCecSink true => mHdmiPlaybackClient != null
if (mHdmiCecSink
+ && mHdmiCecVolumeControlEnabled
&& streamTypeAlias == AudioSystem.STREAM_MUSIC
// vol change on a full volume device
&& isFullVolumeDevice(device)) {
@@ -2320,7 +2324,8 @@ public class AudioService extends IAudioService.Stub
@GuardedBy("mHdmiClientLock")
private void maybeSendSystemAudioStatusCommand(boolean isMuteAdjust) {
if (mHdmiAudioSystemClient == null
- || !mHdmiSystemAudioSupported) {
+ || !mHdmiSystemAudioSupported
+ || !mHdmiCecVolumeControlEnabled) {
return;
}
@@ -2340,7 +2345,8 @@ public class AudioService extends IAudioService.Stub
|| mHdmiTvClient == null
|| oldVolume == newVolume
|| (flags & AudioManager.FLAG_HDMI_SYSTEM_AUDIO_VOLUME) != 0
- || !mHdmiSystemAudioSupported) {
+ || !mHdmiSystemAudioSupported
+ || !mHdmiCecVolumeControlEnabled) {
return;
}
final long token = Binder.clearCallingIdentity();
@@ -2940,16 +2946,18 @@ public class AudioService extends IAudioService.Stub
mVolumeController.postVolumeChanged(streamType, flags);
}
- // If Hdmi-CEC system audio mode is on and we are a TV panel, never show volume bar.
+ // Don't show volume UI when:
+ // - Hdmi-CEC system audio mode is on and we are a TV panel
+ // - CEC volume control enabled on a set-top box
private int updateFlagsForTvPlatform(int flags) {
synchronized (mHdmiClientLock) {
- if (mHdmiTvClient != null && mHdmiSystemAudioSupported) {
+ if ((mHdmiTvClient != null && mHdmiSystemAudioSupported && mHdmiCecVolumeControlEnabled)
+ || (mHdmiPlaybackClient != null && mHdmiCecVolumeControlEnabled)) {
flags &= ~AudioManager.FLAG_SHOW_UI;
}
}
return flags;
}
-
// UI update and Broadcast Intent
private void sendMasterMuteUpdate(boolean muted, int flags) {
mVolumeController.postMasterMuteChanged(updateFlagsForTvPlatform(flags));
@@ -4042,6 +4050,11 @@ public class AudioService extends IAudioService.Stub
}
readVolumeGroupsSettings();
+
+ if (DEBUG_VOL) {
+ Log.d(TAG, "Restoring device volume behavior");
+ }
+ restoreDeviceVolumeBehavior();
}
/** @see AudioManager#setSpeakerphoneOn(boolean) */
@@ -4901,50 +4914,47 @@ public class AudioService extends IAudioService.Stub
if (pkgName == null) {
pkgName = "";
}
- // translate Java device type to native device type (for the devices masks for full / fixed)
- final int type;
- switch (device.getType()) {
- case AudioDeviceInfo.TYPE_HDMI:
- type = AudioSystem.DEVICE_OUT_HDMI;
- break;
- case AudioDeviceInfo.TYPE_HDMI_ARC:
- type = AudioSystem.DEVICE_OUT_HDMI_ARC;
- break;
- case AudioDeviceInfo.TYPE_LINE_DIGITAL:
- type = AudioSystem.DEVICE_OUT_SPDIF;
- break;
- case AudioDeviceInfo.TYPE_AUX_LINE:
- type = AudioSystem.DEVICE_OUT_LINE;
- break;
- default:
- // unsupported for now
- throw new IllegalArgumentException("Unsupported device type " + device.getType());
+
+ int audioSystemDeviceOut = AudioDeviceInfo.convertDeviceTypeToInternalDevice(
+ device.getType());
+ setDeviceVolumeBehaviorInternal(audioSystemDeviceOut, deviceVolumeBehavior, pkgName);
+
+ persistDeviceVolumeBehavior(audioSystemDeviceOut, deviceVolumeBehavior);
+ }
+
+ private void setDeviceVolumeBehaviorInternal(int audioSystemDeviceOut,
+ @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior, @NonNull String caller) {
+ if (!sDeviceVolumeBehaviorSupportedDeviceOutSet.contains(audioSystemDeviceOut)) {
+ // unsupported for now
+ throw new IllegalArgumentException("Unsupported device type " + audioSystemDeviceOut);
}
+
// update device masks based on volume behavior
switch (deviceVolumeBehavior) {
case AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE:
- mFullVolumeDevices.remove(type);
- mFixedVolumeDevices.remove(type);
+ removeAudioSystemDeviceOutFromFullVolumeDevices(audioSystemDeviceOut);
+ removeAudioSystemDeviceOutFromFixedVolumeDevices(audioSystemDeviceOut);
break;
case AudioManager.DEVICE_VOLUME_BEHAVIOR_FIXED:
- mFullVolumeDevices.remove(type);
- mFixedVolumeDevices.add(type);
+ removeAudioSystemDeviceOutFromFullVolumeDevices(audioSystemDeviceOut);
+ addAudioSystemDeviceOutToFixedVolumeDevices(audioSystemDeviceOut);
break;
case AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL:
- mFullVolumeDevices.add(type);
- mFixedVolumeDevices.remove(type);
+ addAudioSystemDeviceOutToFullVolumeDevices(audioSystemDeviceOut);
+ removeAudioSystemDeviceOutFromFixedVolumeDevices(audioSystemDeviceOut);
break;
case AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE:
case AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE:
throw new IllegalArgumentException("Absolute volume unsupported for now");
}
+
// log event and caller
sDeviceLogger.log(new AudioEventLogger.StringEvent(
- "Volume behavior " + deviceVolumeBehavior
- + " for dev=0x" + Integer.toHexString(type) + " by pkg:" + pkgName));
+ "Volume behavior " + deviceVolumeBehavior + " for dev=0x"
+ + Integer.toHexString(audioSystemDeviceOut) + " from:" + caller));
// make sure we have a volume entry for this device, and that volume is updated according
// to volume behavior
- checkAddAllFixedVolumeDevices(type, "setDeviceVolumeBehavior:" + pkgName);
+ checkAddAllFixedVolumeDevices(audioSystemDeviceOut, "setDeviceVolumeBehavior:" + caller);
}
/**
@@ -4952,45 +4962,38 @@ public class AudioService extends IAudioService.Stub
* @param device the audio output device type
* @return the volume behavior for the device
*/
- public @AudioManager.DeviceVolumeBehavior int getDeviceVolumeBehavior(
+ public @AudioManager.DeviceVolumeBehaviorState int getDeviceVolumeBehavior(
@NonNull AudioDeviceAttributes device) {
// verify permissions
enforceModifyAudioRoutingPermission();
+
// translate Java device type to native device type (for the devices masks for full / fixed)
- final int type;
- switch (device.getType()) {
- case AudioDeviceInfo.TYPE_HEARING_AID:
- type = AudioSystem.DEVICE_OUT_HEARING_AID;
- break;
- case AudioDeviceInfo.TYPE_BLUETOOTH_A2DP:
- type = AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP;
- break;
- case AudioDeviceInfo.TYPE_HDMI:
- type = AudioSystem.DEVICE_OUT_HDMI;
- break;
- case AudioDeviceInfo.TYPE_HDMI_ARC:
- type = AudioSystem.DEVICE_OUT_HDMI_ARC;
- break;
- case AudioDeviceInfo.TYPE_LINE_DIGITAL:
- type = AudioSystem.DEVICE_OUT_SPDIF;
- break;
- case AudioDeviceInfo.TYPE_AUX_LINE:
- type = AudioSystem.DEVICE_OUT_LINE;
- break;
- default:
- // unsupported for now
- throw new IllegalArgumentException("Unsupported device type " + device.getType());
+ final int audioSystemDeviceOut = AudioDeviceInfo.convertDeviceTypeToInternalDevice(
+ device.getType());
+ if (!sDeviceVolumeBehaviorSupportedDeviceOutSet.contains(audioSystemDeviceOut)
+ && audioSystemDeviceOut != AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP
+ && audioSystemDeviceOut != AudioSystem.DEVICE_OUT_HEARING_AID) {
+ throw new IllegalArgumentException("Unsupported volume behavior "
+ + audioSystemDeviceOut);
+ }
+
+ int setDeviceVolumeBehavior = retrieveStoredDeviceVolumeBehavior(audioSystemDeviceOut);
+ if (setDeviceVolumeBehavior != AudioManager.DEVICE_VOLUME_BEHAVIOR_UNSET) {
+ return setDeviceVolumeBehavior;
}
- if ((mFullVolumeDevices.contains(type))) {
+
+ // setDeviceVolumeBehavior has not been explicitly called for the device type. Deduce the
+ // current volume behavior.
+ if ((mFullVolumeDevices.contains(audioSystemDeviceOut))) {
return AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL;
}
- if ((mFixedVolumeDevices.contains(type))) {
+ if ((mFixedVolumeDevices.contains(audioSystemDeviceOut))) {
return AudioManager.DEVICE_VOLUME_BEHAVIOR_FIXED;
}
- if ((mAbsVolumeMultiModeCaseDevices.contains(type))) {
+ if ((mAbsVolumeMultiModeCaseDevices.contains(audioSystemDeviceOut))) {
return AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE;
}
- if (type == AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP
+ if (audioSystemDeviceOut == AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP
&& mDeviceBroker.isAvrcpAbsoluteVolumeSupported()) {
return AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE;
}
@@ -7113,18 +7116,20 @@ public class AudioService extends IAudioService.Stub
@GuardedBy("mHdmiClientLock")
private void updateHdmiCecSinkLocked(boolean hdmiCecSink) {
mHdmiCecSink = hdmiCecSink;
- if (mHdmiCecSink) {
- if (DEBUG_VOL) {
- Log.d(TAG, "CEC sink: setting HDMI as full vol device");
- }
- mFullVolumeDevices.add(AudioSystem.DEVICE_OUT_HDMI);
- } else {
- if (DEBUG_VOL) {
- Log.d(TAG, "TV, no CEC: setting HDMI as regular vol device");
+ if (!hasDeviceVolumeBehavior(AudioSystem.DEVICE_OUT_HDMI)) {
+ if (mHdmiCecSink) {
+ if (DEBUG_VOL) {
+ Log.d(TAG, "CEC sink: setting HDMI as full vol device");
+ }
+ addAudioSystemDeviceOutToFullVolumeDevices(AudioSystem.DEVICE_OUT_HDMI);
+ } else {
+ if (DEBUG_VOL) {
+ Log.d(TAG, "TV, no CEC: setting HDMI as regular vol device");
+ }
+ // Android TV devices without CEC service apply software volume on
+ // HDMI output
+ removeAudioSystemDeviceOutFromFullVolumeDevices(AudioSystem.DEVICE_OUT_HDMI);
}
- // Android TV devices without CEC service apply software volume on
- // HDMI output
- mFullVolumeDevices.remove(AudioSystem.DEVICE_OUT_HDMI);
}
checkAddAllFixedVolumeDevices(AudioSystem.DEVICE_OUT_HDMI,
@@ -7141,9 +7146,21 @@ public class AudioService extends IAudioService.Stub
}
};
+ private class MyHdmiCecVolumeControlFeatureListener
+ implements HdmiControlManager.HdmiCecVolumeControlFeatureListener {
+ public void onHdmiCecVolumeControlFeature(boolean enabled) {
+ synchronized (mHdmiClientLock) {
+ if (mHdmiManager == null) return;
+ mHdmiCecVolumeControlEnabled = enabled;
+ }
+ }
+ };
+
private final Object mHdmiClientLock = new Object();
// If HDMI-CEC system audio is supported
+ // Note that for CEC volume commands mHdmiCecVolumeControlEnabled will play a role on volume
+ // commands
private boolean mHdmiSystemAudioSupported = false;
// Set only when device is tv.
@GuardedBy("mHdmiClientLock")
@@ -7161,10 +7178,16 @@ public class AudioService extends IAudioService.Stub
// Set only when device is an audio system.
@GuardedBy("mHdmiClientLock")
private HdmiAudioSystemClient mHdmiAudioSystemClient;
+ // True when volume control over HDMI CEC is used when CEC is enabled (meaningless otherwise)
+ @GuardedBy("mHdmiClientLock")
+ private boolean mHdmiCecVolumeControlEnabled;
private MyHdmiControlStatusChangeListenerCallback mHdmiControlStatusChangeListenerCallback =
new MyHdmiControlStatusChangeListenerCallback();
+ private MyHdmiCecVolumeControlFeatureListener mMyHdmiCecVolumeControlFeatureListener =
+ new MyHdmiCecVolumeControlFeatureListener();
+
@Override
public int setHdmiSystemAudioSupported(boolean on) {
int device = AudioSystem.DEVICE_NONE;
@@ -7403,6 +7426,7 @@ public class AudioService extends IAudioService.Stub
pw.print(" mHdmiPlaybackClient="); pw.println(mHdmiPlaybackClient);
pw.print(" mHdmiTvClient="); pw.println(mHdmiTvClient);
pw.print(" mHdmiSystemAudioSupported="); pw.println(mHdmiSystemAudioSupported);
+ pw.print(" mHdmiCecVolumeControlEnabled="); pw.println(mHdmiCecVolumeControlEnabled);
pw.print(" mIsCallScreeningModeSupported="); pw.println(mIsCallScreeningModeSupported);
pw.print(" mic mute FromSwitch=" + mMicMuteFromSwitch
+ " FromRestrictions=" + mMicMuteFromRestrictions
@@ -8944,4 +8968,91 @@ public class AudioService extends IAudioService.Stub
}
return mFullVolumeDevices.contains(deviceType);
}
+
+ //====================
+ // Helper functions for {set,get}DeviceVolumeBehavior
+ //====================
+ private static String getSettingsNameForDeviceVolumeBehavior(int deviceType) {
+ return "AudioService_DeviceVolumeBehavior_" + AudioSystem.getOutputDeviceName(deviceType);
+ }
+
+ private void persistDeviceVolumeBehavior(int deviceType,
+ @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior) {
+ if (DEBUG_VOL) {
+ Log.d(TAG, "Persisting Volume Behavior for DeviceType: " + deviceType);
+ }
+ System.putIntForUser(mContentResolver,
+ getSettingsNameForDeviceVolumeBehavior(deviceType),
+ deviceVolumeBehavior,
+ UserHandle.USER_CURRENT);
+ }
+
+ @AudioManager.DeviceVolumeBehaviorState
+ private int retrieveStoredDeviceVolumeBehavior(int deviceType) {
+ return System.getIntForUser(mContentResolver,
+ getSettingsNameForDeviceVolumeBehavior(deviceType),
+ AudioManager.DEVICE_VOLUME_BEHAVIOR_UNSET,
+ UserHandle.USER_CURRENT);
+ }
+
+ private void restoreDeviceVolumeBehavior() {
+ for (int deviceType : sDeviceVolumeBehaviorSupportedDeviceOutSet) {
+ if (DEBUG_VOL) {
+ Log.d(TAG, "Retrieving Volume Behavior for DeviceType: " + deviceType);
+ }
+ int deviceVolumeBehavior = retrieveStoredDeviceVolumeBehavior(deviceType);
+ if (deviceVolumeBehavior == AudioManager.DEVICE_VOLUME_BEHAVIOR_UNSET) {
+ if (DEBUG_VOL) {
+ Log.d(TAG, "Skipping Setting Volume Behavior for DeviceType: " + deviceType);
+ }
+ continue;
+ }
+
+ setDeviceVolumeBehaviorInternal(deviceType, deviceVolumeBehavior,
+ "AudioService.restoreDeviceVolumeBehavior()");
+ }
+ }
+
+ /**
+ * @param audioSystemDeviceOut one of AudioSystem.DEVICE_OUT_*
+ * @return whether {@code audioSystemDeviceOut} has previously been set to a specific volume
+ * behavior
+ */
+ private boolean hasDeviceVolumeBehavior(
+ int audioSystemDeviceOut) {
+ return retrieveStoredDeviceVolumeBehavior(audioSystemDeviceOut)
+ != AudioManager.DEVICE_VOLUME_BEHAVIOR_UNSET;
+ }
+
+ private void addAudioSystemDeviceOutToFixedVolumeDevices(int audioSystemDeviceOut) {
+ if (DEBUG_VOL) {
+ Log.d(TAG, "Adding DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut)
+ + " to mFixedVolumeDevices");
+ }
+ mFixedVolumeDevices.add(audioSystemDeviceOut);
+ }
+
+ private void removeAudioSystemDeviceOutFromFixedVolumeDevices(int audioSystemDeviceOut) {
+ if (DEBUG_VOL) {
+ Log.d(TAG, "Removing DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut)
+ + " from mFixedVolumeDevices");
+ }
+ mFixedVolumeDevices.remove(audioSystemDeviceOut);
+ }
+
+ private void addAudioSystemDeviceOutToFullVolumeDevices(int audioSystemDeviceOut) {
+ if (DEBUG_VOL) {
+ Log.d(TAG, "Adding DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut)
+ + " to mFullVolumeDevices");
+ }
+ mFullVolumeDevices.add(audioSystemDeviceOut);
+ }
+
+ private void removeAudioSystemDeviceOutFromFullVolumeDevices(int audioSystemDeviceOut) {
+ if (DEBUG_VOL) {
+ Log.d(TAG, "Removing DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut)
+ + " from mFullVolumeDevices");
+ }
+ mFullVolumeDevices.remove(audioSystemDeviceOut);
+ }
}
diff --git a/services/core/java/com/android/server/connectivity/DnsManager.java b/services/core/java/com/android/server/connectivity/DnsManager.java
index 506c8e39194b..cf6a7f6e8d70 100644
--- a/services/core/java/com/android/server/connectivity/DnsManager.java
+++ b/services/core/java/com/android/server/connectivity/DnsManager.java
@@ -57,6 +57,7 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
@@ -64,7 +65,9 @@ import java.util.stream.Collectors;
* Encapsulate the management of DNS settings for networks.
*
* This class it NOT designed for concurrent access. Furthermore, all non-static
- * methods MUST be called from ConnectivityService's thread.
+ * methods MUST be called from ConnectivityService's thread. However, an exceptional
+ * case is getPrivateDnsConfig(Network) which is exclusively for
+ * ConnectivityService#dumpNetworkDiagnostics() on a random binder thread.
*
* [ Private DNS ]
* The code handling Private DNS is spread across several components, but this
@@ -236,8 +239,8 @@ public class DnsManager {
private final ContentResolver mContentResolver;
private final IDnsResolver mDnsResolver;
private final MockableSystemProperties mSystemProperties;
- // TODO: Replace these Maps with SparseArrays.
- private final Map<Integer, PrivateDnsConfig> mPrivateDnsMap;
+ private final ConcurrentHashMap<Integer, PrivateDnsConfig> mPrivateDnsMap;
+ // TODO: Replace the Map with SparseArrays.
private final Map<Integer, PrivateDnsValidationStatuses> mPrivateDnsValidationMap;
private final Map<Integer, LinkProperties> mLinkPropertiesMap;
private final Map<Integer, int[]> mTransportsMap;
@@ -247,15 +250,13 @@ public class DnsManager {
private int mSuccessThreshold;
private int mMinSamples;
private int mMaxSamples;
- private String mPrivateDnsMode;
- private String mPrivateDnsSpecifier;
public DnsManager(Context ctx, IDnsResolver dnsResolver, MockableSystemProperties sp) {
mContext = ctx;
mContentResolver = mContext.getContentResolver();
mDnsResolver = dnsResolver;
mSystemProperties = sp;
- mPrivateDnsMap = new HashMap<>();
+ mPrivateDnsMap = new ConcurrentHashMap<>();
mPrivateDnsValidationMap = new HashMap<>();
mLinkPropertiesMap = new HashMap<>();
mTransportsMap = new HashMap<>();
@@ -275,6 +276,12 @@ public class DnsManager {
mLinkPropertiesMap.remove(network.netId);
}
+ // This is exclusively called by ConnectivityService#dumpNetworkDiagnostics() which
+ // is not on the ConnectivityService handler thread.
+ public PrivateDnsConfig getPrivateDnsConfig(@NonNull Network network) {
+ return mPrivateDnsMap.getOrDefault(network.netId, PRIVATE_DNS_OFF);
+ }
+
public PrivateDnsConfig updatePrivateDns(Network network, PrivateDnsConfig cfg) {
Slog.w(TAG, "updatePrivateDns(" + network + ", " + cfg + ")");
return (cfg != null)
diff --git a/services/core/java/com/android/server/connectivity/NetworkDiagnostics.java b/services/core/java/com/android/server/connectivity/NetworkDiagnostics.java
index a1a8e355dcec..49c16ad96eb7 100644
--- a/services/core/java/com/android/server/connectivity/NetworkDiagnostics.java
+++ b/services/core/java/com/android/server/connectivity/NetworkDiagnostics.java
@@ -18,12 +18,15 @@ package com.android.server.connectivity;
import static android.system.OsConstants.*;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.net.LinkAddress;
import android.net.LinkProperties;
import android.net.Network;
import android.net.NetworkUtils;
import android.net.RouteInfo;
import android.net.TrafficStats;
+import android.net.shared.PrivateDnsConfig;
import android.net.util.NetworkConstants;
import android.os.SystemClock;
import android.system.ErrnoException;
@@ -38,6 +41,8 @@ import com.android.internal.util.TrafficStatsConstants;
import libcore.io.IoUtils;
import java.io.Closeable;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.InterruptedIOException;
@@ -52,6 +57,7 @@ import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -59,6 +65,12 @@ import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
+import javax.net.ssl.SNIHostName;
+import javax.net.ssl.SNIServerName;
+import javax.net.ssl.SSLParameters;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+
/**
* NetworkDiagnostics
*
@@ -100,6 +112,7 @@ public class NetworkDiagnostics {
private final Network mNetwork;
private final LinkProperties mLinkProperties;
+ private final PrivateDnsConfig mPrivateDnsCfg;
private final Integer mInterfaceIndex;
private final long mTimeoutMs;
@@ -163,12 +176,15 @@ public class NetworkDiagnostics {
private final Map<Pair<InetAddress, InetAddress>, Measurement> mExplicitSourceIcmpChecks =
new HashMap<>();
private final Map<InetAddress, Measurement> mDnsUdpChecks = new HashMap<>();
+ private final Map<InetAddress, Measurement> mDnsTlsChecks = new HashMap<>();
private final String mDescription;
- public NetworkDiagnostics(Network network, LinkProperties lp, long timeoutMs) {
+ public NetworkDiagnostics(Network network, LinkProperties lp,
+ @NonNull PrivateDnsConfig privateDnsCfg, long timeoutMs) {
mNetwork = network;
mLinkProperties = lp;
+ mPrivateDnsCfg = privateDnsCfg;
mInterfaceIndex = getInterfaceIndex(mLinkProperties.getInterfaceName());
mTimeoutMs = timeoutMs;
mStartTime = now();
@@ -199,8 +215,22 @@ public class NetworkDiagnostics {
}
}
for (InetAddress nameserver : mLinkProperties.getDnsServers()) {
- prepareIcmpMeasurement(nameserver);
- prepareDnsMeasurement(nameserver);
+ prepareIcmpMeasurement(nameserver);
+ prepareDnsMeasurement(nameserver);
+
+ // Unlike the DnsResolver which doesn't do certificate validation in opportunistic mode,
+ // DoT probes to the DNS servers will fail if certificate validation fails.
+ prepareDnsTlsMeasurement(null /* hostname */, nameserver);
+ }
+
+ for (InetAddress tlsNameserver : mPrivateDnsCfg.ips) {
+ // Reachability check is necessary since when resolving the strict mode hostname,
+ // NetworkMonitor always queries for both A and AAAA records, even if the network
+ // is IPv4-only or IPv6-only.
+ if (mLinkProperties.isReachable(tlsNameserver)) {
+ // If there are IPs, there must have been a name that resolved to them.
+ prepareDnsTlsMeasurement(mPrivateDnsCfg.hostname, tlsNameserver);
+ }
}
mCountDownLatch = new CountDownLatch(totalMeasurementCount());
@@ -222,6 +252,15 @@ public class NetworkDiagnostics {
}
}
+ private static String socketAddressToString(@NonNull SocketAddress sockAddr) {
+ // The default toString() implementation is not the prettiest.
+ InetSocketAddress inetSockAddr = (InetSocketAddress) sockAddr;
+ InetAddress localAddr = inetSockAddr.getAddress();
+ return String.format(
+ (localAddr instanceof Inet6Address ? "[%s]:%d" : "%s:%d"),
+ localAddr.getHostAddress(), inetSockAddr.getPort());
+ }
+
private void prepareIcmpMeasurement(InetAddress target) {
if (!mIcmpChecks.containsKey(target)) {
Measurement measurement = new Measurement();
@@ -252,8 +291,19 @@ public class NetworkDiagnostics {
}
}
+ private void prepareDnsTlsMeasurement(@Nullable String hostname, @NonNull InetAddress target) {
+ // This might overwrite an existing entry in mDnsTlsChecks, because |target| can be an IP
+ // address configured by the network as well as an IP address learned by resolving the
+ // strict mode DNS hostname. If the entry is overwritten, the overwritten measurement
+ // thread will not execute.
+ Measurement measurement = new Measurement();
+ measurement.thread = new Thread(new DnsTlsCheck(hostname, target, measurement));
+ mDnsTlsChecks.put(target, measurement);
+ }
+
private int totalMeasurementCount() {
- return mIcmpChecks.size() + mExplicitSourceIcmpChecks.size() + mDnsUdpChecks.size();
+ return mIcmpChecks.size() + mExplicitSourceIcmpChecks.size() + mDnsUdpChecks.size()
+ + mDnsTlsChecks.size();
}
private void startMeasurements() {
@@ -266,6 +316,9 @@ public class NetworkDiagnostics {
for (Measurement measurement : mDnsUdpChecks.values()) {
measurement.thread.start();
}
+ for (Measurement measurement : mDnsTlsChecks.values()) {
+ measurement.thread.start();
+ }
}
public void waitForMeasurements() {
@@ -297,6 +350,11 @@ public class NetworkDiagnostics {
measurements.add(entry.getValue());
}
}
+ for (Map.Entry<InetAddress, Measurement> entry : mDnsTlsChecks.entrySet()) {
+ if (entry.getKey() instanceof Inet4Address) {
+ measurements.add(entry.getValue());
+ }
+ }
// IPv6 measurements second.
for (Map.Entry<InetAddress, Measurement> entry : mIcmpChecks.entrySet()) {
@@ -315,6 +373,11 @@ public class NetworkDiagnostics {
measurements.add(entry.getValue());
}
}
+ for (Map.Entry<InetAddress, Measurement> entry : mDnsTlsChecks.entrySet()) {
+ if (entry.getKey() instanceof Inet6Address) {
+ measurements.add(entry.getValue());
+ }
+ }
return measurements;
}
@@ -387,6 +450,8 @@ public class NetworkDiagnostics {
try {
mFileDescriptor = Os.socket(mAddressFamily, sockType, protocol);
} finally {
+ // TODO: The tag should remain set until all traffic is sent and received.
+ // Consider tagging the socket after the measurement thread is started.
TrafficStats.setThreadStatsTag(oldTag);
}
// Setting SNDTIMEO is purely for defensive purposes.
@@ -403,13 +468,12 @@ public class NetworkDiagnostics {
mSocketAddress = Os.getsockname(mFileDescriptor);
}
- protected String getSocketAddressString() {
- // The default toString() implementation is not the prettiest.
- InetSocketAddress inetSockAddr = (InetSocketAddress) mSocketAddress;
- InetAddress localAddr = inetSockAddr.getAddress();
- return String.format(
- (localAddr instanceof Inet6Address ? "[%s]:%d" : "%s:%d"),
- localAddr.getHostAddress(), inetSockAddr.getPort());
+ protected boolean ensureMeasurementNecessary() {
+ if (mMeasurement.finishTime == 0) return false;
+
+ // Countdown latch was not decremented when the measurement failed during setup.
+ mCountDownLatch.countDown();
+ return true;
}
@Override
@@ -448,13 +512,7 @@ public class NetworkDiagnostics {
@Override
public void run() {
- // Check if this measurement has already failed during setup.
- if (mMeasurement.finishTime > 0) {
- // If the measurement failed during construction it didn't
- // decrement the countdown latch; do so here.
- mCountDownLatch.countDown();
- return;
- }
+ if (ensureMeasurementNecessary()) return;
try {
setupSocket(SOCK_DGRAM, mProtocol, TIMEOUT_SEND, TIMEOUT_RECV, 0);
@@ -462,7 +520,7 @@ public class NetworkDiagnostics {
mMeasurement.recordFailure(e.toString());
return;
}
- mMeasurement.description += " src{" + getSocketAddressString() + "}";
+ mMeasurement.description += " src{" + socketAddressToString(mSocketAddress) + "}";
// Build a trivial ICMP packet.
final byte[] icmpPacket = {
@@ -507,10 +565,10 @@ public class NetworkDiagnostics {
private static final int RR_TYPE_AAAA = 28;
private static final int PACKET_BUFSIZE = 512;
- private final Random mRandom = new Random();
+ protected final Random mRandom = new Random();
// Should be static, but the compiler mocks our puny, human attempts at reason.
- private String responseCodeStr(int rcode) {
+ protected String responseCodeStr(int rcode) {
try {
return DnsResponseCode.values()[rcode].toString();
} catch (IndexOutOfBoundsException e) {
@@ -518,7 +576,7 @@ public class NetworkDiagnostics {
}
}
- private final int mQueryType;
+ protected final int mQueryType;
public DnsUdpCheck(InetAddress target, Measurement measurement) {
super(target, measurement);
@@ -535,13 +593,7 @@ public class NetworkDiagnostics {
@Override
public void run() {
- // Check if this measurement has already failed during setup.
- if (mMeasurement.finishTime > 0) {
- // If the measurement failed during construction it didn't
- // decrement the countdown latch; do so here.
- mCountDownLatch.countDown();
- return;
- }
+ if (ensureMeasurementNecessary()) return;
try {
setupSocket(SOCK_DGRAM, IPPROTO_UDP, TIMEOUT_SEND, TIMEOUT_RECV,
@@ -550,12 +602,10 @@ public class NetworkDiagnostics {
mMeasurement.recordFailure(e.toString());
return;
}
- mMeasurement.description += " src{" + getSocketAddressString() + "}";
// This needs to be fixed length so it can be dropped into the pre-canned packet.
final String sixRandomDigits = String.valueOf(mRandom.nextInt(900000) + 100000);
- mMeasurement.description += " qtype{" + mQueryType + "}"
- + " qname{" + sixRandomDigits + "-android-ds.metric.gstatic.com}";
+ appendDnsToMeasurementDescription(sixRandomDigits, mSocketAddress);
// Build a trivial DNS packet.
final byte[] dnsPacket = getDnsQueryPacket(sixRandomDigits);
@@ -592,7 +642,7 @@ public class NetworkDiagnostics {
close();
}
- private byte[] getDnsQueryPacket(String sixRandomDigits) {
+ protected byte[] getDnsQueryPacket(String sixRandomDigits) {
byte[] rnd = sixRandomDigits.getBytes(StandardCharsets.US_ASCII);
return new byte[] {
(byte) mRandom.nextInt(), (byte) mRandom.nextInt(), // [0-1] query ID
@@ -611,5 +661,97 @@ public class NetworkDiagnostics {
0, 1 // QCLASS, set to 1 = IN (Internet)
};
}
+
+ protected void appendDnsToMeasurementDescription(
+ String sixRandomDigits, SocketAddress sockAddr) {
+ mMeasurement.description += " src{" + socketAddressToString(sockAddr) + "}"
+ + " qtype{" + mQueryType + "}"
+ + " qname{" + sixRandomDigits + "-android-ds.metric.gstatic.com}";
+ }
+ }
+
+ // TODO: Have it inherited from SimpleSocketCheck, and separate common DNS helpers out of
+ // DnsUdpCheck.
+ private class DnsTlsCheck extends DnsUdpCheck {
+ private static final int TCP_CONNECT_TIMEOUT_MS = 2500;
+ private static final int TCP_TIMEOUT_MS = 2000;
+ private static final int DNS_TLS_PORT = 853;
+ private static final int DNS_HEADER_SIZE = 12;
+
+ private final String mHostname;
+
+ public DnsTlsCheck(@Nullable String hostname, @NonNull InetAddress target,
+ @NonNull Measurement measurement) {
+ super(target, measurement);
+
+ mHostname = hostname;
+ mMeasurement.description = "DNS TLS dst{" + mTarget.getHostAddress() + "} hostname{"
+ + TextUtils.emptyIfNull(mHostname) + "}";
+ }
+
+ private SSLSocket setupSSLSocket() throws IOException {
+ // A TrustManager will be created and initialized with a KeyStore containing system
+ // CaCerts. During SSL handshake, it will be used to validate the certificates from
+ // the server.
+ SSLSocket sslSocket = (SSLSocket) SSLSocketFactory.getDefault().createSocket();
+ sslSocket.setSoTimeout(TCP_TIMEOUT_MS);
+
+ if (!TextUtils.isEmpty(mHostname)) {
+ // Set SNI.
+ final List<SNIServerName> names =
+ Collections.singletonList(new SNIHostName(mHostname));
+ SSLParameters params = sslSocket.getSSLParameters();
+ params.setServerNames(names);
+ sslSocket.setSSLParameters(params);
+ }
+
+ mNetwork.bindSocket(sslSocket);
+ return sslSocket;
+ }
+
+ private void sendDoTProbe(@Nullable SSLSocket sslSocket) throws IOException {
+ final String sixRandomDigits = String.valueOf(mRandom.nextInt(900000) + 100000);
+ final byte[] dnsPacket = getDnsQueryPacket(sixRandomDigits);
+
+ mMeasurement.startTime = now();
+ sslSocket.connect(new InetSocketAddress(mTarget, DNS_TLS_PORT), TCP_CONNECT_TIMEOUT_MS);
+
+ // Synchronous call waiting for the TLS handshake complete.
+ sslSocket.startHandshake();
+ appendDnsToMeasurementDescription(sixRandomDigits, sslSocket.getLocalSocketAddress());
+
+ final DataOutputStream output = new DataOutputStream(sslSocket.getOutputStream());
+ output.writeShort(dnsPacket.length);
+ output.write(dnsPacket, 0, dnsPacket.length);
+
+ final DataInputStream input = new DataInputStream(sslSocket.getInputStream());
+ final int replyLength = Short.toUnsignedInt(input.readShort());
+ final byte[] reply = new byte[replyLength];
+ int bytesRead = 0;
+ while (bytesRead < replyLength) {
+ bytesRead += input.read(reply, bytesRead, replyLength - bytesRead);
+ }
+
+ if (bytesRead > DNS_HEADER_SIZE && bytesRead == replyLength) {
+ mMeasurement.recordSuccess("1/1 " + responseCodeStr((int) (reply[3]) & 0x0f));
+ } else {
+ mMeasurement.recordFailure("1/1 Read " + bytesRead + " bytes while expected to be "
+ + replyLength + " bytes");
+ }
+ }
+
+ @Override
+ public void run() {
+ if (ensureMeasurementNecessary()) return;
+
+ // No need to restore the tag, since this thread is only used for this measurement.
+ TrafficStats.getAndSetThreadStatsTag(TrafficStatsConstants.TAG_SYSTEM_PROBE);
+
+ try (SSLSocket sslSocket = setupSSLSocket()) {
+ sendDoTProbe(sslSocket);
+ } catch (IOException e) {
+ mMeasurement.recordFailure(e.toString());
+ }
+ }
}
}
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index e654af706fca..1f85d1046523 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -1106,7 +1106,8 @@ public class Vpn {
NetworkAgentConfig networkAgentConfig = new NetworkAgentConfig();
networkAgentConfig.allowBypass = mConfig.allowBypass && !mLockdown;
- mNetworkCapabilities.setOwnerUid(Binder.getCallingUid());
+ mNetworkCapabilities.setOwnerUid(mOwnerUID);
+ mNetworkCapabilities.setAdministratorUids(new int[] {mOwnerUID});
mNetworkCapabilities.setUids(createUserAndRestrictedProfilesRanges(mUserHandle,
mConfig.allowedApplications, mConfig.disallowedApplications));
long token = Binder.clearCallingIdentity();
diff --git a/services/core/java/com/android/server/display/DisplayDeviceInfo.java b/services/core/java/com/android/server/display/DisplayDeviceInfo.java
index 18adc0ba27ee..d4377e4870a5 100644
--- a/services/core/java/com/android/server/display/DisplayDeviceInfo.java
+++ b/services/core/java/com/android/server/display/DisplayDeviceInfo.java
@@ -116,12 +116,20 @@ final class DisplayDeviceInfo {
/**
* Flag: This flag identifies secondary displays that should show system decorations, such as
* status bar, navigation bar, home activity or IME.
+ * <p>Note that this flag doesn't work without {@link #FLAG_TRUSTED}</p>
* @hide
*/
// TODO (b/114338689): Remove the flag and use IWindowManager#setShouldShowSystemDecors
public static final int FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS = 1 << 12;
/**
+ * Flag: The display is trusted to show system decorations and receive inputs without users'
+ * touch.
+ * @see #FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS
+ */
+ public static final int FLAG_TRUSTED = 1 << 13;
+
+ /**
* Touch attachment: Display does not receive touch.
*/
public static final int TOUCH_NONE = 0;
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index dee6cd02917f..1058000e0b68 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -16,6 +16,7 @@
package com.android.server.display;
+import static android.Manifest.permission.ADD_TRUSTED_DISPLAY;
import static android.Manifest.permission.CAPTURE_SECURE_VIDEO_OUTPUT;
import static android.Manifest.permission.CAPTURE_VIDEO_OUTPUT;
import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
@@ -25,6 +26,7 @@ import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_C
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC;
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE;
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS;
+import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_TRUSTED;
import static android.hardware.display.DisplayViewport.VIEWPORT_EXTERNAL;
import static android.hardware.display.DisplayViewport.VIEWPORT_INTERNAL;
import static android.hardware.display.DisplayViewport.VIEWPORT_VIRTUAL;
@@ -2189,16 +2191,25 @@ public final class DisplayManagerService extends SystemService {
}
}
+ if (callingUid == Process.SYSTEM_UID
+ || checkCallingPermission(ADD_TRUSTED_DISPLAY, "createVirtualDisplay()")) {
+ flags |= VIRTUAL_DISPLAY_FLAG_TRUSTED;
+ } else {
+ flags &= ~VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS;
+ }
+
// Sometimes users can have sensitive information in system decoration windows. An app
// could create a virtual display with system decorations support and read the user info
// from the surface.
// We should only allow adding flag VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS
- // to virtual displays that are owned by the system.
- if (callingUid != Process.SYSTEM_UID
- && (flags & VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS) != 0) {
- if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "createVirtualDisplay()")) {
+ // to trusted virtual displays.
+ final int trustedDisplayWithSysDecorFlag =
+ (VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS
+ | VIRTUAL_DISPLAY_FLAG_TRUSTED);
+ if ((flags & trustedDisplayWithSysDecorFlag)
+ == VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS
+ && !checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "createVirtualDisplay()")) {
throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission");
- }
}
final long token = Binder.clearCallingIdentity();
diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
index 2a65b33461cf..2c08420af42d 100644
--- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
@@ -577,6 +577,8 @@ final class LocalDisplayAdapter extends DisplayAdapter {
mInfo.name = getContext().getResources().getString(
com.android.internal.R.string.display_manager_hdmi_display_name);
}
+ // The display is trusted since it is created by system.
+ mInfo.flags |= DisplayDeviceInfo.FLAG_TRUSTED;
}
return mInfo;
}
diff --git a/services/core/java/com/android/server/display/LogicalDisplay.java b/services/core/java/com/android/server/display/LogicalDisplay.java
index 0261f388f7cb..8556f084a072 100644
--- a/services/core/java/com/android/server/display/LogicalDisplay.java
+++ b/services/core/java/com/android/server/display/LogicalDisplay.java
@@ -269,6 +269,9 @@ final class LogicalDisplay {
if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS) != 0) {
mBaseDisplayInfo.flags |= Display.FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS;
}
+ if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_TRUSTED) != 0) {
+ mBaseDisplayInfo.flags |= Display.FLAG_TRUSTED;
+ }
Rect maskingInsets = getMaskingInsets(deviceInfo);
int maskedWidth = deviceInfo.width - maskingInsets.left - maskingInsets.right;
int maskedHeight = deviceInfo.height - maskingInsets.top - maskingInsets.bottom;
diff --git a/services/core/java/com/android/server/display/OverlayDisplayAdapter.java b/services/core/java/com/android/server/display/OverlayDisplayAdapter.java
index 8fb384070e25..69943e3904ed 100644
--- a/services/core/java/com/android/server/display/OverlayDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/OverlayDisplayAdapter.java
@@ -16,6 +16,8 @@
package com.android.server.display;
+import static com.android.server.display.DisplayDeviceInfo.FLAG_TRUSTED;
+
import android.annotation.Nullable;
import android.content.Context;
import android.database.ContentObserver;
@@ -356,6 +358,8 @@ final class OverlayDisplayAdapter extends DisplayAdapter {
mInfo.type = Display.TYPE_OVERLAY;
mInfo.touch = DisplayDeviceInfo.TOUCH_VIRTUAL;
mInfo.state = mState;
+ // The display is trusted since it is created by system.
+ mInfo.flags |= FLAG_TRUSTED;
}
return mInfo;
}
diff --git a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
index ccd88483593a..210d2979c807 100644
--- a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
@@ -25,6 +25,9 @@ import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_ROTAT
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE;
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS;
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH;
+import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_TRUSTED;
+
+import static com.android.server.display.DisplayDeviceInfo.FLAG_TRUSTED;
import android.content.Context;
import android.hardware.display.IVirtualDisplayCallback;
@@ -412,6 +415,9 @@ public class VirtualDisplayAdapter extends DisplayAdapter {
if ((mFlags & VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS) != 0) {
mInfo.flags |= DisplayDeviceInfo.FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS;
}
+ if ((mFlags & VIRTUAL_DISPLAY_FLAG_TRUSTED) != 0) {
+ mInfo.flags |= FLAG_TRUSTED;
+ }
mInfo.type = Display.TYPE_VIRTUAL;
mInfo.touch = ((mFlags & VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH) == 0) ?
diff --git a/services/core/java/com/android/server/display/WifiDisplayAdapter.java b/services/core/java/com/android/server/display/WifiDisplayAdapter.java
index 5584dcf69f50..57323170b327 100644
--- a/services/core/java/com/android/server/display/WifiDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/WifiDisplayAdapter.java
@@ -651,6 +651,8 @@ final class WifiDisplayAdapter extends DisplayAdapter {
mInfo.address = mAddress;
mInfo.touch = DisplayDeviceInfo.TOUCH_EXTERNAL;
mInfo.setAssumedDensityForExternalDisplay(mWidth, mHeight);
+ // The display is trusted since it is created by system.
+ mInfo.flags |= DisplayDeviceInfo.FLAG_TRUSTED;
}
return mInfo;
}
diff --git a/services/core/java/com/android/server/dreams/DreamManagerService.java b/services/core/java/com/android/server/dreams/DreamManagerService.java
index 769956d797b0..e3eeb6c41d9f 100644
--- a/services/core/java/com/android/server/dreams/DreamManagerService.java
+++ b/services/core/java/com/android/server/dreams/DreamManagerService.java
@@ -47,6 +47,10 @@ import android.service.dreams.IDreamManager;
import android.util.Slog;
import android.view.Display;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.logging.UiEvent;
+import com.android.internal.logging.UiEventLogger;
+import com.android.internal.logging.UiEventLoggerImpl;
import com.android.internal.util.DumpUtils;
import com.android.server.FgThread;
import com.android.server.LocalServices;
@@ -77,6 +81,8 @@ public final class DreamManagerService extends SystemService {
private final PowerManagerInternal mPowerManagerInternal;
private final PowerManager.WakeLock mDozeWakeLock;
private final ActivityTaskManagerInternal mAtmInternal;
+ private final UiEventLogger mUiEventLogger;
+ private final ComponentName mAmbientDisplayComponent;
private Binder mCurrentDreamToken;
private ComponentName mCurrentDreamName;
@@ -91,6 +97,26 @@ public final class DreamManagerService extends SystemService {
private AmbientDisplayConfiguration mDozeConfig;
+ @VisibleForTesting
+ public enum DreamManagerEvent implements UiEventLogger.UiEventEnum {
+ @UiEvent(doc = "The screensaver has started.")
+ DREAM_START(577),
+
+ @UiEvent(doc = "The screensaver has stopped.")
+ DREAM_STOP(578);
+
+ private final int mId;
+
+ DreamManagerEvent(int id) {
+ mId = id;
+ }
+
+ @Override
+ public int getId() {
+ return mId;
+ }
+ }
+
public DreamManagerService(Context context) {
super(context);
mContext = context;
@@ -102,6 +128,9 @@ public final class DreamManagerService extends SystemService {
mAtmInternal = getLocalService(ActivityTaskManagerInternal.class);
mDozeWakeLock = mPowerManager.newWakeLock(PowerManager.DOZE_WAKE_LOCK, TAG);
mDozeConfig = new AmbientDisplayConfiguration(mContext);
+ mUiEventLogger = new UiEventLoggerImpl();
+ AmbientDisplayConfiguration adc = new AmbientDisplayConfiguration(mContext);
+ mAmbientDisplayComponent = ComponentName.unflattenFromString(adc.ambientDisplayComponent());
}
@Override
@@ -388,6 +417,9 @@ public final class DreamManagerService extends SystemService {
.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "startDream");
mHandler.post(wakeLock.wrap(() -> {
mAtmInternal.notifyDreamStateChanged(true);
+ if (!mCurrentDreamName.equals(mAmbientDisplayComponent)) {
+ mUiEventLogger.log(DreamManagerEvent.DREAM_START);
+ }
mController.startDream(newToken, name, isTest, canDoze, userId, wakeLock);
}));
}
@@ -415,6 +447,9 @@ public final class DreamManagerService extends SystemService {
}
private void cleanupDreamLocked() {
+ if (!mCurrentDreamName.equals(mAmbientDisplayComponent)) {
+ mUiEventLogger.log(DreamManagerEvent.DREAM_STOP);
+ }
mCurrentDreamToken = null;
mCurrentDreamName = null;
mCurrentDreamIsTest = false;
diff --git a/services/core/java/com/android/server/gpu/GpuService.java b/services/core/java/com/android/server/gpu/GpuService.java
index 955f17781540..8a3c963f4805 100644
--- a/services/core/java/com/android/server/gpu/GpuService.java
+++ b/services/core/java/com/android/server/gpu/GpuService.java
@@ -39,6 +39,7 @@ import android.os.UserHandle;
import android.provider.DeviceConfig;
import android.provider.DeviceConfig.Properties;
import android.provider.Settings;
+import android.text.TextUtils;
import android.util.Base64;
import android.util.Slog;
@@ -62,15 +63,19 @@ public class GpuService extends SystemService {
public static final String TAG = "GpuService";
public static final boolean DEBUG = false;
- private static final String PROPERTY_GFX_DRIVER = "ro.gfx.driver.0";
+ private static final String PROD_DRIVER_PROPERTY = "ro.gfx.driver.0";
+ private static final String DEV_DRIVER_PROPERTY = "ro.gfx.driver.1";
private static final String GAME_DRIVER_WHITELIST_FILENAME = "whitelist.txt";
private static final int BASE64_FLAGS = Base64.NO_PADDING | Base64.NO_WRAP;
private final Context mContext;
- private final String mDriverPackageName;
+ private final String mProdDriverPackageName;
+ private final String mDevDriverPackageName;
private final PackageManager mPackageManager;
private final Object mLock = new Object();
private final Object mDeviceConfigLock = new Object();
+ private final boolean mHasProdDriver;
+ private final boolean mHasDevDriver;
private ContentResolver mContentResolver;
private long mGameDriverVersionCode;
private SettingsObserver mSettingsObserver;
@@ -82,10 +87,13 @@ public class GpuService extends SystemService {
super(context);
mContext = context;
- mDriverPackageName = SystemProperties.get(PROPERTY_GFX_DRIVER);
+ mProdDriverPackageName = SystemProperties.get(PROD_DRIVER_PROPERTY);
mGameDriverVersionCode = -1;
+ mDevDriverPackageName = SystemProperties.get(DEV_DRIVER_PROPERTY);
mPackageManager = context.getPackageManager();
- if (mDriverPackageName != null && !mDriverPackageName.isEmpty()) {
+ mHasProdDriver = !TextUtils.isEmpty(mProdDriverPackageName);
+ mHasDevDriver = !TextUtils.isEmpty(mDevDriverPackageName);
+ if (mHasDevDriver || mHasProdDriver) {
final IntentFilter packageFilter = new IntentFilter();
packageFilter.addAction(ACTION_PACKAGE_ADDED);
packageFilter.addAction(ACTION_PACKAGE_CHANGED);
@@ -104,7 +112,7 @@ public class GpuService extends SystemService {
public void onBootPhase(int phase) {
if (phase == PHASE_BOOT_COMPLETED) {
mContentResolver = mContext.getContentResolver();
- if (mDriverPackageName == null || mDriverPackageName.isEmpty()) {
+ if (!mHasProdDriver && !mHasDevDriver) {
return;
}
mSettingsObserver = new SettingsObserver();
@@ -112,6 +120,7 @@ public class GpuService extends SystemService {
fetchGameDriverPackageProperties();
processBlacklists();
setBlacklist();
+ fetchDeveloperDriverPackageProperties();
}
}
@@ -166,18 +175,22 @@ public class GpuService extends SystemService {
return;
}
final String packageName = data.getSchemeSpecificPart();
- if (!packageName.equals(mDriverPackageName)) {
+ final boolean isProdDriver = packageName.equals(mProdDriverPackageName);
+ final boolean isDevDriver = packageName.equals(mDevDriverPackageName);
+ if (!isProdDriver && !isDevDriver) {
return;
}
- final boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
-
switch (intent.getAction()) {
case ACTION_PACKAGE_ADDED:
case ACTION_PACKAGE_CHANGED:
case ACTION_PACKAGE_REMOVED:
- fetchGameDriverPackageProperties();
- setBlacklist();
+ if (isProdDriver) {
+ fetchGameDriverPackageProperties();
+ setBlacklist();
+ } else if (isDevDriver) {
+ fetchDeveloperDriverPackageProperties();
+ }
break;
default:
// do nothing
@@ -208,11 +221,11 @@ public class GpuService extends SystemService {
private void fetchGameDriverPackageProperties() {
final ApplicationInfo driverInfo;
try {
- driverInfo = mPackageManager.getApplicationInfo(mDriverPackageName,
+ driverInfo = mPackageManager.getApplicationInfo(mProdDriverPackageName,
PackageManager.MATCH_SYSTEM_ONLY);
} catch (PackageManager.NameNotFoundException e) {
if (DEBUG) {
- Slog.e(TAG, "driver package '" + mDriverPackageName + "' not installed");
+ Slog.e(TAG, "driver package '" + mProdDriverPackageName + "' not installed");
}
return;
}
@@ -232,14 +245,14 @@ public class GpuService extends SystemService {
mGameDriverVersionCode = driverInfo.longVersionCode;
try {
- final Context driverContext = mContext.createPackageContext(mDriverPackageName,
+ final Context driverContext = mContext.createPackageContext(mProdDriverPackageName,
Context.CONTEXT_RESTRICTED);
assetToSettingsGlobal(mContext, driverContext, GAME_DRIVER_WHITELIST_FILENAME,
Settings.Global.GAME_DRIVER_WHITELIST, ",");
} catch (PackageManager.NameNotFoundException e) {
if (DEBUG) {
- Slog.w(TAG, "driver package '" + mDriverPackageName + "' not installed");
+ Slog.w(TAG, "driver package '" + mProdDriverPackageName + "' not installed");
}
}
}
@@ -291,4 +304,40 @@ public class GpuService extends SystemService {
}
}
}
+
+ private void fetchDeveloperDriverPackageProperties() {
+ final ApplicationInfo driverInfo;
+ try {
+ driverInfo = mPackageManager.getApplicationInfo(mDevDriverPackageName,
+ PackageManager.MATCH_SYSTEM_ONLY);
+ } catch (PackageManager.NameNotFoundException e) {
+ if (DEBUG) {
+ Slog.e(TAG, "driver package '" + mDevDriverPackageName + "' not installed");
+ }
+ return;
+ }
+
+ // O drivers are restricted to the sphal linker namespace, so don't try to use
+ // packages unless they declare they're compatible with that restriction.
+ if (driverInfo.targetSdkVersion < Build.VERSION_CODES.O) {
+ if (DEBUG) {
+ Slog.w(TAG, "Driver package is not known to be compatible with O");
+ }
+ return;
+ }
+
+ setUpdatableDriverPath(driverInfo);
+ }
+
+ private void setUpdatableDriverPath(ApplicationInfo ai) {
+ if (ai.primaryCpuAbi == null) {
+ nSetUpdatableDriverPath("");
+ return;
+ }
+ final StringBuilder sb = new StringBuilder();
+ sb.append(ai.sourceDir).append("!/lib/");
+ nSetUpdatableDriverPath(sb.toString());
+ }
+
+ private static native void nSetUpdatableDriverPath(String driverPath);
}
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
index 0ac4f9ee4c6d..f4a86675541d 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
@@ -213,6 +213,7 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
mLocalDeviceAddresses = initLocalDeviceAddresses();
resetSelectRequestBuffer();
launchDeviceDiscovery();
+ startQueuedActions();
}
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index b9669c74a6df..87a908c10721 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -3142,7 +3142,7 @@ public class HdmiControlService extends SystemService {
return;
}
- setHdmiCecVolumeControlEnabled(false);
+ mHdmiCecVolumeControlEnabled = false;
// Call the vendor handler before the service is disabled.
invokeVendorCommandListenersOnControlStateChanged(false,
HdmiControlManager.CONTROL_STATE_CHANGED_REASON_SETTING);
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java
index de13bd86a415..70f0399d1070 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java
@@ -17,6 +17,7 @@
package com.android.server.inputmethod;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.os.IBinder;
import android.view.inputmethod.InlineSuggestionsRequest;
@@ -109,6 +110,16 @@ public abstract class InputMethodManagerInternal {
int displayId);
/**
+ * Reports that IME control has transferred to the given window token, or if null that
+ * control has been taken away from client windows (and is instead controlled by the policy
+ * or SystemUI).
+ *
+ * @param windowToken the window token that is now in control, or {@code null} if no client
+ * window is in control of the IME.
+ */
+ public abstract void reportImeControl(@Nullable IBinder windowToken);
+
+ /**
* Fake implementation of {@link InputMethodManagerInternal}. All the methods do nothing.
*/
private static final InputMethodManagerInternal NOP =
@@ -151,6 +162,10 @@ public abstract class InputMethodManagerInternal {
int displayId) {
return false;
}
+
+ @Override
+ public void reportImeControl(@Nullable IBinder windowToken) {
+ }
};
/**
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index 65a13016c9b6..9acb47538043 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -18,6 +18,8 @@ package com.android.server.inputmethod;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;
+import static com.android.internal.inputmethod.StartInputReason.WINDOW_FOCUS_GAIN_REPORT_WITH_SAME_EDITOR;
+
import static java.lang.annotation.RetentionPolicy.SOURCE;
import android.Manifest;
@@ -177,6 +179,7 @@ import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Locale;
+import java.util.Objects;
import java.util.WeakHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicInteger;
@@ -207,6 +210,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
static final int MSG_HIDE_CURRENT_INPUT_METHOD = 1035;
static final int MSG_INITIALIZE_IME = 1040;
static final int MSG_CREATE_SESSION = 1050;
+ static final int MSG_REMOVE_IME_SURFACE = 1060;
static final int MSG_START_INPUT = 2000;
@@ -590,6 +594,11 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
private boolean mCurClientInKeyguard;
/**
+ * {@code true} if the IME has not been mostly hidden via {@link android.view.InsetsController}
+ */
+ private boolean mCurPerceptible;
+
+ /**
* Set to true if our ServiceConnection is currently actively bound to
* a service (whether or not we have gotten its IBinder back yet).
*/
@@ -709,6 +718,11 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
*/
int mImeWindowVis;
+ /**
+ * Checks if the client needs to start input.
+ */
+ private boolean mCurClientNeedStartInput = false;
+
private AlertDialog.Builder mDialogBuilder;
private AlertDialog mSwitchingDialog;
private IBinder mSwitchingDialogToken = new Binder();
@@ -2928,6 +2942,9 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
if (vis != 0 && isKeyguardLocked() && !mCurClientInKeyguard) {
vis = 0;
}
+ if (!mCurPerceptible) {
+ vis = 0;
+ }
// mImeWindowVis should be updated before calling shouldShowImeSwitcherLocked().
final boolean needsToShowImeSwitcher = shouldShowImeSwitcherLocked(vis);
if (mStatusBar != null) {
@@ -3140,6 +3157,28 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
}
+ @BinderThread
+ @Override
+ public void reportPerceptible(IBinder windowToken, boolean perceptible) {
+ Objects.requireNonNull(windowToken, "windowToken must not be null");
+ int uid = Binder.getCallingUid();
+ synchronized (mMethodMap) {
+ if (!calledFromValidUserLocked()) {
+ return;
+ }
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ if (mCurFocusedWindow == windowToken
+ && mCurPerceptible != perceptible) {
+ mCurPerceptible = perceptible;
+ updateSystemUiLocked(mImeWindowVis, mBackDisposition);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+ }
+
@GuardedBy("mMethodMap")
boolean showCurrentInputLocked(IBinder windowToken, int flags, ResultReceiver resultReceiver,
@SoftInputShowHideReason int reason) {
@@ -3424,10 +3463,18 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
Slog.w(TAG, "Window already focused, ignoring focus gain of: " + client
+ " attribute=" + attribute + ", token = " + windowToken);
}
- if (attribute != null) {
+ // Needs to start input when the same window focus gain but not with the same editor,
+ // or when the current client needs to start input (e.g. when focusing the same
+ // window after device turned screen on).
+ if (attribute != null && (startInputReason != WINDOW_FOCUS_GAIN_REPORT_WITH_SAME_EDITOR
+ || mCurClientNeedStartInput)) {
+ if (mIsInteractive) {
+ mCurClientNeedStartInput = false;
+ }
return startInputUncheckedLocked(cs, inputContext, missingMethods,
attribute, startInputFlags, startInputReason);
}
+
return new InputBindResult(
InputBindResult.ResultCode.SUCCESS_REPORT_WINDOW_FOCUS_ONLY,
null, null, null, -1, null);
@@ -3435,6 +3482,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
mCurFocusedWindow = windowToken;
mCurFocusedWindowSoftInputMode = softInputMode;
mCurFocusedWindowClient = cs;
+ mCurPerceptible = true;
// Should we auto-show the IME even if the caller has not
// specified what should be done with it?
@@ -3946,6 +3994,12 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
}
+ @Override
+ public void removeImeSurface() {
+ mContext.enforceCallingPermission(Manifest.permission.INTERNAL_SYSTEM_WINDOW, null);
+ mHandler.sendMessage(mHandler.obtainMessage(MSG_REMOVE_IME_SURFACE));
+ }
+
@BinderThread
private void notifyUserAction(@NonNull IBinder token) {
if (DEBUG) {
@@ -4216,6 +4270,15 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
args.recycle();
return true;
}
+ case MSG_REMOVE_IME_SURFACE: {
+ try {
+ if (mEnabledSession != null && mEnabledSession.session != null) {
+ mEnabledSession.session.removeImeSurface();
+ }
+ } catch (RemoteException e) {
+ }
+ return true;
+ }
// ---------------------------------------------------------
case MSG_START_INPUT: {
@@ -4365,6 +4428,9 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
private void handleSetInteractive(final boolean interactive) {
synchronized (mMethodMap) {
mIsInteractive = interactive;
+ if (!interactive) {
+ mCurClientNeedStartInput = true;
+ }
updateSystemUiLocked(interactive ? mImeWindowVis : 0, mBackDisposition);
// Inform the current client of the change in active status
@@ -4976,6 +5042,16 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
return mInputManagerInternal.transferTouchFocus(sourceInputToken, curHostInputToken);
}
+ private void reportImeControl(@Nullable IBinder windowToken) {
+ synchronized (mMethodMap) {
+ if (mCurFocusedWindow != windowToken) {
+ // mCurPerceptible was set by the focused window, but it is no longer in control,
+ // so we reset mCurPerceptible.
+ mCurPerceptible = true;
+ }
+ }
+ }
+
private static final class LocalServiceImpl extends InputMethodManagerInternal {
@NonNull
private final InputMethodManagerService mService;
@@ -5028,6 +5104,11 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
int displayId) {
return mService.transferTouchFocusToImeWindow(sourceInputToken, displayId);
}
+
+ @Override
+ public void reportImeControl(@Nullable IBinder windowToken) {
+ mService.reportImeControl(windowToken);
+ }
}
@BinderThread
@@ -5130,6 +5211,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
p.println(" mCurMethodId=" + mCurMethodId);
client = mCurClient;
p.println(" mCurClient=" + client + " mCurSeq=" + mCurSeq);
+ p.println(" mCurPerceptible=" + mCurPerceptible);
p.println(" mCurFocusedWindow=" + mCurFocusedWindow
+ " softInputMode=" +
InputMethodDebug.softInputModeToString(mCurFocusedWindowSoftInputMode)
diff --git a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java
index 6c415ca326c6..2e3d3963c9df 100644
--- a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java
@@ -221,6 +221,10 @@ public final class MultiClientInputMethodManagerService {
reportNotSupported();
return false;
}
+
+ @Override
+ public void reportImeControl(@Nullable IBinder windowToken) {
+ }
});
}
@@ -1463,6 +1467,12 @@ public final class MultiClientInputMethodManagerService {
@BinderThread
@Override
+ public void removeImeSurface() {
+ reportNotSupported();
+ }
+
+ @BinderThread
+ @Override
public boolean showSoftInput(
IInputMethodClient client, IBinder token, int flags,
ResultReceiver resultReceiver) {
@@ -1747,6 +1757,12 @@ public final class MultiClientInputMethodManagerService {
@BinderThread
@Override
+ public void reportPerceptible(IBinder windowClient, boolean perceptible) {
+ reportNotSupported();
+ }
+
+ @BinderThread
+ @Override
public void onShellCommand(@Nullable FileDescriptor in, @Nullable FileDescriptor out,
@Nullable FileDescriptor err, String[] args, @Nullable ShellCallback callback,
ResultReceiver resultReceiver) {
diff --git a/services/core/java/com/android/server/location/gnss/GnssNetworkConnectivityHandler.java b/services/core/java/com/android/server/location/gnss/GnssNetworkConnectivityHandler.java
index e17cca423822..3fb713bc01a5 100644
--- a/services/core/java/com/android/server/location/gnss/GnssNetworkConnectivityHandler.java
+++ b/services/core/java/com/android/server/location/gnss/GnssNetworkConnectivityHandler.java
@@ -17,9 +17,8 @@
package com.android.server.location.gnss;
import android.content.Context;
+import android.database.Cursor;
import android.net.ConnectivityManager;
-import android.net.LinkAddress;
-import android.net.LinkProperties;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
@@ -27,26 +26,25 @@ import android.net.NetworkRequest;
import android.os.Handler;
import android.os.Looper;
import android.os.PowerManager;
-import android.telephony.PhoneStateListener;
-import android.telephony.PreciseCallState;
+import android.provider.Telephony.Carriers;
+import android.telephony.ServiceState;
+import android.telephony.TelephonyManager;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyManager;
+import android.telephony.PreciseCallState;
+import android.telephony.PhoneStateListener;
import android.util.Log;
import com.android.internal.location.GpsNetInitiatedHandler;
-import java.net.Inet4Address;
-import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
+import java.util.Map;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.Iterator;
import java.util.List;
-import java.util.Map;
-
+import java.util.Iterator;
/**
* Handles network connection requests and network state change updates for AGPS data download.
@@ -387,10 +385,10 @@ class GnssNetworkConnectivityHandler {
private ConnectivityManager.NetworkCallback createSuplConnectivityCallback() {
return new ConnectivityManager.NetworkCallback() {
@Override
- public void onLinkPropertiesChanged(Network network, LinkProperties linkProperties) {
+ public void onAvailable(Network network) {
if (DEBUG) Log.d(TAG, "SUPL network connection available.");
// Specific to a change to a SUPL enabled network becoming ready
- handleSuplConnectionAvailable(network, linkProperties);
+ handleSuplConnectionAvailable(network);
}
@Override
@@ -498,7 +496,7 @@ class GnssNetworkConnectivityHandler {
return networkAttributes;
}
- private void handleSuplConnectionAvailable(Network network, LinkProperties linkProperties) {
+ private void handleSuplConnectionAvailable(Network network) {
// TODO: The synchronous method ConnectivityManager.getNetworkInfo() should not be called
// inside the asynchronous ConnectivityManager.NetworkCallback methods.
NetworkInfo info = mConnMgr.getNetworkInfo(network);
@@ -530,7 +528,7 @@ class GnssNetworkConnectivityHandler {
setRouting();
}
- int apnIpType = getLinkIpType(linkProperties);
+ int apnIpType = getApnIpType(apn);
if (DEBUG) {
String message = String.format(
"native_agps_data_conn_open: mAgpsApn=%s, mApnIpType=%s",
@@ -706,32 +704,74 @@ class GnssNetworkConnectivityHandler {
}
}
- private int getLinkIpType(LinkProperties linkProperties) {
+ private int getApnIpType(String apn) {
ensureInHandlerThread();
- boolean isIPv4 = false;
- boolean isIPv6 = false;
-
- List<LinkAddress> linkAddresses = linkProperties.getLinkAddresses();
- for (LinkAddress linkAddress : linkAddresses) {
- InetAddress inetAddress = linkAddress.getAddress();
- if (inetAddress instanceof Inet4Address) {
- isIPv4 = true;
- } else if (inetAddress instanceof Inet6Address) {
- isIPv6 = true;
+ if (apn == null) {
+ return APN_INVALID;
+ }
+ TelephonyManager phone = (TelephonyManager)
+ mContext.getSystemService(Context.TELEPHONY_SERVICE);
+ // During an emergency call with an active sub id, get the Telephony Manager specific
+ // to the active sub to get the correct value from getServiceState and getNetworkType
+ if (mNiHandler.getInEmergency() && mActiveSubId >= 0) {
+ TelephonyManager subIdTelManager =
+ phone.createForSubscriptionId(mActiveSubId);
+ if (subIdTelManager != null) {
+ phone = subIdTelManager;
}
- if (DEBUG) Log.d(TAG, "LinkAddress : " + inetAddress.toString());
}
-
- if (isIPv4 && isIPv6) {
- return APN_IPV4V6;
+ ServiceState serviceState = phone.getServiceState();
+ String projection = null;
+ String selection = null;
+
+ // Carrier configuration may override framework roaming state, we need to use the actual
+ // modem roaming state instead of the framework roaming state.
+ if (serviceState != null && serviceState.getDataRoamingFromRegistration()) {
+ projection = Carriers.ROAMING_PROTOCOL;
+ } else {
+ projection = Carriers.PROTOCOL;
+ }
+ // No SIM case for emergency
+ if (TelephonyManager.NETWORK_TYPE_UNKNOWN == phone.getNetworkType()
+ && AGPS_TYPE_EIMS == mAGpsType) {
+ selection = String.format(
+ "type like '%%emergency%%' and apn = '%s' and carrier_enabled = 1", apn);
+ } else {
+ selection = String.format("current = 1 and apn = '%s' and carrier_enabled = 1", apn);
+ }
+ try (Cursor cursor = mContext.getContentResolver().query(
+ Carriers.CONTENT_URI,
+ new String[]{projection},
+ selection,
+ null,
+ Carriers.DEFAULT_SORT_ORDER)) {
+ if (null != cursor && cursor.moveToFirst()) {
+ return translateToApnIpType(cursor.getString(0), apn);
+ } else {
+ Log.e(TAG, "No entry found in query for APN: " + apn);
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "Error encountered on APN query for: " + apn, e);
}
- if (isIPv4) {
+
+ return APN_IPV4V6;
+ }
+
+ private int translateToApnIpType(String ipProtocol, String apn) {
+ if ("IP".equals(ipProtocol)) {
return APN_IPV4;
}
- if (isIPv6) {
+ if ("IPV6".equals(ipProtocol)) {
return APN_IPV6;
}
- return APN_INVALID;
+ if ("IPV4V6".equals(ipProtocol)) {
+ return APN_IPV4V6;
+ }
+
+ // we hit the default case so the ipProtocol is not recognized
+ String message = String.format("Unknown IP Protocol: %s, for APN: %s", ipProtocol, apn);
+ Log.e(TAG, message);
+ return APN_IPV4V6;
}
// AGPS support
diff --git a/services/core/java/com/android/server/media/BluetoothRouteProvider.java b/services/core/java/com/android/server/media/BluetoothRouteProvider.java
index c7575d4fc8a4..25bbfa02fa05 100644
--- a/services/core/java/com/android/server/media/BluetoothRouteProvider.java
+++ b/services/core/java/com/android/server/media/BluetoothRouteProvider.java
@@ -17,6 +17,8 @@
package com.android.server.media;
import static android.bluetooth.BluetoothAdapter.ACTIVE_DEVICE_AUDIO;
+import static android.bluetooth.BluetoothAdapter.STATE_CONNECTED;
+import static android.bluetooth.BluetoothAdapter.STATE_DISCONNECTED;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -33,6 +35,7 @@ import android.media.AudioManager;
import android.media.AudioSystem;
import android.media.MediaRoute2Info;
import android.text.TextUtils;
+import android.util.Log;
import android.util.Slog;
import android.util.SparseBooleanArray;
import android.util.SparseIntArray;
@@ -48,13 +51,16 @@ import java.util.Objects;
class BluetoothRouteProvider {
private static final String TAG = "BTRouteProvider";
+ private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
private static final String HEARING_AID_ROUTE_ID_PREFIX = "HEARING_AID_";
private static BluetoothRouteProvider sInstance;
@SuppressWarnings("WeakerAccess") /* synthetic access */
+ // Maps hardware address to BluetoothRouteInfo
final Map<String, BluetoothRouteInfo> mBluetoothRoutes = new HashMap<>();
@SuppressWarnings("WeakerAccess") /* synthetic access */
- BluetoothRouteInfo mSelectedRoute = null;
+ final List<BluetoothRouteInfo> mActiveRoutes = new ArrayList<>();
@SuppressWarnings("WeakerAccess") /* synthetic access */
BluetoothA2dp mA2dpProfile;
@SuppressWarnings("WeakerAccess") /* synthetic access */
@@ -103,7 +109,7 @@ class BluetoothRouteProvider {
// Bluetooth on/off broadcasts
addEventReceiver(BluetoothAdapter.ACTION_STATE_CHANGED, new AdapterStateChangedReceiver());
- DeviceStateChangedRecevier deviceStateChangedReceiver = new DeviceStateChangedRecevier();
+ DeviceStateChangedReceiver deviceStateChangedReceiver = new DeviceStateChangedReceiver();
addEventReceiver(BluetoothA2dp.ACTION_ACTIVE_DEVICE_CHANGED, deviceStateChangedReceiver);
addEventReceiver(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED, deviceStateChangedReceiver);
addEventReceiver(BluetoothHearingAid.ACTION_ACTIVE_DEVICE_CHANGED,
@@ -127,9 +133,10 @@ class BluetoothRouteProvider {
return;
}
- BluetoothRouteInfo btRouteInfo = mBluetoothRoutes.get(routeId);
+ BluetoothRouteInfo btRouteInfo = findBluetoothRouteWithRouteId(routeId);
+
if (btRouteInfo == null) {
- Slog.w(TAG, "transferTo: unknown route id=" + routeId);
+ Slog.w(TAG, "transferTo: Unknown route. ID=" + routeId);
return;
}
@@ -166,14 +173,16 @@ class BluetoothRouteProvider {
@Nullable
MediaRoute2Info getSelectedRoute() {
- return (mSelectedRoute == null) ? null : mSelectedRoute.route;
+ // For now, active routes can be multiple only when a pair of hearing aid devices is active.
+ // Let the first active device represent them.
+ return (mActiveRoutes.isEmpty() ? null : mActiveRoutes.get(0).route);
}
@NonNull
List<MediaRoute2Info> getTransferableRoutes() {
List<MediaRoute2Info> routes = getAllBluetoothRoutes();
- if (mSelectedRoute != null) {
- routes.remove(mSelectedRoute.route);
+ for (BluetoothRouteInfo btRoute : mActiveRoutes) {
+ routes.remove(btRoute.route);
}
return routes;
}
@@ -183,8 +192,14 @@ class BluetoothRouteProvider {
List<MediaRoute2Info> routes = new ArrayList<>();
List<String> routeIds = new ArrayList<>();
+ MediaRoute2Info selectedRoute = getSelectedRoute();
+ if (selectedRoute != null) {
+ routes.add(selectedRoute);
+ routeIds.add(selectedRoute.getId());
+ }
+
for (BluetoothRouteInfo btRoute : mBluetoothRoutes.values()) {
- // A pair of hearing aid devices or the same hardware address
+ // A pair of hearing aid devices or having the same hardware address
if (routeIds.contains(btRoute.route.getId())) {
continue;
}
@@ -194,6 +209,18 @@ class BluetoothRouteProvider {
return routes;
}
+ BluetoothRouteInfo findBluetoothRouteWithRouteId(String routeId) {
+ if (routeId == null) {
+ return null;
+ }
+ for (BluetoothRouteInfo btRouteInfo : mBluetoothRoutes.values()) {
+ if (TextUtils.equals(btRouteInfo.route.getId(), routeId)) {
+ return btRouteInfo;
+ }
+ }
+ return null;
+ }
+
/**
* Updates the volume for {@link AudioManager#getDevicesForStream(int) devices}.
*
@@ -211,13 +238,20 @@ class BluetoothRouteProvider {
return false;
}
mVolumeMap.put(routeType, volume);
- if (mSelectedRoute == null || mSelectedRoute.route.getType() != routeType) {
- return true;
+
+ boolean shouldNotify = false;
+ for (BluetoothRouteInfo btRoute : mActiveRoutes) {
+ if (btRoute.route.getType() != routeType) {
+ continue;
+ }
+ btRoute.route = new MediaRoute2Info.Builder(btRoute.route)
+ .setVolume(volume)
+ .build();
+ shouldNotify = true;
+ }
+ if (shouldNotify) {
+ notifyBluetoothRoutesUpdated();
}
- mSelectedRoute.route = new MediaRoute2Info.Builder(mSelectedRoute.route)
- .setVolume(volume)
- .build();
- notifyBluetoothRoutesUpdated();
return true;
}
@@ -252,6 +286,7 @@ class BluetoothRouteProvider {
// Current volume will be set when connected.
newBtRoute.route = new MediaRoute2Info.Builder(routeId, deviceName)
.addFeature(MediaRoute2Info.FEATURE_LIVE_AUDIO)
+ .addFeature(MediaRoute2Info.FEATURE_LOCAL_PLAYBACK)
.setConnectionState(MediaRoute2Info.CONNECTION_STATE_DISCONNECTED)
.setDescription(mContext.getResources().getText(
R.string.bluetooth_a2dp_audio_route_name).toString())
@@ -283,6 +318,53 @@ class BluetoothRouteProvider {
btRoute.route = builder.build();
}
+ private void clearActiveRoutes() {
+ if (DEBUG) {
+ Log.d(TAG, "Clearing active routes");
+ }
+ for (BluetoothRouteInfo btRoute : mActiveRoutes) {
+ setRouteConnectionState(btRoute, STATE_DISCONNECTED);
+ }
+ mActiveRoutes.clear();
+ }
+
+ private void addActiveRoute(BluetoothRouteInfo btRoute) {
+ if (DEBUG) {
+ Log.d(TAG, "Adding active route: " + btRoute.route);
+ }
+ if (btRoute == null || mActiveRoutes.contains(btRoute)) {
+ return;
+ }
+ setRouteConnectionState(btRoute, STATE_CONNECTED);
+ mActiveRoutes.add(btRoute);
+ }
+
+ private void removeActiveRoute(BluetoothRouteInfo btRoute) {
+ if (DEBUG) {
+ Log.d(TAG, "Removing active route: " + btRoute.route);
+ }
+ if (mActiveRoutes.remove(btRoute)) {
+ setRouteConnectionState(btRoute, STATE_DISCONNECTED);
+ }
+ }
+
+ private void findAndSetActiveHearingAidDevices() {
+ if (DEBUG) {
+ Log.d(TAG, "Setting active hearing aid devices");
+ }
+
+ BluetoothHearingAid hearingAidProfile = mHearingAidProfile;
+ if (hearingAidProfile == null) {
+ return;
+ }
+ List<BluetoothDevice> activeDevices = hearingAidProfile.getActiveDevices();
+ for (BluetoothRouteInfo btRoute : mBluetoothRoutes.values()) {
+ if (activeDevices.contains(btRoute.btDevice)) {
+ addActiveRoute(btRoute);
+ }
+ }
+ }
+
interface BluetoothRoutesUpdatedListener {
void onBluetoothRoutesUpdated(@NonNull List<MediaRoute2Info> routes);
}
@@ -319,7 +401,6 @@ class BluetoothRouteProvider {
default:
return;
}
- //TODO(b/157708273): Handle two active devices in the binaural case.
for (BluetoothDevice device : proxy.getConnectedDevices()) {
BluetoothRouteInfo btRoute = mBluetoothRoutes.get(device.getAddress());
if (btRoute == null) {
@@ -327,9 +408,7 @@ class BluetoothRouteProvider {
mBluetoothRoutes.put(device.getAddress(), btRoute);
}
if (activeDevices.contains(device)) {
- mSelectedRoute = btRoute;
- setRouteConnectionState(mSelectedRoute,
- MediaRoute2Info.CONNECTION_STATE_CONNECTED);
+ addActiveRoute(btRoute);
}
}
notifyBluetoothRoutesUpdated();
@@ -381,26 +460,23 @@ class BluetoothRouteProvider {
}
}
- private class DeviceStateChangedRecevier implements BluetoothEventReceiver {
+ private class DeviceStateChangedReceiver implements BluetoothEventReceiver {
@Override
public void onReceive(Context context, Intent intent, BluetoothDevice device) {
switch (intent.getAction()) {
case BluetoothA2dp.ACTION_ACTIVE_DEVICE_CHANGED:
+ clearActiveRoutes();
+ if (device != null) {
+ addActiveRoute(mBluetoothRoutes.get(device.getAddress()));
+ }
+ notifyBluetoothRoutesUpdated();
+ break;
case BluetoothHearingAid.ACTION_ACTIVE_DEVICE_CHANGED:
- if (mSelectedRoute == null
- || !mSelectedRoute.btDevice.equals(device)) {
- if (mSelectedRoute != null) {
- setRouteConnectionState(mSelectedRoute,
- MediaRoute2Info.CONNECTION_STATE_DISCONNECTED);
- }
- mSelectedRoute = (device == null) ? null
- : mBluetoothRoutes.get(device.getAddress());
- if (mSelectedRoute != null) {
- setRouteConnectionState(mSelectedRoute,
- MediaRoute2Info.CONNECTION_STATE_CONNECTED);
- }
- notifyBluetoothRoutesUpdated();
+ clearActiveDevices();
+ if (device != null) {
+ findAndSetActiveHearingAidDevices();
}
+ notifyBluetoothRoutesUpdated();
break;
case BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED:
handleConnectionStateChanged(BluetoothProfile.A2DP, intent, device);
@@ -430,10 +506,7 @@ class BluetoothRouteProvider {
if (btRoute != null) {
btRoute.connectedProfiles.delete(profile);
if (btRoute.connectedProfiles.size() == 0) {
- mBluetoothRoutes.remove(device.getAddress());
- if (mSelectedRoute != null && mSelectedRoute.btDevice.equals(device)) {
- mSelectedRoute = null;
- }
+ removeActiveRoute(mBluetoothRoutes.remove(device.getAddress()));
notifyBluetoothRoutesUpdated();
}
}
diff --git a/services/core/java/com/android/server/media/MediaButtonReceiverHolder.java b/services/core/java/com/android/server/media/MediaButtonReceiverHolder.java
index 58c2707a1f19..9dae1b44117b 100644
--- a/services/core/java/com/android/server/media/MediaButtonReceiverHolder.java
+++ b/services/core/java/com/android/server/media/MediaButtonReceiverHolder.java
@@ -85,6 +85,9 @@ final class MediaButtonReceiverHolder {
return null;
}
ComponentName componentName = ComponentName.unflattenFromString(tokens[0]);
+ if (componentName == null) {
+ return null;
+ }
int userId = Integer.parseInt(tokens[1]);
// Guess component type if the OS version is updated from the older version.
int componentType = (tokens.length == 3)
diff --git a/services/core/java/com/android/server/media/MediaKeyDispatcher.java b/services/core/java/com/android/server/media/MediaKeyDispatcher.java
index 176ec3f003ea..5933723f01b6 100644
--- a/services/core/java/com/android/server/media/MediaKeyDispatcher.java
+++ b/services/core/java/com/android/server/media/MediaKeyDispatcher.java
@@ -71,6 +71,9 @@ public abstract class MediaKeyDispatcher {
mOverriddenKeyEvents.put(KeyEvent.KEYCODE_MEDIA_STOP, 0);
mOverriddenKeyEvents.put(KeyEvent.KEYCODE_MEDIA_NEXT, 0);
mOverriddenKeyEvents.put(KeyEvent.KEYCODE_MEDIA_PREVIOUS, 0);
+ mOverriddenKeyEvents.put(KeyEvent.KEYCODE_VOLUME_DOWN, 0);
+ mOverriddenKeyEvents.put(KeyEvent.KEYCODE_VOLUME_UP, 0);
+ mOverriddenKeyEvents.put(KeyEvent.KEYCODE_VOLUME_MUTE, 0);
}
// TODO: Move this method into SessionPolicyProvider.java for better readability.
@@ -126,6 +129,9 @@ public abstract class MediaKeyDispatcher {
* <li> {@link KeyEvent#KEYCODE_MEDIA_STOP}
* <li> {@link KeyEvent#KEYCODE_MEDIA_NEXT}
* <li> {@link KeyEvent#KEYCODE_MEDIA_PREVIOUS}
+ * <li> {@link KeyEvent#KEYCODE_VOLUME_UP}
+ * <li> {@link KeyEvent#KEYCODE_VOLUME_DOWN}
+ * <li> {@link KeyEvent#KEYCODE_VOLUME_MUTE}
* </ul>
* @see {@link KeyEvent#isMediaSessionKey(int)}
*/
@@ -164,6 +170,9 @@ public abstract class MediaKeyDispatcher {
* <li> {@link KeyEvent#KEYCODE_MEDIA_STOP}
* <li> {@link KeyEvent#KEYCODE_MEDIA_NEXT}
* <li> {@link KeyEvent#KEYCODE_MEDIA_PREVIOUS}
+ * <li> {@link KeyEvent#KEYCODE_VOLUME_DOWN}
+ * <li> {@link KeyEvent#KEYCODE_VOLUME_UP}
+ * <li> {@link KeyEvent#KEYCODE_VOLUME_MUTE}
* </ul>
* @see {@link KeyEvent#isMediaSessionKey(int)}
* @param keyCode
diff --git a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
index 9a2aee3d8df6..72d296fc5f6b 100644
--- a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
+++ b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
@@ -598,6 +598,10 @@ class MediaRouter2ServiceImpl {
UserRecord userRecord = routerRecord.mUserRecord;
userRecord.mRouterRecords.remove(routerRecord);
+ routerRecord.mUserRecord.mHandler.sendMessage(
+ obtainMessage(UserHandler::notifyPreferredFeaturesChangedToManagers,
+ routerRecord.mUserRecord.mHandler,
+ routerRecord.mPackageName, /* preferredFeatures=*/ null));
userRecord.mHandler.sendMessage(
obtainMessage(UserHandler::updateDiscoveryPreferenceOnHandler,
userRecord.mHandler));
@@ -613,7 +617,9 @@ class MediaRouter2ServiceImpl {
routerRecord.mDiscoveryPreference = discoveryRequest;
routerRecord.mUserRecord.mHandler.sendMessage(
obtainMessage(UserHandler::notifyPreferredFeaturesChangedToManagers,
- routerRecord.mUserRecord.mHandler, routerRecord));
+ routerRecord.mUserRecord.mHandler,
+ routerRecord.mPackageName,
+ routerRecord.mDiscoveryPreference.getPreferredFeatures()));
routerRecord.mUserRecord.mHandler.sendMessage(
obtainMessage(UserHandler::updateDiscoveryPreferenceOnHandler,
routerRecord.mUserRecord.mHandler));
@@ -979,6 +985,7 @@ class MediaRouter2ServiceImpl {
if (userRecord == null) {
userRecord = new UserRecord(userId);
mUserRecords.put(userId, userRecord);
+ userRecord.init();
if (userId == mCurrentUserId) {
userRecord.mHandler.sendMessage(
obtainMessage(UserHandler::start, userRecord.mHandler));
@@ -1028,6 +1035,10 @@ class MediaRouter2ServiceImpl {
mHandler = new UserHandler(MediaRouter2ServiceImpl.this, this);
}
+ void init() {
+ mHandler.init();
+ }
+
// TODO: This assumes that only one router exists in a package.
// Do this in Android S or later.
RouterRecord findRouterRecordLocked(String packageName) {
@@ -1135,16 +1146,21 @@ class MediaRouter2ServiceImpl {
private boolean mRunning;
+ // TODO: (In Android S+) Pull out SystemMediaRoute2Provider out of UserHandler.
UserHandler(@NonNull MediaRouter2ServiceImpl service, @NonNull UserRecord userRecord) {
super(Looper.getMainLooper(), null, true);
mServiceRef = new WeakReference<>(service);
mUserRecord = userRecord;
- mSystemProvider = new SystemMediaRoute2Provider(service.mContext, this);
+ mSystemProvider = new SystemMediaRoute2Provider(service.mContext);
mRouteProviders.add(mSystemProvider);
mWatcher = new MediaRoute2ProviderWatcher(service.mContext, this,
this, mUserRecord.mUserId);
}
+ void init() {
+ mSystemProvider.setCallback(this);
+ }
+
private void start() {
if (!mRunning) {
mRunning = true;
@@ -1954,7 +1970,8 @@ class MediaRouter2ServiceImpl {
}
}
- private void notifyPreferredFeaturesChangedToManagers(@NonNull RouterRecord routerRecord) {
+ private void notifyPreferredFeaturesChangedToManagers(@NonNull String routerPackageName,
+ @Nullable List<String> preferredFeatures) {
MediaRouter2ServiceImpl service = mServiceRef.get();
if (service == null) {
return;
@@ -1967,8 +1984,7 @@ class MediaRouter2ServiceImpl {
}
for (IMediaRouter2Manager manager : managers) {
try {
- manager.notifyPreferredFeaturesChanged(routerRecord.mPackageName,
- routerRecord.mDiscoveryPreference.getPreferredFeatures());
+ manager.notifyPreferredFeaturesChanged(routerPackageName, preferredFeatures);
} catch (RemoteException ex) {
Slog.w(TAG, "Failed to notify preferred features changed."
+ " Manager probably died.", ex);
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index afae20dcf525..242132c8e5ff 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -830,9 +830,6 @@ public class MediaSessionService extends SystemService implements Monitor {
private IOnVolumeKeyLongPressListener mOnVolumeKeyLongPressListener;
private int mOnVolumeKeyLongPressListenerUid;
- private KeyEvent mInitialDownVolumeKeyEvent;
- private int mInitialDownVolumeStream;
- private boolean mInitialDownMusicOnly;
private IOnMediaKeyListener mOnMediaKeyListener;
private int mOnMediaKeyListenerUid;
@@ -1104,12 +1101,10 @@ public class MediaSessionService extends SystemService implements Monitor {
"android.media.AudioService.WAKELOCK_ACQUIRED";
private static final int WAKELOCK_RELEASE_ON_FINISHED = 1980; // magic number
- private KeyEvent mTrackingFirstDownKeyEvent = null;
- private boolean mIsLongPressing = false;
- private Runnable mLongPressTimeoutRunnable = null;
- private int mMultiTapCount = 0;
- private int mMultiTapKeyCode = 0;
- private Runnable mMultiTapTimeoutRunnable = null;
+ private KeyEventHandler mMediaKeyEventHandler =
+ new KeyEventHandler(KeyEventHandler.KEY_TYPE_MEDIA);
+ private KeyEventHandler mVolumeKeyEventHandler =
+ new KeyEventHandler(KeyEventHandler.KEY_TYPE_VOLUME);
@Override
public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
@@ -1387,8 +1382,8 @@ public class MediaSessionService extends SystemService implements Monitor {
dispatchMediaKeyEventLocked(packageName, pid, uid, asSystemService,
keyEvent, needWakeLock);
} else {
- handleKeyEventLocked(packageName, pid, uid, asSystemService, keyEvent,
- needWakeLock);
+ mMediaKeyEventHandler.handleMediaKeyEventLocked(packageName, pid, uid,
+ asSystemService, keyEvent, needWakeLock);
}
}
} finally {
@@ -1710,53 +1705,14 @@ public class MediaSessionService extends SystemService implements Monitor {
try {
synchronized (mLock) {
- if (isGlobalPriorityActiveLocked()
- || mCurrentFullUserRecord.mOnVolumeKeyLongPressListener == null) {
+ if (isGlobalPriorityActiveLocked()) {
dispatchVolumeKeyEventLocked(packageName, opPackageName, pid, uid,
asSystemService, keyEvent, stream, musicOnly);
} else {
// TODO: Consider the case when both volume up and down keys are pressed
// at the same time.
- if (keyEvent.getAction() == KeyEvent.ACTION_DOWN) {
- if (keyEvent.getRepeatCount() == 0) {
- // Keeps the copy of the KeyEvent because it can be reused.
- mCurrentFullUserRecord.mInitialDownVolumeKeyEvent =
- KeyEvent.obtain(keyEvent);
- mCurrentFullUserRecord.mInitialDownVolumeStream = stream;
- mCurrentFullUserRecord.mInitialDownMusicOnly = musicOnly;
- mHandler.sendMessageDelayed(
- mHandler.obtainMessage(
- MessageHandler.MSG_VOLUME_INITIAL_DOWN,
- mCurrentFullUserRecord.mFullUserId, 0),
- LONG_PRESS_TIMEOUT);
- }
- if (keyEvent.getRepeatCount() > 0 || keyEvent.isLongPress()) {
- mHandler.removeMessages(MessageHandler.MSG_VOLUME_INITIAL_DOWN);
- if (mCurrentFullUserRecord.mInitialDownVolumeKeyEvent != null) {
- dispatchVolumeKeyLongPressLocked(
- mCurrentFullUserRecord.mInitialDownVolumeKeyEvent);
- // Mark that the key is already handled.
- mCurrentFullUserRecord.mInitialDownVolumeKeyEvent = null;
- }
- dispatchVolumeKeyLongPressLocked(keyEvent);
- }
- } else { // if up
- mHandler.removeMessages(MessageHandler.MSG_VOLUME_INITIAL_DOWN);
- if (mCurrentFullUserRecord.mInitialDownVolumeKeyEvent != null
- && mCurrentFullUserRecord.mInitialDownVolumeKeyEvent
- .getDownTime() == keyEvent.getDownTime()) {
- // Short-press. Should change volume.
- dispatchVolumeKeyEventLocked(packageName, opPackageName, pid, uid,
- asSystemService,
- mCurrentFullUserRecord.mInitialDownVolumeKeyEvent,
- mCurrentFullUserRecord.mInitialDownVolumeStream,
- mCurrentFullUserRecord.mInitialDownMusicOnly);
- dispatchVolumeKeyEventLocked(packageName, opPackageName, pid, uid,
- asSystemService, keyEvent, stream, musicOnly);
- } else {
- dispatchVolumeKeyLongPressLocked(keyEvent);
- }
- }
+ mVolumeKeyEventHandler.handleVolumeKeyEventLocked(packageName, pid, uid,
+ asSystemService, keyEvent, opPackageName, stream, musicOnly);
}
}
} finally {
@@ -2136,266 +2092,6 @@ public class MediaSessionService extends SystemService implements Monitor {
}
}
- // A long press is determined by:
- // 1) A KeyEvent.ACTION_DOWN KeyEvent and repeat count of 0, followed by
- // 2) A KeyEvent.ACTION_DOWN KeyEvent with the same key code, a repeat count of 1, and
- // FLAG_LONG_PRESS received within ViewConfiguration.getLongPressTimeout().
- // A tap is determined by:
- // 1) A KeyEvent.ACTION_DOWN KeyEvent followed by
- // 2) A KeyEvent.ACTION_UP KeyEvent with the same key code.
- private void handleKeyEventLocked(String packageName, int pid, int uid,
- boolean asSystemService, KeyEvent keyEvent, boolean needWakeLock) {
- if (keyEvent.isCanceled()) {
- return;
- }
-
- int overriddenKeyEvents = (mCustomMediaKeyDispatcher == null) ? 0
- : mCustomMediaKeyDispatcher.getOverriddenKeyEvents().get(keyEvent.getKeyCode());
- cancelTrackingIfNeeded(packageName, pid, uid, asSystemService, keyEvent, needWakeLock,
- overriddenKeyEvents);
- if (!needTracking(keyEvent, overriddenKeyEvents)) {
- dispatchMediaKeyEventLocked(packageName, pid, uid, asSystemService, keyEvent,
- needWakeLock);
- return;
- }
-
- if (isFirstDownKeyEvent(keyEvent)) {
- mTrackingFirstDownKeyEvent = keyEvent;
- mIsLongPressing = false;
- return;
- }
-
- // Long press is always overridden here, otherwise the key event would have been already
- // handled
- if (isFirstLongPressKeyEvent(keyEvent)) {
- mIsLongPressing = true;
- }
- if (mIsLongPressing) {
- handleLongPressLocked(keyEvent, needWakeLock, overriddenKeyEvents);
- return;
- }
-
- if (keyEvent.getAction() == KeyEvent.ACTION_UP) {
- mTrackingFirstDownKeyEvent = null;
- if (shouldTrackForMultipleTapsLocked(overriddenKeyEvents)) {
- if (mMultiTapCount == 0) {
- mMultiTapTimeoutRunnable = createSingleTapRunnable(packageName, pid, uid,
- asSystemService, keyEvent, needWakeLock,
- isSingleTapOverridden(overriddenKeyEvents));
- if (isSingleTapOverridden(overriddenKeyEvents)
- && !isDoubleTapOverridden(overriddenKeyEvents)
- && !isTripleTapOverridden(overriddenKeyEvents)) {
- mMultiTapTimeoutRunnable.run();
- } else {
- mHandler.postDelayed(mMultiTapTimeoutRunnable,
- MULTI_TAP_TIMEOUT);
- mMultiTapCount = 1;
- mMultiTapKeyCode = keyEvent.getKeyCode();
- }
- } else if (mMultiTapCount == 1) {
- mHandler.removeCallbacks(mMultiTapTimeoutRunnable);
- mMultiTapTimeoutRunnable = createDoubleTapRunnable(packageName, pid, uid,
- asSystemService, keyEvent, needWakeLock,
- isSingleTapOverridden(overriddenKeyEvents),
- isDoubleTapOverridden(overriddenKeyEvents));
- if (isTripleTapOverridden(overriddenKeyEvents)) {
- mHandler.postDelayed(mMultiTapTimeoutRunnable, MULTI_TAP_TIMEOUT);
- mMultiTapCount = 2;
- } else {
- mMultiTapTimeoutRunnable.run();
- }
- } else if (mMultiTapCount == 2) {
- mHandler.removeCallbacks(mMultiTapTimeoutRunnable);
- onTripleTap(keyEvent);
- }
- } else {
- dispatchDownAndUpKeyEventsLocked(packageName, pid, uid, asSystemService,
- keyEvent, needWakeLock);
- }
- }
- }
-
- private boolean shouldTrackForMultipleTapsLocked(int overriddenKeyEvents) {
- return isSingleTapOverridden(overriddenKeyEvents)
- || isDoubleTapOverridden(overriddenKeyEvents)
- || isTripleTapOverridden(overriddenKeyEvents);
- }
-
- private void cancelTrackingIfNeeded(String packageName, int pid, int uid,
- boolean asSystemService, KeyEvent keyEvent, boolean needWakeLock,
- int overriddenKeyEvents) {
- if (mTrackingFirstDownKeyEvent == null && mMultiTapTimeoutRunnable == null) {
- return;
- }
-
- if (isFirstDownKeyEvent(keyEvent)) {
- if (mLongPressTimeoutRunnable != null) {
- mHandler.removeCallbacks(mLongPressTimeoutRunnable);
- mLongPressTimeoutRunnable.run();
- }
- if (mMultiTapTimeoutRunnable != null && keyEvent.getKeyCode() != mMultiTapKeyCode) {
- runExistingMultiTapRunnableLocked();
- }
- resetLongPressTracking();
- return;
- }
-
- if (mTrackingFirstDownKeyEvent != null
- && mTrackingFirstDownKeyEvent.getDownTime() == keyEvent.getDownTime()
- && mTrackingFirstDownKeyEvent.getKeyCode() == keyEvent.getKeyCode()
- && keyEvent.getAction() == KeyEvent.ACTION_DOWN) {
- if (isFirstLongPressKeyEvent(keyEvent)) {
- if (mMultiTapTimeoutRunnable != null) {
- runExistingMultiTapRunnableLocked();
- }
- if ((overriddenKeyEvents & KEY_EVENT_LONG_PRESS) == 0
- && !isVoiceKey(keyEvent.getKeyCode())) {
- dispatchMediaKeyEventLocked(packageName, pid, uid, asSystemService,
- mTrackingFirstDownKeyEvent, needWakeLock);
- mTrackingFirstDownKeyEvent = null;
- }
- } else if (keyEvent.getRepeatCount() > 1 && !mIsLongPressing) {
- resetLongPressTracking();
- }
- }
- }
-
- private boolean needTracking(KeyEvent keyEvent, int overriddenKeyEvents) {
- if (!isFirstDownKeyEvent(keyEvent)) {
- if (mTrackingFirstDownKeyEvent == null) {
- return false;
- } else if (mTrackingFirstDownKeyEvent.getDownTime() != keyEvent.getDownTime()
- || mTrackingFirstDownKeyEvent.getKeyCode() != keyEvent.getKeyCode()) {
- return false;
- }
- }
- if (overriddenKeyEvents == 0 && !isVoiceKey(keyEvent.getKeyCode())) {
- return false;
- }
- return true;
- }
-
- private void runExistingMultiTapRunnableLocked() {
- mHandler.removeCallbacks(mMultiTapTimeoutRunnable);
- mMultiTapTimeoutRunnable.run();
- }
-
- private void resetMultiTapTrackingLocked() {
- mMultiTapCount = 0;
- mMultiTapTimeoutRunnable = null;
- mMultiTapKeyCode = 0;
- }
-
- private void handleLongPressLocked(KeyEvent keyEvent, boolean needWakeLock,
- int overriddenKeyEvents) {
- if (mCustomMediaKeyDispatcher != null
- && isLongPressOverridden(overriddenKeyEvents)) {
- mCustomMediaKeyDispatcher.onLongPress(keyEvent);
-
- if (mLongPressTimeoutRunnable != null) {
- mHandler.removeCallbacks(mLongPressTimeoutRunnable);
- }
- if (keyEvent.getAction() == KeyEvent.ACTION_DOWN) {
- if (mLongPressTimeoutRunnable == null) {
- mLongPressTimeoutRunnable = createLongPressTimeoutRunnable(keyEvent);
- }
- mHandler.postDelayed(mLongPressTimeoutRunnable, LONG_PRESS_TIMEOUT);
- } else {
- resetLongPressTracking();
- }
- } else if (isFirstLongPressKeyEvent(keyEvent) && isVoiceKey(keyEvent.getKeyCode())) {
- // Default implementation
- startVoiceInput(needWakeLock);
- resetLongPressTracking();
- }
- }
-
- private Runnable createLongPressTimeoutRunnable(KeyEvent keyEvent) {
- return new Runnable() {
- @Override
- public void run() {
- if (mCustomMediaKeyDispatcher != null) {
- mCustomMediaKeyDispatcher.onLongPress(createCanceledKeyEvent(keyEvent));
- }
- resetLongPressTracking();
- }
- };
- }
-
- private void resetLongPressTracking() {
- mTrackingFirstDownKeyEvent = null;
- mIsLongPressing = false;
- mLongPressTimeoutRunnable = null;
- }
-
- private KeyEvent createCanceledKeyEvent(KeyEvent keyEvent) {
- KeyEvent upEvent = KeyEvent.changeAction(keyEvent, KeyEvent.ACTION_UP);
- return KeyEvent.changeTimeRepeat(upEvent, System.currentTimeMillis(), 0,
- KeyEvent.FLAG_CANCELED);
- }
-
- private boolean isFirstLongPressKeyEvent(KeyEvent keyEvent) {
- return ((keyEvent.getFlags() & KeyEvent.FLAG_LONG_PRESS) != 0)
- && keyEvent.getRepeatCount() == 1;
- }
-
- private boolean isFirstDownKeyEvent(KeyEvent keyEvent) {
- return keyEvent.getAction() == KeyEvent.ACTION_DOWN && keyEvent.getRepeatCount() == 0;
- }
-
- private void dispatchDownAndUpKeyEventsLocked(String packageName, int pid, int uid,
- boolean asSystemService, KeyEvent keyEvent, boolean needWakeLock) {
- KeyEvent downEvent = KeyEvent.changeAction(keyEvent, KeyEvent.ACTION_DOWN);
- dispatchMediaKeyEventLocked(packageName, pid, uid, asSystemService,
- downEvent, needWakeLock);
- dispatchMediaKeyEventLocked(packageName, pid, uid, asSystemService,
- keyEvent, needWakeLock);
- }
-
- Runnable createSingleTapRunnable(String packageName, int pid, int uid,
- boolean asSystemService, KeyEvent keyEvent, boolean needWakeLock,
- boolean overridden) {
- return new Runnable() {
- @Override
- public void run() {
- resetMultiTapTrackingLocked();
- if (overridden) {
- mCustomMediaKeyDispatcher.onSingleTap(keyEvent);
- } else {
- dispatchDownAndUpKeyEventsLocked(packageName, pid, uid, asSystemService,
- keyEvent, needWakeLock);
- }
- }
- };
- };
-
- Runnable createDoubleTapRunnable(String packageName, int pid, int uid,
- boolean asSystemService, KeyEvent keyEvent, boolean needWakeLock,
- boolean singleTapOverridden, boolean doubleTapOverridden) {
- return new Runnable() {
- @Override
- public void run() {
- resetMultiTapTrackingLocked();
- if (doubleTapOverridden) {
- mCustomMediaKeyDispatcher.onDoubleTap(keyEvent);
- } else if (singleTapOverridden) {
- mCustomMediaKeyDispatcher.onSingleTap(keyEvent);
- mCustomMediaKeyDispatcher.onSingleTap(keyEvent);
- } else {
- dispatchDownAndUpKeyEventsLocked(packageName, pid, uid, asSystemService,
- keyEvent, needWakeLock);
- dispatchDownAndUpKeyEventsLocked(packageName, pid, uid, asSystemService,
- keyEvent, needWakeLock);
- }
- }
- };
- };
-
- private void onTripleTap(KeyEvent keyEvent) {
- resetMultiTapTrackingLocked();
- mCustomMediaKeyDispatcher.onTripleTap(keyEvent);
- }
-
private void dispatchMediaKeyEventLocked(String packageName, int pid, int uid,
boolean asSystemService, KeyEvent keyEvent, boolean needWakeLock) {
if (mCurrentFullUserRecord.getMediaButtonSessionLocked()
@@ -2579,8 +2275,8 @@ public class MediaSessionService extends SystemService implements Monitor {
dispatchMediaKeyEventLocked(mPackageName, mPid, mUid, mAsSystemService,
mKeyEvent, mNeedWakeLock);
} else {
- handleKeyEventLocked(mPackageName, mPid, mUid, mAsSystemService,
- mKeyEvent, mNeedWakeLock);
+ mMediaKeyEventHandler.handleMediaKeyEventLocked(mPackageName, mPid, mUid,
+ mAsSystemService, mKeyEvent, mNeedWakeLock);
}
}
}
@@ -2655,12 +2351,341 @@ public class MediaSessionService extends SystemService implements Monitor {
onReceiveResult(resultCode, null);
}
};
+
+ // A long press is determined by:
+ // 1) A KeyEvent.ACTION_DOWN KeyEvent and repeat count of 0, followed by
+ // 2) A KeyEvent.ACTION_DOWN KeyEvent with the same key code, a repeat count of 1, and
+ // FLAG_LONG_PRESS received within ViewConfiguration.getLongPressTimeout().
+ // A tap is determined by:
+ // 1) A KeyEvent.ACTION_DOWN KeyEvent followed by
+ // 2) A KeyEvent.ACTION_UP KeyEvent with the same key code.
+ class KeyEventHandler {
+ private static final int KEY_TYPE_MEDIA = 0;
+ private static final int KEY_TYPE_VOLUME = 1;
+
+ private KeyEvent mTrackingFirstDownKeyEvent;
+ private boolean mIsLongPressing;
+ private Runnable mLongPressTimeoutRunnable;
+ private int mMultiTapCount;
+ private Runnable mMultiTapTimeoutRunnable;
+ private int mMultiTapKeyCode;
+ private int mKeyType;
+
+ KeyEventHandler(int keyType) {
+ mKeyType = keyType;
+ }
+
+ void handleMediaKeyEventLocked(String packageName, int pid, int uid,
+ boolean asSystemService, KeyEvent keyEvent, boolean needWakeLock) {
+ handleKeyEventLocked(packageName, pid, uid, asSystemService, keyEvent, needWakeLock,
+ null, 0, false);
+ }
+
+ void handleVolumeKeyEventLocked(String packageName, int pid, int uid,
+ boolean asSystemService, KeyEvent keyEvent, String opPackageName, int stream,
+ boolean musicOnly) {
+ handleKeyEventLocked(packageName, pid, uid, asSystemService, keyEvent, false,
+ opPackageName, stream, musicOnly);
+ }
+
+ void handleKeyEventLocked(String packageName, int pid, int uid,
+ boolean asSystemService, KeyEvent keyEvent, boolean needWakeLock,
+ String opPackageName, int stream, boolean musicOnly) {
+ if (keyEvent.isCanceled()) {
+ return;
+ }
+
+ int overriddenKeyEvents = (mCustomMediaKeyDispatcher == null) ? 0
+ : mCustomMediaKeyDispatcher.getOverriddenKeyEvents()
+ .get(keyEvent.getKeyCode());
+ cancelTrackingIfNeeded(packageName, pid, uid, asSystemService, keyEvent,
+ needWakeLock, opPackageName, stream, musicOnly, overriddenKeyEvents);
+ if (!needTracking(keyEvent, overriddenKeyEvents)) {
+ if (mKeyType == KEY_TYPE_VOLUME) {
+ dispatchVolumeKeyEventLocked(packageName, opPackageName, pid, uid,
+ asSystemService, keyEvent, stream, musicOnly);
+ } else {
+ dispatchMediaKeyEventLocked(packageName, pid, uid, asSystemService,
+ keyEvent, needWakeLock);
+ }
+ return;
+ }
+
+ if (isFirstDownKeyEvent(keyEvent)) {
+ mTrackingFirstDownKeyEvent = keyEvent;
+ mIsLongPressing = false;
+ return;
+ }
+
+ // Long press is always overridden here, otherwise the key event would have been
+ // already handled
+ if (isFirstLongPressKeyEvent(keyEvent)) {
+ mIsLongPressing = true;
+ }
+ if (mIsLongPressing) {
+ handleLongPressLocked(keyEvent, needWakeLock, overriddenKeyEvents);
+ return;
+ }
+
+ if (keyEvent.getAction() == KeyEvent.ACTION_UP) {
+ mTrackingFirstDownKeyEvent = null;
+ if (shouldTrackForMultipleTapsLocked(overriddenKeyEvents)) {
+ if (mMultiTapCount == 0) {
+ mMultiTapTimeoutRunnable = createSingleTapRunnable(packageName, pid,
+ uid, asSystemService, keyEvent, needWakeLock,
+ opPackageName, stream, musicOnly,
+ isSingleTapOverridden(overriddenKeyEvents));
+ if (isSingleTapOverridden(overriddenKeyEvents)
+ && !isDoubleTapOverridden(overriddenKeyEvents)
+ && !isTripleTapOverridden(overriddenKeyEvents)) {
+ mMultiTapTimeoutRunnable.run();
+ } else {
+ mHandler.postDelayed(mMultiTapTimeoutRunnable,
+ MULTI_TAP_TIMEOUT);
+ mMultiTapCount = 1;
+ mMultiTapKeyCode = keyEvent.getKeyCode();
+ }
+ } else if (mMultiTapCount == 1) {
+ mHandler.removeCallbacks(mMultiTapTimeoutRunnable);
+ mMultiTapTimeoutRunnable = createDoubleTapRunnable(packageName, pid,
+ uid, asSystemService, keyEvent, needWakeLock, opPackageName,
+ stream, musicOnly, isSingleTapOverridden(overriddenKeyEvents),
+ isDoubleTapOverridden(overriddenKeyEvents));
+ if (isTripleTapOverridden(overriddenKeyEvents)) {
+ mHandler.postDelayed(mMultiTapTimeoutRunnable, MULTI_TAP_TIMEOUT);
+ mMultiTapCount = 2;
+ } else {
+ mMultiTapTimeoutRunnable.run();
+ }
+ } else if (mMultiTapCount == 2) {
+ mHandler.removeCallbacks(mMultiTapTimeoutRunnable);
+ onTripleTap(keyEvent);
+ }
+ } else {
+ dispatchDownAndUpKeyEventsLocked(packageName, pid, uid, asSystemService,
+ keyEvent, needWakeLock, opPackageName, stream, musicOnly);
+ }
+ }
+ }
+
+ private boolean shouldTrackForMultipleTapsLocked(int overriddenKeyEvents) {
+ return isSingleTapOverridden(overriddenKeyEvents)
+ || isDoubleTapOverridden(overriddenKeyEvents)
+ || isTripleTapOverridden(overriddenKeyEvents);
+ }
+
+ private void cancelTrackingIfNeeded(String packageName, int pid, int uid,
+ boolean asSystemService, KeyEvent keyEvent, boolean needWakeLock,
+ String opPackageName, int stream, boolean musicOnly, int overriddenKeyEvents) {
+ if (mTrackingFirstDownKeyEvent == null && mMultiTapTimeoutRunnable == null) {
+ return;
+ }
+
+ if (isFirstDownKeyEvent(keyEvent)) {
+ if (mLongPressTimeoutRunnable != null) {
+ mHandler.removeCallbacks(mLongPressTimeoutRunnable);
+ mLongPressTimeoutRunnable.run();
+ }
+ if (mMultiTapTimeoutRunnable != null
+ && keyEvent.getKeyCode() != mMultiTapKeyCode) {
+ runExistingMultiTapRunnableLocked();
+ }
+ resetLongPressTracking();
+ return;
+ }
+
+ if (mTrackingFirstDownKeyEvent != null
+ && mTrackingFirstDownKeyEvent.getDownTime() == keyEvent.getDownTime()
+ && mTrackingFirstDownKeyEvent.getKeyCode() == keyEvent.getKeyCode()
+ && keyEvent.getAction() == KeyEvent.ACTION_DOWN) {
+ if (isFirstLongPressKeyEvent(keyEvent)) {
+ if (mMultiTapTimeoutRunnable != null) {
+ runExistingMultiTapRunnableLocked();
+ }
+ if ((overriddenKeyEvents & KEY_EVENT_LONG_PRESS) == 0) {
+ if (mKeyType == KEY_TYPE_VOLUME) {
+ if (mCurrentFullUserRecord.mOnVolumeKeyLongPressListener == null) {
+ dispatchVolumeKeyEventLocked(packageName, opPackageName, pid,
+ uid, asSystemService, keyEvent, stream, musicOnly);
+ mTrackingFirstDownKeyEvent = null;
+ }
+ } else if (!isVoiceKey(keyEvent.getKeyCode())) {
+ dispatchMediaKeyEventLocked(packageName, pid, uid, asSystemService,
+ keyEvent, needWakeLock);
+ mTrackingFirstDownKeyEvent = null;
+ }
+ }
+ } else if (keyEvent.getRepeatCount() > 1 && !mIsLongPressing) {
+ resetLongPressTracking();
+ }
+ }
+ }
+
+ private boolean needTracking(KeyEvent keyEvent, int overriddenKeyEvents) {
+ if (!isFirstDownKeyEvent(keyEvent)) {
+ if (mTrackingFirstDownKeyEvent == null) {
+ return false;
+ } else if (mTrackingFirstDownKeyEvent.getDownTime() != keyEvent.getDownTime()
+ || mTrackingFirstDownKeyEvent.getKeyCode() != keyEvent.getKeyCode()) {
+ return false;
+ }
+ }
+ if (overriddenKeyEvents == 0) {
+ if (mKeyType == KEY_TYPE_VOLUME) {
+ if (mCurrentFullUserRecord.mOnVolumeKeyLongPressListener == null) {
+ return false;
+ }
+ } else if (!isVoiceKey(keyEvent.getKeyCode())) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private void runExistingMultiTapRunnableLocked() {
+ mHandler.removeCallbacks(mMultiTapTimeoutRunnable);
+ mMultiTapTimeoutRunnable.run();
+ }
+
+ private void resetMultiTapTrackingLocked() {
+ mMultiTapCount = 0;
+ mMultiTapTimeoutRunnable = null;
+ mMultiTapKeyCode = 0;
+ }
+
+ private void handleLongPressLocked(KeyEvent keyEvent, boolean needWakeLock,
+ int overriddenKeyEvents) {
+ if (mCustomMediaKeyDispatcher != null
+ && isLongPressOverridden(overriddenKeyEvents)) {
+ mCustomMediaKeyDispatcher.onLongPress(keyEvent);
+
+ if (mLongPressTimeoutRunnable != null) {
+ mHandler.removeCallbacks(mLongPressTimeoutRunnable);
+ }
+ if (keyEvent.getAction() == KeyEvent.ACTION_DOWN) {
+ if (mLongPressTimeoutRunnable == null) {
+ mLongPressTimeoutRunnable = createLongPressTimeoutRunnable(keyEvent);
+ }
+ mHandler.postDelayed(mLongPressTimeoutRunnable, LONG_PRESS_TIMEOUT);
+ } else {
+ resetLongPressTracking();
+ }
+ } else {
+ if (mKeyType == KEY_TYPE_VOLUME) {
+ if (isFirstLongPressKeyEvent(keyEvent)) {
+ dispatchVolumeKeyLongPressLocked(mTrackingFirstDownKeyEvent);
+ }
+ dispatchVolumeKeyLongPressLocked(keyEvent);
+ } else if (isFirstLongPressKeyEvent(keyEvent)
+ && isVoiceKey(keyEvent.getKeyCode())) {
+ // Default implementation
+ startVoiceInput(needWakeLock);
+ resetLongPressTracking();
+ }
+ }
+ }
+
+ private Runnable createLongPressTimeoutRunnable(KeyEvent keyEvent) {
+ return new Runnable() {
+ @Override
+ public void run() {
+ if (mCustomMediaKeyDispatcher != null) {
+ mCustomMediaKeyDispatcher.onLongPress(createCanceledKeyEvent(keyEvent));
+ }
+ resetLongPressTracking();
+ }
+ };
+ }
+
+ private void resetLongPressTracking() {
+ mTrackingFirstDownKeyEvent = null;
+ mIsLongPressing = false;
+ mLongPressTimeoutRunnable = null;
+ }
+
+ private KeyEvent createCanceledKeyEvent(KeyEvent keyEvent) {
+ KeyEvent upEvent = KeyEvent.changeAction(keyEvent, KeyEvent.ACTION_UP);
+ return KeyEvent.changeTimeRepeat(upEvent, System.currentTimeMillis(), 0,
+ KeyEvent.FLAG_CANCELED);
+ }
+
+ private boolean isFirstLongPressKeyEvent(KeyEvent keyEvent) {
+ return ((keyEvent.getFlags() & KeyEvent.FLAG_LONG_PRESS) != 0)
+ && keyEvent.getRepeatCount() == 1;
+ }
+
+ private boolean isFirstDownKeyEvent(KeyEvent keyEvent) {
+ return keyEvent.getAction() == KeyEvent.ACTION_DOWN
+ && keyEvent.getRepeatCount() == 0;
+ }
+
+ private void dispatchDownAndUpKeyEventsLocked(String packageName, int pid, int uid,
+ boolean asSystemService, KeyEvent keyEvent, boolean needWakeLock,
+ String opPackageName, int stream, boolean musicOnly) {
+ KeyEvent downEvent = KeyEvent.changeAction(keyEvent, KeyEvent.ACTION_DOWN);
+ if (mKeyType == KEY_TYPE_VOLUME) {
+ dispatchVolumeKeyEventLocked(packageName, opPackageName, pid, uid,
+ asSystemService, downEvent, stream, musicOnly);
+ dispatchVolumeKeyEventLocked(packageName, opPackageName, pid, uid,
+ asSystemService, keyEvent, stream, musicOnly);
+ } else {
+ dispatchMediaKeyEventLocked(packageName, pid, uid, asSystemService, downEvent,
+ needWakeLock);
+ dispatchMediaKeyEventLocked(packageName, pid, uid, asSystemService, keyEvent,
+ needWakeLock);
+ }
+ }
+
+ Runnable createSingleTapRunnable(String packageName, int pid, int uid,
+ boolean asSystemService, KeyEvent keyEvent, boolean needWakeLock,
+ String opPackageName, int stream, boolean musicOnly, boolean overridden) {
+ return new Runnable() {
+ @Override
+ public void run() {
+ resetMultiTapTrackingLocked();
+ if (overridden) {
+ mCustomMediaKeyDispatcher.onSingleTap(keyEvent);
+ } else {
+ dispatchDownAndUpKeyEventsLocked(packageName, pid, uid, asSystemService,
+ keyEvent, needWakeLock, opPackageName, stream, musicOnly);
+ }
+ }
+ };
+ };
+
+ Runnable createDoubleTapRunnable(String packageName, int pid, int uid,
+ boolean asSystemService, KeyEvent keyEvent, boolean needWakeLock,
+ String opPackageName, int stream, boolean musicOnly,
+ boolean singleTapOverridden, boolean doubleTapOverridden) {
+ return new Runnable() {
+ @Override
+ public void run() {
+ resetMultiTapTrackingLocked();
+ if (doubleTapOverridden) {
+ mCustomMediaKeyDispatcher.onDoubleTap(keyEvent);
+ } else if (singleTapOverridden) {
+ mCustomMediaKeyDispatcher.onSingleTap(keyEvent);
+ mCustomMediaKeyDispatcher.onSingleTap(keyEvent);
+ } else {
+ dispatchDownAndUpKeyEventsLocked(packageName, pid, uid, asSystemService,
+ keyEvent, needWakeLock, opPackageName, stream, musicOnly);
+ dispatchDownAndUpKeyEventsLocked(packageName, pid, uid, asSystemService,
+ keyEvent, needWakeLock, opPackageName, stream, musicOnly);
+ }
+ }
+ };
+ };
+
+ private void onTripleTap(KeyEvent keyEvent) {
+ resetMultiTapTrackingLocked();
+ mCustomMediaKeyDispatcher.onTripleTap(keyEvent);
+ }
+ }
}
final class MessageHandler extends Handler {
private static final int MSG_SESSIONS_1_CHANGED = 1;
private static final int MSG_SESSIONS_2_CHANGED = 2;
- private static final int MSG_VOLUME_INITIAL_DOWN = 3;
private final SparseArray<Integer> mIntegerCache = new SparseArray<>();
@Override
@@ -2672,16 +2697,6 @@ public class MediaSessionService extends SystemService implements Monitor {
case MSG_SESSIONS_2_CHANGED:
pushSession2Changed((int) msg.obj);
break;
- case MSG_VOLUME_INITIAL_DOWN:
- synchronized (mLock) {
- FullUserRecord user = mUserRecords.get((int) msg.arg1);
- if (user != null && user.mInitialDownVolumeKeyEvent != null) {
- dispatchVolumeKeyLongPressLocked(user.mInitialDownVolumeKeyEvent);
- // Mark that the key is already handled.
- user.mInitialDownVolumeKeyEvent = null;
- }
- }
- break;
}
}
diff --git a/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java b/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java
index d7e724780c94..42d4c88959bd 100644
--- a/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java
+++ b/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java
@@ -18,6 +18,7 @@ package com.android.server.media;
import static android.media.MediaRoute2Info.FEATURE_LIVE_AUDIO;
import static android.media.MediaRoute2Info.FEATURE_LIVE_VIDEO;
+import static android.media.MediaRoute2Info.FEATURE_LOCAL_PLAYBACK;
import static android.media.MediaRoute2Info.TYPE_BUILTIN_SPEAKER;
import static android.media.MediaRoute2Info.TYPE_DOCK;
import static android.media.MediaRoute2Info.TYPE_HDMI;
@@ -45,6 +46,7 @@ import android.os.Looper;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.text.TextUtils;
+import android.util.Log;
import android.util.Slog;
import com.android.internal.R;
@@ -58,8 +60,7 @@ import java.util.Objects;
// TODO: check thread safety. We may need to use lock to protect variables.
class SystemMediaRoute2Provider extends MediaRoute2Provider {
private static final String TAG = "MR2SystemProvider";
- // TODO(b/156996903): Revert it when releasing the framework.
- private static final boolean DEBUG = true;
+ private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
static final String DEFAULT_ROUTE_ID = "DEFAULT_ROUTE";
static final String DEVICE_ROUTE_ID = "DEVICE_ROUTE";
@@ -98,12 +99,10 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider {
}
};
- SystemMediaRoute2Provider(Context context, Callback callback) {
+ SystemMediaRoute2Provider(Context context) {
super(sComponentName);
- setCallback(callback);
mIsSystemRouteProvider = true;
-
mContext = context;
mHandler = new Handler(Looper.getMainLooper());
@@ -143,6 +142,13 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider {
}
@Override
+ public void setCallback(Callback callback) {
+ super.setCallback(callback);
+ notifyProviderState();
+ notifySessionInfoUpdated();
+ }
+
+ @Override
public void requestCreateSession(long requestId, String packageName, String routeId,
Bundle sessionHints) {
// Assume a router without MODIFY_AUDIO_ROUTING permission can't request with
@@ -257,6 +263,7 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider {
.setType(type)
.addFeature(FEATURE_LIVE_AUDIO)
.addFeature(FEATURE_LIVE_VIDEO)
+ .addFeature(FEATURE_LOCAL_PLAYBACK)
.setConnectionState(MediaRoute2Info.CONNECTION_STATE_CONNECTED)
.build();
updateProviderState();
@@ -354,6 +361,10 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider {
}
void notifySessionInfoUpdated() {
+ if (mCallback == null) {
+ return;
+ }
+
RoutingSessionInfo sessionInfo;
synchronized (mLock) {
sessionInfo = mSessionInfos.get(0);
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 3283fd9b2c51..87f0fb14ee33 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -578,6 +578,10 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
private final NetworkPolicyLogger mLogger = new NetworkPolicyLogger();
+ /** List of apps indexed by appId and whether they have the internet permission */
+ @GuardedBy("mUidRulesFirstLock")
+ private final SparseBooleanArray mInternetPermissionMap = new SparseBooleanArray();
+
// TODO: keep whitelist of system-critical services that should never have
// rules enforced, such as system, phone, and radio UIDs.
@@ -958,7 +962,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
// update rules for UID, since it might be subject to
// global background data policy
if (LOGV) Slog.v(TAG, "ACTION_PACKAGE_ADDED for uid=" + uid);
+ // Clear the cache for the app
synchronized (mUidRulesFirstLock) {
+ mInternetPermissionMap.delete(UserHandle.getAppId(uid));
updateRestrictionRulesForUidUL(uid);
}
}
@@ -1000,7 +1006,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
synchronized (mUidRulesFirstLock) {
// Remove any persistable state for the given user; both cleaning up after a
// USER_REMOVED, and one last sanity check during USER_ADDED
- removeUserStateUL(userId, true);
+ removeUserStateUL(userId, true, false);
// Removing outside removeUserStateUL since that can also be called when
// user resets app preferences.
mMeteredRestrictedUids.remove(userId);
@@ -2613,7 +2619,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
setUidPolicyUncheckedUL(uid, policy, false);
final boolean notifyApp;
- if (!isUidValidForWhitelistRules(uid)) {
+ if (!isUidValidForWhitelistRulesUL(uid)) {
notifyApp = false;
} else {
final boolean wasBlacklisted = oldPolicy == POLICY_REJECT_METERED_BACKGROUND;
@@ -2689,7 +2695,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
* if any changes that are made.
*/
@GuardedBy("mUidRulesFirstLock")
- boolean removeUserStateUL(int userId, boolean writePolicy) {
+ boolean removeUserStateUL(int userId, boolean writePolicy, boolean updateGlobalRules) {
mLogger.removingUserState(userId);
boolean changed = false;
@@ -2719,7 +2725,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
changed = true;
}
synchronized (mNetworkPoliciesSecondLock) {
- updateRulesForGlobalChangeAL(true);
+ if (updateGlobalRules) {
+ updateRulesForGlobalChangeAL(true);
+ }
if (writePolicy && changed) {
writePolicyAL();
}
@@ -3859,7 +3867,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
// quick check: if this uid doesn't have INTERNET permission, it
// doesn't have network access anyway, so it is a waste to mess
// with it here.
- if (hasInternetPermissions(uid)) {
+ if (hasInternetPermissionUL(uid)) {
uidRules.put(uid, FIREWALL_RULE_DENY);
}
}
@@ -3874,7 +3882,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
@GuardedBy("mUidRulesFirstLock")
void updateRuleForAppIdleUL(int uid) {
- if (!isUidValidForBlacklistRules(uid)) return;
+ if (!isUidValidForBlacklistRulesUL(uid)) return;
if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) {
Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRuleForAppIdleUL: " + uid );
@@ -4056,18 +4064,20 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
// TODO: the MEDIA / DRM restriction might not be needed anymore, in which case both
// methods below could be merged into a isUidValidForRules() method.
- private boolean isUidValidForBlacklistRules(int uid) {
+ @GuardedBy("mUidRulesFirstLock")
+ private boolean isUidValidForBlacklistRulesUL(int uid) {
// allow rules on specific system services, and any apps
if (uid == android.os.Process.MEDIA_UID || uid == android.os.Process.DRM_UID
- || (UserHandle.isApp(uid) && hasInternetPermissions(uid))) {
+ || isUidValidForWhitelistRulesUL(uid)) {
return true;
}
return false;
}
- private boolean isUidValidForWhitelistRules(int uid) {
- return UserHandle.isApp(uid) && hasInternetPermissions(uid);
+ @GuardedBy("mUidRulesFirstLock")
+ private boolean isUidValidForWhitelistRulesUL(int uid) {
+ return UserHandle.isApp(uid) && hasInternetPermissionUL(uid);
}
/**
@@ -4143,12 +4153,20 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
* <p>
* Useful for the cases where the lack of network access can simplify the rules.
*/
- private boolean hasInternetPermissions(int uid) {
+ @GuardedBy("mUidRulesFirstLock")
+ private boolean hasInternetPermissionUL(int uid) {
try {
- if (mIPm.checkUidPermission(Manifest.permission.INTERNET, uid)
- != PackageManager.PERMISSION_GRANTED) {
- return false;
+ final int appId = UserHandle.getAppId(uid);
+ final boolean hasPermission;
+ if (mInternetPermissionMap.indexOfKey(appId) < 0) {
+ hasPermission =
+ mIPm.checkUidPermission(Manifest.permission.INTERNET, uid)
+ == PackageManager.PERMISSION_GRANTED;
+ mInternetPermissionMap.put(appId, hasPermission);
+ } else {
+ hasPermission = mInternetPermissionMap.get(appId);
}
+ return hasPermission;
} catch (RemoteException e) {
}
return true;
@@ -4253,7 +4271,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
}
private void updateRulesForDataUsageRestrictionsULInner(int uid) {
- if (!isUidValidForWhitelistRules(uid)) {
+ if (!isUidValidForWhitelistRulesUL(uid)) {
if (LOGD) Slog.d(TAG, "no need to update restrict data rules for uid " + uid);
return;
}
@@ -4400,6 +4418,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
*
* @return the new computed rules for the uid
*/
+ @GuardedBy("mUidRulesFirstLock")
private int updateRulesForPowerRestrictionsUL(int uid, int oldUidRules, boolean paroled) {
if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) {
Trace.traceBegin(Trace.TRACE_TAG_NETWORK,
@@ -4413,8 +4432,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
}
}
+ @GuardedBy("mUidRulesFirstLock")
private int updateRulesForPowerRestrictionsULInner(int uid, int oldUidRules, boolean paroled) {
- if (!isUidValidForBlacklistRules(uid)) {
+ if (!isUidValidForBlacklistRulesUL(uid)) {
if (LOGD) Slog.d(TAG, "no need to update restrict power rules for uid " + uid);
return RULE_NONE;
}
@@ -5198,7 +5218,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
@Override
public void resetUserState(int userId) {
synchronized (mUidRulesFirstLock) {
- boolean changed = removeUserStateUL(userId, false);
+ boolean changed = removeUserStateUL(userId, false, true);
changed = addDefaultRestrictBackgroundWhitelistUidsUL(userId) || changed;
if (changed) {
synchronized (mNetworkPoliciesSecondLock) {
diff --git a/services/core/java/com/android/server/notification/BadgeExtractor.java b/services/core/java/com/android/server/notification/BadgeExtractor.java
index d323d8095525..0681d95ad199 100644
--- a/services/core/java/com/android/server/notification/BadgeExtractor.java
+++ b/services/core/java/com/android/server/notification/BadgeExtractor.java
@@ -17,9 +17,9 @@ package com.android.server.notification;
import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_BADGE;
+import android.app.Notification;
import android.content.Context;
import android.util.Slog;
-import android.app.Notification;
/**
* Determines whether a badge should be shown for this notification
@@ -66,6 +66,17 @@ public class BadgeExtractor implements NotificationSignalExtractor {
if (metadata != null && metadata.isNotificationSuppressed()) {
record.setShowBadge(false);
}
+
+ if (mConfig.isMediaNotificationFilteringEnabled()) {
+ final Notification notif = record.getNotification();
+ if (notif.hasMediaSession()) {
+ Class<? extends Notification.Style> notifStyle = notif.getNotificationStyle();
+ if (Notification.DecoratedMediaCustomViewStyle.class.equals(notifStyle)
+ || Notification.MediaStyle.class.equals(notifStyle)) {
+ record.setShowBadge(false);
+ }
+ }
+ }
return null;
}
diff --git a/services/core/java/com/android/server/notification/CalendarTracker.java b/services/core/java/com/android/server/notification/CalendarTracker.java
index 3829b6580c59..cfcf6ebf9540 100644
--- a/services/core/java/com/android/server/notification/CalendarTracker.java
+++ b/services/core/java/com/android/server/notification/CalendarTracker.java
@@ -21,6 +21,7 @@ import android.content.ContentUris;
import android.content.Context;
import android.database.ContentObserver;
import android.database.Cursor;
+import android.database.sqlite.SQLiteException;
import android.net.Uri;
import android.provider.CalendarContract.Attendees;
import android.provider.CalendarContract.Calendars;
@@ -102,6 +103,8 @@ public class CalendarTracker {
while (cursor != null && cursor.moveToNext()) {
rt.add(cursor.getLong(0));
}
+ } catch (SQLiteException e) {
+ Slog.w(TAG, "error querying calendar content provider", e);
} finally {
if (cursor != null) {
cursor.close();
@@ -118,11 +121,12 @@ public class CalendarTracker {
ContentUris.appendId(uriBuilder, time);
ContentUris.appendId(uriBuilder, time + EVENT_CHECK_LOOKAHEAD);
final Uri uri = uriBuilder.build();
- final Cursor cursor = mUserContext.getContentResolver().query(uri, INSTANCE_PROJECTION,
- null, null, INSTANCE_ORDER_BY);
+ Cursor cursor = null;
final CheckEventResult result = new CheckEventResult();
result.recheckAt = time + EVENT_CHECK_LOOKAHEAD;
try {
+ cursor = mUserContext.getContentResolver().query(uri, INSTANCE_PROJECTION,
+ null, null, INSTANCE_ORDER_BY);
final ArraySet<Long> calendars = getCalendarsWithAccess();
while (cursor != null && cursor.moveToNext()) {
final long begin = cursor.getLong(0);
@@ -183,9 +187,10 @@ public class CalendarTracker {
selection = null;
selectionArgs = null;
}
- final Cursor cursor = mUserContext.getContentResolver().query(Attendees.CONTENT_URI,
- ATTENDEE_PROJECTION, selection, selectionArgs, null);
+ Cursor cursor = null;
try {
+ cursor = mUserContext.getContentResolver().query(Attendees.CONTENT_URI,
+ ATTENDEE_PROJECTION, selection, selectionArgs, null);
if (cursor == null || cursor.getCount() == 0) {
if (DEBUG) Log.d(TAG, "No attendees found");
return true;
@@ -205,6 +210,9 @@ public class CalendarTracker {
rt |= eventMeets;
}
return rt;
+ } catch (SQLiteException e) {
+ Slog.w(TAG, "error querying attendees content provider", e);
+ return false;
} finally {
if (cursor != null) {
cursor.close();
diff --git a/services/core/java/com/android/server/notification/NotificationChannelLogger.java b/services/core/java/com/android/server/notification/NotificationChannelLogger.java
index a7b18778f868..51faac76c447 100644
--- a/services/core/java/com/android/server/notification/NotificationChannelLogger.java
+++ b/services/core/java/com/android/server/notification/NotificationChannelLogger.java
@@ -16,9 +16,12 @@
package com.android.server.notification;
+import static android.app.NotificationManager.IMPORTANCE_HIGH;
+
import android.annotation.NonNull;
import android.app.NotificationChannel;
import android.app.NotificationChannelGroup;
+import android.stats.sysui.NotificationEnums;
import com.android.internal.logging.UiEvent;
import com.android.internal.logging.UiEventLogger;
@@ -42,7 +45,7 @@ public interface NotificationChannelLogger {
String pkg) {
logNotificationChannel(
NotificationChannelEvent.getCreated(channel),
- channel, uid, pkg, 0, 0);
+ channel, uid, pkg, 0, getLoggingImportance(channel));
}
/**
@@ -55,7 +58,7 @@ public interface NotificationChannelLogger {
String pkg) {
logNotificationChannel(
NotificationChannelEvent.getDeleted(channel),
- channel, uid, pkg, 0, 0);
+ channel, uid, pkg, getLoggingImportance(channel), 0);
}
/**
@@ -63,13 +66,13 @@ public interface NotificationChannelLogger {
* @param channel The channel.
* @param uid UID of app that owns the channel.
* @param pkg Package of app that owns the channel.
- * @param oldImportance Previous importance level of the channel.
+ * @param oldLoggingImportance Previous logging importance level of the channel.
* @param byUser True if the modification was user-specified.
*/
default void logNotificationChannelModified(@NonNull NotificationChannel channel, int uid,
- String pkg, int oldImportance, boolean byUser) {
+ String pkg, int oldLoggingImportance, boolean byUser) {
logNotificationChannel(NotificationChannelEvent.getUpdated(byUser),
- channel, uid, pkg, oldImportance, channel.getImportance());
+ channel, uid, pkg, oldLoggingImportance, getLoggingImportance(channel));
}
/**
@@ -99,6 +102,16 @@ public interface NotificationChannelLogger {
}
/**
+ * Log blocking or unblocking of the entire app's notifications.
+ * @param uid UID of the app.
+ * @param pkg Package name of the app.
+ * @param enabled If true, notifications are now allowed.
+ */
+ default void logAppNotificationsAllowed(int uid, String pkg, boolean enabled) {
+ logAppEvent(NotificationChannelEvent.getBlocked(enabled), uid, pkg);
+ }
+
+ /**
* Low-level interface for logging events, to be implemented.
* @param event Event to log.
* @param channel Notification channel.
@@ -124,6 +137,13 @@ public interface NotificationChannelLogger {
boolean wasBlocked);
/**
+ * Low-level interface for logging app-as-a-whole events, to be implemented.
+ * @param uid UID of app.
+ * @param pkg Package of app.
+ */
+ void logAppEvent(@NonNull NotificationChannelEvent event, int uid, String pkg);
+
+ /**
* The UiEvent enums that this class can log.
*/
enum NotificationChannelEvent implements UiEventLogger.UiEventEnum {
@@ -144,8 +164,11 @@ public interface NotificationChannelLogger {
@UiEvent(doc = "System created a new conversation (sub-channel in a notification channel)")
NOTIFICATION_CHANNEL_CONVERSATION_CREATED(272),
@UiEvent(doc = "System deleted a new conversation (sub-channel in a notification channel)")
- NOTIFICATION_CHANNEL_CONVERSATION_DELETED(274);
-
+ NOTIFICATION_CHANNEL_CONVERSATION_DELETED(274),
+ @UiEvent(doc = "All notifications for the app were blocked.")
+ APP_NOTIFICATIONS_BLOCKED(557),
+ @UiEvent(doc = "Notifications for the app as a whole were unblocked.")
+ APP_NOTIFICATIONS_UNBLOCKED(558);
private final int mId;
NotificationChannelEvent(int id) {
@@ -178,6 +201,10 @@ public interface NotificationChannelLogger {
? NotificationChannelEvent.NOTIFICATION_CHANNEL_GROUP_CREATED
: NotificationChannelEvent.NOTIFICATION_CHANNEL_GROUP_DELETED;
}
+
+ public static NotificationChannelEvent getBlocked(boolean enabled) {
+ return enabled ? APP_NOTIFICATIONS_UNBLOCKED : APP_NOTIFICATIONS_BLOCKED;
+ }
}
/**
@@ -195,6 +222,27 @@ public interface NotificationChannelLogger {
}
/**
+ * @return Logging importance for a channel: the regular importance, or
+ * IMPORTANCE_IMPORTANT_CONVERSATION for a HIGH-importance conversation tagged important.
+ */
+ static int getLoggingImportance(@NonNull NotificationChannel channel) {
+ return getLoggingImportance(channel, channel.getImportance());
+ }
+
+ /**
+ * @return Logging importance for a channel or notification: the regular importance, or
+ * IMPORTANCE_IMPORTANT_CONVERSATION for a HIGH-importance conversation tagged important.
+ */
+ static int getLoggingImportance(@NonNull NotificationChannel channel, int importance) {
+ if (channel.getConversationId() == null || importance < IMPORTANCE_HIGH) {
+ return importance;
+ }
+ return (channel.isImportantConversation())
+ ? NotificationEnums.IMPORTANCE_IMPORTANT_CONVERSATION
+ : importance;
+ }
+
+ /**
* @return "Importance" for a channel group
*/
static int getImportance(@NonNull NotificationChannelGroup channelGroup) {
diff --git a/services/core/java/com/android/server/notification/NotificationChannelLoggerImpl.java b/services/core/java/com/android/server/notification/NotificationChannelLoggerImpl.java
index 2f7772eec2d2..fd3dd568f634 100644
--- a/services/core/java/com/android/server/notification/NotificationChannelLoggerImpl.java
+++ b/services/core/java/com/android/server/notification/NotificationChannelLoggerImpl.java
@@ -19,6 +19,8 @@ package com.android.server.notification;
import android.app.NotificationChannel;
import android.app.NotificationChannelGroup;
+import com.android.internal.logging.UiEventLogger;
+import com.android.internal.logging.UiEventLoggerImpl;
import com.android.internal.util.FrameworkStatsLog;
/**
@@ -27,6 +29,8 @@ import com.android.internal.util.FrameworkStatsLog;
* should live in the interface so it can be tested.
*/
public class NotificationChannelLoggerImpl implements NotificationChannelLogger {
+ UiEventLogger mUiEventLogger = new UiEventLoggerImpl();
+
@Override
public void logNotificationChannel(NotificationChannelEvent event,
NotificationChannel channel, int uid, String pkg,
@@ -51,4 +55,9 @@ public class NotificationChannelLoggerImpl implements NotificationChannelLogger
/* int old_importance*/ NotificationChannelLogger.getImportance(wasBlocked),
/* int importance*/ NotificationChannelLogger.getImportance(channelGroup));
}
+
+ @Override
+ public void logAppEvent(NotificationChannelEvent event, int uid, String pkg) {
+ mUiEventLogger.log(event, uid, pkg);
+ }
}
diff --git a/services/core/java/com/android/server/notification/NotificationHistoryDatabase.java b/services/core/java/com/android/server/notification/NotificationHistoryDatabase.java
index 0ec4b39d8960..18da33ce19e0 100644
--- a/services/core/java/com/android/server/notification/NotificationHistoryDatabase.java
+++ b/services/core/java/com/android/server/notification/NotificationHistoryDatabase.java
@@ -65,6 +65,7 @@ public class NotificationHistoryDatabase {
private static final int HISTORY_RETENTION_DAYS = 1;
private static final int HISTORY_RETENTION_MS = 24 * 60 * 60 * 1000;
private static final long WRITE_BUFFER_INTERVAL_MS = 1000 * 60 * 20;
+ private static final long INVALID_FILE_TIME_MS = -1;
private static final String ACTION_HISTORY_DELETION =
NotificationHistoryDatabase.class.getSimpleName() + ".CLEANUP";
@@ -130,8 +131,8 @@ public class NotificationHistoryDatabase {
}
// Sort with newest files first
- Arrays.sort(files, (lhs, rhs) -> Long.compare(Long.parseLong(rhs.getName()),
- Long.parseLong(lhs.getName())));
+ Arrays.sort(files, (lhs, rhs) -> Long.compare(safeParseLong(rhs.getName()),
+ safeParseLong(lhs.getName())));
for (File file : files) {
mHistoryFiles.addLast(new AtomicFile(file));
@@ -252,22 +253,19 @@ public class NotificationHistoryDatabase {
for (int i = mHistoryFiles.size() - 1; i >= 0; i--) {
final AtomicFile currentOldestFile = mHistoryFiles.get(i);
- try {
- final long creationTime = Long.parseLong(
- currentOldestFile.getBaseFile().getName());
- if (DEBUG) {
- Slog.d(TAG, "File " + currentOldestFile.getBaseFile().getName()
- + " created on " + creationTime);
- }
- if (creationTime <= retentionBoundary.getTimeInMillis()) {
- deleteFile(currentOldestFile);
- } else {
- // all remaining files are newer than the cut off; schedule jobs to delete
- scheduleDeletion(
- currentOldestFile.getBaseFile(), creationTime, retentionDays);
- }
- } catch (NumberFormatException e) {
+ final long creationTime = safeParseLong(
+ currentOldestFile.getBaseFile().getName());
+ if (DEBUG) {
+ Slog.d(TAG, "File " + currentOldestFile.getBaseFile().getName()
+ + " created on " + creationTime);
+ }
+
+ if (creationTime <= retentionBoundary.getTimeInMillis()) {
deleteFile(currentOldestFile);
+ } else {
+ // all remaining files are newer than the cut off; schedule jobs to delete
+ scheduleDeletion(
+ currentOldestFile.getBaseFile(), creationTime, retentionDays);
}
}
}
@@ -331,6 +329,17 @@ public class NotificationHistoryDatabase {
}
}
+ private static long safeParseLong(String fileName) {
+ // AtomicFile will create copies of the numeric files with ".new" and ".bak"
+ // over the course of its processing. If these files still exist on boot we need to clean
+ // them up
+ try {
+ return Long.parseLong(fileName);
+ } catch (NumberFormatException e) {
+ return INVALID_FILE_TIME_MS;
+ }
+ }
+
private final BroadcastReceiver mFileCleaupReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index b64e99168445..18635e8c07e3 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -1621,7 +1621,8 @@ public class NotificationManagerService extends SystemService {
= Settings.Global.getUriFor(Settings.Global.MAX_NOTIFICATION_ENQUEUE_RATE);
private final Uri NOTIFICATION_HISTORY_ENABLED
= Settings.Secure.getUriFor(Settings.Secure.NOTIFICATION_HISTORY_ENABLED);
-
+ private final Uri NOTIFICATION_SHOW_MEDIA_ON_QUICK_SETTINGS_URI
+ = Settings.Global.getUriFor(Settings.Global.SHOW_MEDIA_ON_QUICK_SETTINGS);
SettingsObserver(Handler handler) {
super(handler);
@@ -1639,6 +1640,8 @@ public class NotificationManagerService extends SystemService {
false, this, UserHandle.USER_ALL);
resolver.registerContentObserver(NOTIFICATION_HISTORY_ENABLED,
false, this, UserHandle.USER_ALL);
+ resolver.registerContentObserver(NOTIFICATION_SHOW_MEDIA_ON_QUICK_SETTINGS_URI,
+ false, this, UserHandle.USER_ALL);
update(null);
}
@@ -1675,6 +1678,9 @@ public class NotificationManagerService extends SystemService {
Settings.Secure.NOTIFICATION_HISTORY_ENABLED, 0) == 1);
}
}
+ if (uri == null || NOTIFICATION_SHOW_MEDIA_ON_QUICK_SETTINGS_URI.equals(uri)) {
+ mPreferencesHelper.updateMediaNotificationFilteringEnabled();
+ }
}
}
diff --git a/services/core/java/com/android/server/notification/NotificationRecordLogger.java b/services/core/java/com/android/server/notification/NotificationRecordLogger.java
index e06e01e53852..0e2ff7523c85 100644
--- a/services/core/java/com/android/server/notification/NotificationRecordLogger.java
+++ b/services/core/java/com/android/server/notification/NotificationRecordLogger.java
@@ -20,8 +20,10 @@ import static android.service.notification.NotificationListenerService.REASON_CA
import static android.service.notification.NotificationListenerService.REASON_CLICK;
import static android.service.notification.NotificationListenerService.REASON_TIMEOUT;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.Notification;
+import android.app.NotificationChannel;
import android.app.Person;
import android.os.Bundle;
import android.service.notification.NotificationListenerService;
@@ -346,7 +348,8 @@ public interface NotificationRecordLogger {
== old.getSbn().getNotification().isGroupSummary())
&& Objects.equals(r.getSbn().getNotification().category,
old.getSbn().getNotification().category)
- && (r.getImportance() == old.getImportance()));
+ && (r.getImportance() == old.getImportance())
+ && (getLoggingImportance(r) == getLoggingImportance(old)));
}
/**
@@ -413,5 +416,17 @@ public interface NotificationRecordLogger {
}
+ /**
+ * @param r NotificationRecord
+ * @return Logging importance of record, taking important conversation channels into account.
+ */
+ static int getLoggingImportance(@NonNull NotificationRecord r) {
+ final int importance = r.getImportance();
+ final NotificationChannel channel = r.getChannel();
+ if (channel == null) {
+ return importance;
+ }
+ return NotificationChannelLogger.getLoggingImportance(channel, importance);
+ }
}
diff --git a/services/core/java/com/android/server/notification/NotificationRecordLoggerImpl.java b/services/core/java/com/android/server/notification/NotificationRecordLoggerImpl.java
index 2b8ee92e00d9..1a99fb0e55f3 100644
--- a/services/core/java/com/android/server/notification/NotificationRecordLoggerImpl.java
+++ b/services/core/java/com/android/server/notification/NotificationRecordLoggerImpl.java
@@ -51,7 +51,8 @@ public class NotificationRecordLoggerImpl implements NotificationRecordLogger {
/* int32 style = 11 */ p.getStyle(),
/* int32 num_people = 12 */ p.getNumPeople(),
/* int32 position = 13 */ position,
- /* android.stats.sysui.NotificationImportance importance = 14 */ r.getImportance(),
+ /* android.stats.sysui.NotificationImportance importance = 14 */
+ NotificationRecordLogger.getLoggingImportance(r),
/* int32 alerting = 15 */ buzzBeepBlink,
/* NotificationImportanceExplanation importance_source = 16 */
r.getImportanceExplanationCode(),
diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java
index e472e3097777..dd6a83bc3f60 100644
--- a/services/core/java/com/android/server/notification/PreferencesHelper.java
+++ b/services/core/java/com/android/server/notification/PreferencesHelper.java
@@ -90,7 +90,7 @@ public class PreferencesHelper implements RankingConfig {
private static final String NON_BLOCKABLE_CHANNEL_DELIM = ":";
@VisibleForTesting
- static final int NOTIFICATION_CHANNEL_COUNT_LIMIT = 5000;
+ static final int NOTIFICATION_CHANNEL_COUNT_LIMIT = 50000;
private static final int NOTIFICATION_PREFERENCES_PULL_LIMIT = 1000;
private static final int NOTIFICATION_CHANNEL_PULL_LIMIT = 2000;
@@ -134,6 +134,7 @@ public class PreferencesHelper implements RankingConfig {
static final boolean DEFAULT_GLOBAL_ALLOW_BUBBLE = true;
@VisibleForTesting
static final int DEFAULT_BUBBLE_PREFERENCE = BUBBLE_PREFERENCE_NONE;
+ static final boolean DEFAULT_MEDIA_NOTIFICATION_FILTERING = true;
/**
* Default value for what fields are user locked. See {@link LockableAppFields} for all lockable
@@ -165,6 +166,7 @@ public class PreferencesHelper implements RankingConfig {
private SparseBooleanArray mBadgingEnabled;
private boolean mBubblesEnabledGlobally = DEFAULT_GLOBAL_ALLOW_BUBBLE;
+ private boolean mIsMediaNotificationFilteringEnabled = DEFAULT_MEDIA_NOTIFICATION_FILTERING;
private boolean mAreChannelsBypassingDnd;
private boolean mHideSilentStatusBarIcons = DEFAULT_HIDE_SILENT_STATUS_BAR_ICONS;
@@ -184,6 +186,7 @@ public class PreferencesHelper implements RankingConfig {
updateBadgingEnabled();
updateBubblesEnabled();
+ updateMediaNotificationFilteringEnabled();
syncChannelsBypassingDnd(mContext.getUserId());
}
@@ -838,6 +841,8 @@ public class PreferencesHelper implements RankingConfig {
// Apps are allowed to downgrade channel importance if the user has not changed any
// fields on this channel yet.
final int previousExistingImportance = existing.getImportance();
+ final int previousLoggingImportance =
+ NotificationChannelLogger.getLoggingImportance(existing);
if (existing.getUserLockedFields() == 0 &&
channel.getImportance() < existing.getImportance()) {
existing.setImportance(channel.getImportance());
@@ -867,7 +872,7 @@ public class PreferencesHelper implements RankingConfig {
updateConfig();
if (needsPolicyFileChange && !wasUndeleted) {
mNotificationChannelLogger.logNotificationChannelModified(existing, uid, pkg,
- previousExistingImportance, false);
+ previousLoggingImportance, false);
}
return needsPolicyFileChange;
}
@@ -985,7 +990,7 @@ public class PreferencesHelper implements RankingConfig {
MetricsLogger.action(getChannelLog(updatedChannel, pkg)
.setSubtype(fromUser ? 1 : 0));
mNotificationChannelLogger.logNotificationChannelModified(updatedChannel, uid, pkg,
- channel.getImportance(), fromUser);
+ NotificationChannelLogger.getLoggingImportance(channel), fromUser);
}
if (updatedChannel.canBypassDnd() != mAreChannelsBypassingDnd
@@ -1654,6 +1659,7 @@ public class PreferencesHelper implements RankingConfig {
}
setImportance(packageName, uid,
enabled ? DEFAULT_IMPORTANCE : IMPORTANCE_NONE);
+ mNotificationChannelLogger.logAppNotificationsAllowed(uid, packageName, enabled);
}
/**
@@ -2286,6 +2292,21 @@ public class PreferencesHelper implements RankingConfig {
return mBubblesEnabledGlobally;
}
+ /** Requests check of the feature setting for showing media notifications in quick settings. */
+ public void updateMediaNotificationFilteringEnabled() {
+ final boolean newValue = Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.SHOW_MEDIA_ON_QUICK_SETTINGS, 1) > 0;
+ if (newValue != mIsMediaNotificationFilteringEnabled) {
+ mIsMediaNotificationFilteringEnabled = newValue;
+ updateConfig();
+ }
+ }
+
+ /** Returns true if the setting is enabled for showing media notifications in quick settings. */
+ public boolean isMediaNotificationFilteringEnabled() {
+ return mIsMediaNotificationFilteringEnabled;
+ }
+
public void updateBadgingEnabled() {
if (mBadgingEnabled == null) {
mBadgingEnabled = new SparseBooleanArray();
diff --git a/services/core/java/com/android/server/notification/RankingConfig.java b/services/core/java/com/android/server/notification/RankingConfig.java
index 7fc79e6a9bf7..b2827bae40bc 100644
--- a/services/core/java/com/android/server/notification/RankingConfig.java
+++ b/services/core/java/com/android/server/notification/RankingConfig.java
@@ -31,6 +31,8 @@ public interface RankingConfig {
boolean badgingEnabled(UserHandle userHandle);
int getBubblePreference(String packageName, int uid);
boolean bubblesEnabled();
+ /** Returns true when feature is enabled that shows media notifications in quick settings. */
+ boolean isMediaNotificationFilteringEnabled();
boolean isGroupBlocked(String packageName, int uid, String groupId);
Collection<NotificationChannelGroup> getNotificationChannelGroups(String pkg,
diff --git a/services/core/java/com/android/server/pm/AppsFilter.java b/services/core/java/com/android/server/pm/AppsFilter.java
index 5b9db64dd9b1..8a7702efcba8 100644
--- a/services/core/java/com/android/server/pm/AppsFilter.java
+++ b/services/core/java/com/android/server/pm/AppsFilter.java
@@ -19,6 +19,8 @@ package com.android.server.pm;
import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
import static android.provider.DeviceConfig.NAMESPACE_PACKAGE_MANAGER_SERVICE;
+import static com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE;
+
import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -27,6 +29,7 @@ import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.content.pm.PackageParser;
+import android.content.pm.UserInfo;
import android.content.pm.parsing.component.ParsedComponent;
import android.content.pm.parsing.component.ParsedInstrumentation;
import android.content.pm.parsing.component.ParsedIntentInfo;
@@ -93,6 +96,14 @@ public class AppsFilter {
private final SparseSetArray<Integer> mQueriesViaComponent = new SparseSetArray<>();
/**
+ * Pending full recompute of mQueriesViaComponent. Occurs when a package adds a new set of
+ * protected broadcast. This in turn invalidates all prior additions and require a very
+ * computationally expensive recomputing.
+ * Full recompute is done lazily at the point when we use mQueriesViaComponent to filter apps.
+ */
+ private boolean mQueriesViaComponentRequireRecompute = false;
+
+ /**
* A set of App IDs that are always queryable by any package, regardless of their manifest
* content.
*/
@@ -108,12 +119,25 @@ public class AppsFilter {
private final boolean mSystemAppsQueryable;
private final FeatureConfig mFeatureConfig;
-
private final OverlayReferenceMapper mOverlayReferenceMapper;
+ private final StateProvider mStateProvider;
+
private PackageParser.SigningDetails mSystemSigningDetails;
private Set<String> mProtectedBroadcasts = new ArraySet<>();
- AppsFilter(FeatureConfig featureConfig, String[] forceQueryableWhitelist,
+ /**
+ * This structure maps uid -> uid and indicates whether access from the first should be
+ * filtered to the second. It's essentially a cache of the
+ * {@link #shouldFilterApplicationInternal(int, SettingBase, PackageSetting, int)} call.
+ * NOTE: It can only be relied upon after the system is ready to avoid unnecessary update on
+ * initial scam and is null until {@link #onSystemReady()} is called.
+ */
+ private volatile SparseArray<SparseBooleanArray> mShouldFilterCache;
+
+ @VisibleForTesting(visibility = PRIVATE)
+ AppsFilter(StateProvider stateProvider,
+ FeatureConfig featureConfig,
+ String[] forceQueryableWhitelist,
boolean systemAppsQueryable,
@Nullable OverlayReferenceMapper.Provider overlayProvider) {
mFeatureConfig = featureConfig;
@@ -121,8 +145,23 @@ public class AppsFilter {
mSystemAppsQueryable = systemAppsQueryable;
mOverlayReferenceMapper = new OverlayReferenceMapper(true /*deferRebuild*/,
overlayProvider);
+ mStateProvider = stateProvider;
}
+ /**
+ * Provides system state to AppsFilter via {@link CurrentStateCallback} after properly guarding
+ * the data with the package lock.
+ */
+ @VisibleForTesting(visibility = PRIVATE)
+ public interface StateProvider {
+ void runWithState(CurrentStateCallback callback);
+
+ interface CurrentStateCallback {
+ void currentState(ArrayMap<String, PackageSetting> settings, UserInfo[] users);
+ }
+ }
+
+ @VisibleForTesting(visibility = PRIVATE)
public interface FeatureConfig {
/** Called when the system is ready and components can be queried. */
@@ -139,6 +178,7 @@ public class AppsFilter {
/**
* Turns on logging for the given appId
+ *
* @param enable true if logging should be enabled, false if disabled.
*/
void enableLogging(int appId, boolean enable);
@@ -146,6 +186,7 @@ public class AppsFilter {
/**
* Initializes the package enablement state for the given package. This gives opportunity
* to do any expensive operations ahead of the actual checks.
+ *
* @param removed true if adding, false if removing
*/
void updatePackageState(PackageSetting setting, boolean removed);
@@ -161,6 +202,7 @@ public class AppsFilter {
@Nullable
private SparseBooleanArray mLoggingEnabled = null;
+ private AppsFilter mAppsFilter;
private FeatureConfigImpl(
PackageManagerInternal pmInternal, PackageManagerService.Injector injector) {
@@ -168,6 +210,10 @@ public class AppsFilter {
mInjector = injector;
}
+ public void setAppsFilter(AppsFilter filter) {
+ mAppsFilter = filter;
+ }
+
@Override
public void onSystemReady() {
mFeatureEnabled = DeviceConfig.getBoolean(
@@ -235,6 +281,7 @@ public class AppsFilter {
@Override
public void onCompatChange(String packageName) {
updateEnabledState(mPmInternal.getPackage(packageName));
+ mAppsFilter.updateShouldFilterCacheForPackage(packageName);
}
private void updateEnabledState(AndroidPackage pkg) {
@@ -267,7 +314,7 @@ public class AppsFilter {
final boolean forceSystemAppsQueryable =
injector.getContext().getResources()
.getBoolean(R.bool.config_forceSystemPackagesQueryable);
- final FeatureConfig featureConfig = new FeatureConfigImpl(pms, injector);
+ final FeatureConfigImpl featureConfig = new FeatureConfigImpl(pms, injector);
final String[] forcedQueryablePackageNames;
if (forceSystemAppsQueryable) {
// all system apps already queryable, no need to read and parse individual exceptions
@@ -280,8 +327,16 @@ public class AppsFilter {
forcedQueryablePackageNames[i] = forcedQueryablePackageNames[i].intern();
}
}
- return new AppsFilter(featureConfig, forcedQueryablePackageNames,
- forceSystemAppsQueryable, null);
+ final StateProvider stateProvider = command -> {
+ synchronized (injector.getLock()) {
+ command.currentState(injector.getSettings().mPackages,
+ injector.getUserManagerInternal().getUserInfos());
+ }
+ };
+ AppsFilter appsFilter = new AppsFilter(stateProvider, featureConfig,
+ forcedQueryablePackageNames, forceSystemAppsQueryable, null);
+ featureConfig.setAppsFilter(appsFilter);
+ return appsFilter;
}
public FeatureConfig getFeatureConfig() {
@@ -404,27 +459,59 @@ public class AppsFilter {
* visibility of the caller from the target.
*
* @param recipientUid the uid gaining visibility of the {@code visibleUid}.
- * @param visibleUid the uid becoming visible to the {@recipientUid}
+ * @param visibleUid the uid becoming visible to the {@recipientUid}
*/
public void grantImplicitAccess(int recipientUid, int visibleUid) {
- if (recipientUid != visibleUid
- && mImplicitlyQueryable.add(recipientUid, visibleUid) && DEBUG_LOGGING) {
- Slog.i(TAG, "implicit access granted: " + recipientUid + " -> " + visibleUid);
+ if (recipientUid != visibleUid) {
+ if (mImplicitlyQueryable.add(recipientUid, visibleUid) && DEBUG_LOGGING) {
+ Slog.i(TAG, "implicit access granted: " + recipientUid + " -> " + visibleUid);
+ }
+ if (mShouldFilterCache != null) {
+ // update the cache in a one-off manner since we've got all the information we need.
+ SparseBooleanArray visibleUids = mShouldFilterCache.get(recipientUid);
+ if (visibleUids == null) {
+ visibleUids = new SparseBooleanArray();
+ mShouldFilterCache.put(recipientUid, visibleUids);
+ }
+ visibleUids.put(visibleUid, false);
+ }
}
}
public void onSystemReady() {
+ mStateProvider.runWithState(new StateProvider.CurrentStateCallback() {
+ @Override
+ public void currentState(ArrayMap<String, PackageSetting> settings,
+ UserInfo[] users) {
+ mShouldFilterCache = new SparseArray<>(users.length * settings.size());
+ }
+ });
mFeatureConfig.onSystemReady();
mOverlayReferenceMapper.rebuildIfDeferred();
+ updateEntireShouldFilterCache();
}
/**
* Adds a package that should be considered when filtering visibility between apps.
*
- * @param newPkgSetting the new setting being added
- * @param existingSettings all other settings currently on the device.
+ * @param newPkgSetting the new setting being added
*/
- public void addPackage(PackageSetting newPkgSetting,
+ public void addPackage(PackageSetting newPkgSetting) {
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "filter.addPackage");
+ try {
+ mStateProvider.runWithState((settings, users) -> {
+ addPackageInternal(newPkgSetting, settings);
+ if (mShouldFilterCache != null) {
+ updateShouldFilterCacheForPackage(
+ null, newPkgSetting, settings, users, settings.size());
+ } // else, rebuild entire cache when system is ready
+ });
+ } finally {
+ Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+ }
+ }
+
+ private void addPackageInternal(PackageSetting newPkgSetting,
ArrayMap<String, PackageSetting> existingSettings) {
if (Objects.equals("android", newPkgSetting.name)) {
// let's set aside the framework signatures
@@ -438,79 +525,154 @@ public class AppsFilter {
}
}
- Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "filter.addPackage");
- try {
- final AndroidPackage newPkg = newPkgSetting.pkg;
- if (newPkg == null) {
- // nothing to add
- return;
- }
+ final AndroidPackage newPkg = newPkgSetting.pkg;
+ if (newPkg == null) {
+ // nothing to add
+ return;
+ }
- if (!newPkg.getProtectedBroadcasts().isEmpty()) {
- mProtectedBroadcasts.addAll(newPkg.getProtectedBroadcasts());
- recomputeComponentVisibility(existingSettings, newPkg.getPackageName());
- }
+ if (mProtectedBroadcasts.addAll(newPkg.getProtectedBroadcasts())) {
+ mQueriesViaComponentRequireRecompute = true;
+ }
- final boolean newIsForceQueryable =
- mForceQueryable.contains(newPkgSetting.appId)
- /* shared user that is already force queryable */
- || newPkg.isForceQueryable()
- || newPkgSetting.forceQueryableOverride
- || (newPkgSetting.isSystem() && (mSystemAppsQueryable
- || ArrayUtils.contains(mForceQueryableByDevicePackageNames,
- newPkg.getPackageName())));
- if (newIsForceQueryable
- || (mSystemSigningDetails != null
- && isSystemSigned(mSystemSigningDetails, newPkgSetting))) {
- mForceQueryable.add(newPkgSetting.appId);
- }
+ final boolean newIsForceQueryable =
+ mForceQueryable.contains(newPkgSetting.appId)
+ /* shared user that is already force queryable */
+ || newPkg.isForceQueryable()
+ || newPkgSetting.forceQueryableOverride
+ || (newPkgSetting.isSystem() && (mSystemAppsQueryable
+ || ArrayUtils.contains(mForceQueryableByDevicePackageNames,
+ newPkg.getPackageName())));
+ if (newIsForceQueryable
+ || (mSystemSigningDetails != null
+ && isSystemSigned(mSystemSigningDetails, newPkgSetting))) {
+ mForceQueryable.add(newPkgSetting.appId);
+ }
- for (int i = existingSettings.size() - 1; i >= 0; i--) {
- final PackageSetting existingSetting = existingSettings.valueAt(i);
- if (existingSetting.appId == newPkgSetting.appId || existingSetting.pkg == null) {
- continue;
+ for (int i = existingSettings.size() - 1; i >= 0; i--) {
+ final PackageSetting existingSetting = existingSettings.valueAt(i);
+ if (existingSetting.appId == newPkgSetting.appId || existingSetting.pkg == null) {
+ continue;
+ }
+ final AndroidPackage existingPkg = existingSetting.pkg;
+ // let's evaluate the ability of already added packages to see this new package
+ if (!newIsForceQueryable) {
+ if (!mQueriesViaComponentRequireRecompute && canQueryViaComponents(existingPkg,
+ newPkg, mProtectedBroadcasts)) {
+ mQueriesViaComponent.add(existingSetting.appId, newPkgSetting.appId);
}
- final AndroidPackage existingPkg = existingSetting.pkg;
- // let's evaluate the ability of already added packages to see this new package
- if (!newIsForceQueryable) {
- if (canQueryViaComponents(existingPkg, newPkg, mProtectedBroadcasts)) {
- mQueriesViaComponent.add(existingSetting.appId, newPkgSetting.appId);
- }
- if (canQueryViaPackage(existingPkg, newPkg)
- || canQueryAsInstaller(existingSetting, newPkg)) {
- mQueriesViaPackage.add(existingSetting.appId, newPkgSetting.appId);
- }
+ if (canQueryViaPackage(existingPkg, newPkg)
+ || canQueryAsInstaller(existingSetting, newPkg)) {
+ mQueriesViaPackage.add(existingSetting.appId, newPkgSetting.appId);
}
- // now we'll evaluate our new package's ability to see existing packages
- if (!mForceQueryable.contains(existingSetting.appId)) {
- if (canQueryViaComponents(newPkg, existingPkg, mProtectedBroadcasts)) {
- mQueriesViaComponent.add(newPkgSetting.appId, existingSetting.appId);
- }
- if (canQueryViaPackage(newPkg, existingPkg)
- || canQueryAsInstaller(newPkgSetting, existingPkg)) {
- mQueriesViaPackage.add(newPkgSetting.appId, existingSetting.appId);
- }
+ }
+ // now we'll evaluate our new package's ability to see existing packages
+ if (!mForceQueryable.contains(existingSetting.appId)) {
+ if (!mQueriesViaComponentRequireRecompute && canQueryViaComponents(newPkg,
+ existingPkg, mProtectedBroadcasts)) {
+ mQueriesViaComponent.add(newPkgSetting.appId, existingSetting.appId);
}
- // if either package instruments the other, mark both as visible to one another
- if (pkgInstruments(newPkgSetting, existingSetting)
- || pkgInstruments(existingSetting, newPkgSetting)) {
+ if (canQueryViaPackage(newPkg, existingPkg)
+ || canQueryAsInstaller(newPkgSetting, existingPkg)) {
mQueriesViaPackage.add(newPkgSetting.appId, existingSetting.appId);
- mQueriesViaPackage.add(existingSetting.appId, newPkgSetting.appId);
}
}
+ // if either package instruments the other, mark both as visible to one another
+ if (pkgInstruments(newPkgSetting, existingSetting)
+ || pkgInstruments(existingSetting, newPkgSetting)) {
+ mQueriesViaPackage.add(newPkgSetting.appId, existingSetting.appId);
+ mQueriesViaPackage.add(existingSetting.appId, newPkgSetting.appId);
+ }
+ }
- int existingSize = existingSettings.size();
- ArrayMap<String, AndroidPackage> existingPkgs = new ArrayMap<>(existingSize);
- for (int index = 0; index < existingSize; index++) {
- PackageSetting pkgSetting = existingSettings.valueAt(index);
- if (pkgSetting.pkg != null) {
- existingPkgs.put(pkgSetting.name, pkgSetting.pkg);
+ int existingSize = existingSettings.size();
+ ArrayMap<String, AndroidPackage> existingPkgs = new ArrayMap<>(existingSize);
+ for (int index = 0; index < existingSize; index++) {
+ PackageSetting pkgSetting = existingSettings.valueAt(index);
+ if (pkgSetting.pkg != null) {
+ existingPkgs.put(pkgSetting.name, pkgSetting.pkg);
+ }
+ }
+ mOverlayReferenceMapper.addPkg(newPkgSetting.pkg, existingPkgs);
+ mFeatureConfig.updatePackageState(newPkgSetting, false /*removed*/);
+ }
+
+ private void removeAppIdFromVisibilityCache(int appId) {
+ if (mShouldFilterCache == null) {
+ return;
+ }
+ for (int i = mShouldFilterCache.size() - 1; i >= 0; i--) {
+ if (UserHandle.getAppId(mShouldFilterCache.keyAt(i)) == appId) {
+ mShouldFilterCache.removeAt(i);
+ continue;
+ }
+ SparseBooleanArray targetSparseArray = mShouldFilterCache.valueAt(i);
+ for (int j = targetSparseArray.size() - 1; j >= 0; j--) {
+ if (UserHandle.getAppId(targetSparseArray.keyAt(j)) == appId) {
+ targetSparseArray.removeAt(j);
+ }
+ }
+ }
+ }
+
+ private void updateEntireShouldFilterCache() {
+ mStateProvider.runWithState((settings, users) -> {
+ mShouldFilterCache.clear();
+ for (int i = settings.size() - 1; i >= 0; i--) {
+ updateShouldFilterCacheForPackage(
+ null /*skipPackage*/, settings.valueAt(i), settings, users, i);
+ }
+ });
+ }
+
+ public void onUsersChanged() {
+ if (mShouldFilterCache != null) {
+ updateEntireShouldFilterCache();
+ }
+ }
+
+ private void updateShouldFilterCacheForPackage(String packageName) {
+ mStateProvider.runWithState((settings, users) -> {
+ updateShouldFilterCacheForPackage(null /* skipPackage */, settings.get(packageName),
+ settings, users, settings.size() /*maxIndex*/);
+ });
+
+ }
+
+ private void updateShouldFilterCacheForPackage(@Nullable String skipPackageName,
+ PackageSetting subjectSetting, ArrayMap<String, PackageSetting> allSettings,
+ UserInfo[] allUsers, int maxIndex) {
+ for (int i = Math.min(maxIndex, allSettings.size() - 1); i >= 0; i--) {
+ PackageSetting otherSetting = allSettings.valueAt(i);
+ if (subjectSetting.appId == otherSetting.appId) {
+ continue;
+ }
+ //noinspection StringEquality
+ if (subjectSetting.name == skipPackageName || otherSetting.name == skipPackageName) {
+ continue;
+ }
+ final int userCount = allUsers.length;
+ final int appxUidCount = userCount * allSettings.size();
+ for (int su = 0; su < userCount; su++) {
+ int subjectUser = allUsers[su].id;
+ for (int ou = 0; ou < userCount; ou++) {
+ int otherUser = allUsers[ou].id;
+ int subjectUid = UserHandle.getUid(subjectUser, subjectSetting.appId);
+ if (!mShouldFilterCache.contains(subjectUid)) {
+ mShouldFilterCache.put(subjectUid, new SparseBooleanArray(appxUidCount));
+ }
+ int otherUid = UserHandle.getUid(otherUser, otherSetting.appId);
+ if (!mShouldFilterCache.contains(otherUid)) {
+ mShouldFilterCache.put(otherUid, new SparseBooleanArray(appxUidCount));
+ }
+ mShouldFilterCache.get(subjectUid).put(otherUid,
+ shouldFilterApplicationInternal(
+ subjectUid, subjectSetting, otherSetting, otherUser));
+ mShouldFilterCache.get(otherUid).put(subjectUid,
+ shouldFilterApplicationInternal(
+ otherUid, otherSetting, subjectSetting, subjectUser));
}
}
- mOverlayReferenceMapper.addPkg(newPkgSetting.pkg, existingPkgs);
- mFeatureConfig.updatePackageState(newPkgSetting, false /*removed*/);
- } finally {
- Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
}
@@ -536,13 +698,11 @@ public class AppsFilter {
return ret;
}
- private void recomputeComponentVisibility(ArrayMap<String, PackageSetting> existingSettings,
- @Nullable String excludePackage) {
+ private void recomputeComponentVisibility(ArrayMap<String, PackageSetting> existingSettings) {
mQueriesViaComponent.clear();
for (int i = existingSettings.size() - 1; i >= 0; i--) {
PackageSetting setting = existingSettings.valueAt(i);
if (setting.pkg == null
- || setting.pkg.getPackageName().equals(excludePackage)
|| mForceQueryable.contains(setting.appId)) {
continue;
}
@@ -551,8 +711,7 @@ public class AppsFilter {
continue;
}
final PackageSetting otherSetting = existingSettings.valueAt(j);
- if (otherSetting.pkg == null
- || otherSetting.pkg.getPackageName().equals(excludePackage)) {
+ if (otherSetting.pkg == null) {
continue;
}
if (canQueryViaComponents(setting.pkg, otherSetting.pkg, mProtectedBroadcasts)) {
@@ -560,7 +719,9 @@ public class AppsFilter {
}
}
}
+ mQueriesViaComponentRequireRecompute = false;
}
+
/**
* Fetches all app Ids that a given setting is currently visible to, per provided user. This
* only includes UIDs >= {@link Process#FIRST_APPLICATION_UID} as all other UIDs can already see
@@ -569,11 +730,11 @@ public class AppsFilter {
* If the setting is visible to all UIDs, null is returned. If an app is not visible to any
* applications, the int array will be empty.
*
- * @param users the set of users that should be evaluated for this calculation
+ * @param users the set of users that should be evaluated for this calculation
* @param existingSettings the set of all package settings that currently exist on device
* @return a SparseArray mapping userIds to a sorted int array of appIds that may view the
- * provided setting or null if the app is visible to all and no whitelist should be
- * applied.
+ * provided setting or null if the app is visible to all and no whitelist should be
+ * applied.
*/
@Nullable
public SparseArray<int[]> getVisibilityWhitelist(PackageSetting setting, int[] users,
@@ -618,52 +779,70 @@ public class AppsFilter {
/**
* Removes a package for consideration when filtering visibility between apps.
*
- * @param setting the setting of the package being removed.
- * @param allUsers array of all current users on device.
+ * @param setting the setting of the package being removed.
*/
- public void removePackage(PackageSetting setting, int[] allUsers,
- ArrayMap<String, PackageSetting> existingSettings) {
- mForceQueryable.remove(setting.appId);
+ public void removePackage(PackageSetting setting) {
+ removeAppIdFromVisibilityCache(setting.appId);
+ mStateProvider.runWithState((settings, users) -> {
+ final int userCount = users.length;
+ for (int u = 0; u < userCount; u++) {
+ final int userId = users[u].id;
+ final int removingUid = UserHandle.getUid(userId, setting.appId);
+ mImplicitlyQueryable.remove(removingUid);
+ for (int i = mImplicitlyQueryable.size() - 1; i >= 0; i--) {
+ mImplicitlyQueryable.remove(mImplicitlyQueryable.keyAt(i), removingUid);
+ }
+ }
- for (int u = 0; u < allUsers.length; u++) {
- final int userId = allUsers[u];
- final int removingUid = UserHandle.getUid(userId, setting.appId);
- mImplicitlyQueryable.remove(removingUid);
- for (int i = mImplicitlyQueryable.size() - 1; i >= 0; i--) {
- mImplicitlyQueryable.remove(mImplicitlyQueryable.keyAt(i), removingUid);
+ if (!mQueriesViaComponentRequireRecompute) {
+ mQueriesViaComponent.remove(setting.appId);
+ for (int i = mQueriesViaComponent.size() - 1; i >= 0; i--) {
+ mQueriesViaComponent.remove(mQueriesViaComponent.keyAt(i), setting.appId);
+ }
+ }
+ mQueriesViaPackage.remove(setting.appId);
+ for (int i = mQueriesViaPackage.size() - 1; i >= 0; i--) {
+ mQueriesViaPackage.remove(mQueriesViaPackage.keyAt(i), setting.appId);
}
- }
- mQueriesViaComponent.remove(setting.appId);
- for (int i = mQueriesViaComponent.size() - 1; i >= 0; i--) {
- mQueriesViaComponent.remove(mQueriesViaComponent.keyAt(i), setting.appId);
- }
- mQueriesViaPackage.remove(setting.appId);
- for (int i = mQueriesViaPackage.size() - 1; i >= 0; i--) {
- mQueriesViaPackage.remove(mQueriesViaPackage.keyAt(i), setting.appId);
- }
+ // re-add other shared user members to re-establish visibility between them and other
+ // packages
+ if (setting.sharedUser != null) {
+ for (int i = setting.sharedUser.packages.size() - 1; i >= 0; i--) {
+ if (setting.sharedUser.packages.valueAt(i) == setting) {
+ continue;
+ }
+ addPackageInternal(
+ setting.sharedUser.packages.valueAt(i), settings);
+ }
+ }
- // re-add other shared user members to re-establish visibility between them and other
- // packages
- if (setting.sharedUser != null) {
- for (int i = setting.sharedUser.packages.size() - 1; i >= 0; i--) {
- if (setting.sharedUser.packages.valueAt(i) == setting) {
- continue;
+ if (setting.pkg != null && !setting.pkg.getProtectedBroadcasts().isEmpty()) {
+ final String removingPackageName = setting.pkg.getPackageName();
+ final Set<String> protectedBroadcasts = mProtectedBroadcasts;
+ mProtectedBroadcasts = collectProtectedBroadcasts(settings, removingPackageName);
+ if (!mProtectedBroadcasts.containsAll(protectedBroadcasts)) {
+ mQueriesViaComponentRequireRecompute = true;
}
- addPackage(setting.sharedUser.packages.valueAt(i), existingSettings);
}
- }
- if (!setting.pkg.getProtectedBroadcasts().isEmpty()) {
- final String removingPackageName = setting.pkg.getPackageName();
- mProtectedBroadcasts.clear();
- mProtectedBroadcasts.addAll(
- collectProtectedBroadcasts(existingSettings, removingPackageName));
- recomputeComponentVisibility(existingSettings, removingPackageName);
- }
+ mOverlayReferenceMapper.removePkg(setting.name);
+ mFeatureConfig.updatePackageState(setting, true /*removed*/);
+
+ if (mShouldFilterCache != null && setting.sharedUser != null) {
+ for (int i = setting.sharedUser.packages.size() - 1; i >= 0; i--) {
+ PackageSetting siblingSetting = setting.sharedUser.packages.valueAt(i);
+ if (siblingSetting == setting) {
+ continue;
+ }
+ updateShouldFilterCacheForPackage(
+ setting.name, siblingSetting, settings, users, settings.size());
+ }
+ }
+ });
+ mForceQueryable.remove(setting.appId);
+
- mOverlayReferenceMapper.removePkg(setting.name);
- mFeatureConfig.updatePackageState(setting, true /*removed*/);
}
/**
@@ -680,12 +859,35 @@ public class AppsFilter {
PackageSetting targetPkgSetting, int userId) {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "shouldFilterApplication");
try {
-
- if (!shouldFilterApplicationInternal(
- callingUid, callingSetting, targetPkgSetting, userId)) {
+ int callingAppId = UserHandle.getAppId(callingUid);
+ if (callingAppId < Process.FIRST_APPLICATION_UID
+ || targetPkgSetting.appId < Process.FIRST_APPLICATION_UID
+ || callingAppId == targetPkgSetting.appId) {
return false;
}
- if (DEBUG_LOGGING || mFeatureConfig.isLoggingEnabled(UserHandle.getAppId(callingUid))) {
+ if (mShouldFilterCache != null) { // use cache
+ SparseBooleanArray shouldFilterTargets = mShouldFilterCache.get(callingUid);
+ final int targetUid = UserHandle.getUid(userId, targetPkgSetting.appId);
+ if (shouldFilterTargets == null) {
+ Slog.wtf(TAG, "Encountered calling uid with no cached rules: " + callingUid);
+ return true;
+ }
+ int indexOfTargetUid = shouldFilterTargets.indexOfKey(targetUid);
+ if (indexOfTargetUid < 0) {
+ Slog.w(TAG, "Encountered calling -> target with no cached rules: "
+ + callingUid + " -> " + targetUid);
+ return true;
+ }
+ if (!shouldFilterTargets.valueAt(indexOfTargetUid)) {
+ return false;
+ }
+ } else {
+ if (!shouldFilterApplicationInternal(
+ callingUid, callingSetting, targetPkgSetting, userId)) {
+ return false;
+ }
+ }
+ if (DEBUG_LOGGING || mFeatureConfig.isLoggingEnabled(callingAppId)) {
log(callingSetting, targetPkgSetting, "BLOCKED");
}
return !DEBUG_ALLOW_ALL;
@@ -695,7 +897,7 @@ public class AppsFilter {
}
private boolean shouldFilterApplicationInternal(int callingUid, SettingBase callingSetting,
- PackageSetting targetPkgSetting, int userId) {
+ PackageSetting targetPkgSetting, int targetUserId) {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "shouldFilterApplicationInternal");
try {
final boolean featureEnabled = mFeatureConfig.isGloballyEnabled();
@@ -705,12 +907,6 @@ public class AppsFilter {
}
return false;
}
- if (callingUid < Process.FIRST_APPLICATION_UID) {
- if (DEBUG_LOGGING) {
- Slog.d(TAG, "filtering skipped; " + callingUid + " is system");
- }
- return false;
- }
if (callingSetting == null) {
Slog.wtf(TAG, "No setting found for non system uid " + callingUid);
return true;
@@ -719,8 +915,14 @@ public class AppsFilter {
final ArraySet<PackageSetting> callingSharedPkgSettings;
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "callingSetting instanceof");
if (callingSetting instanceof PackageSetting) {
- callingPkgSetting = (PackageSetting) callingSetting;
- callingSharedPkgSettings = null;
+ if (((PackageSetting) callingSetting).sharedUser == null) {
+ callingPkgSetting = (PackageSetting) callingSetting;
+ callingSharedPkgSettings = null;
+ } else {
+ callingPkgSetting = null;
+ callingSharedPkgSettings =
+ ((PackageSetting) callingSetting).sharedUser.packages;
+ }
} else {
callingPkgSetting = null;
callingSharedPkgSettings = ((SharedUserSetting) callingSetting).packages;
@@ -778,13 +980,19 @@ public class AppsFilter {
}
try {
- Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "hasPermission");
- if (callingSetting.getPermissionsState().hasPermission(
- Manifest.permission.QUERY_ALL_PACKAGES, UserHandle.getUserId(callingUid))) {
- if (DEBUG_LOGGING) {
- log(callingSetting, targetPkgSetting, "has query-all permission");
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "requestsQueryAllPackages");
+ if (callingPkgSetting != null) {
+ if (callingPkgSetting.pkg != null
+ && requestsQueryAllPackages(callingPkgSetting.pkg)) {
+ return false;
+ }
+ } else {
+ for (int i = callingSharedPkgSettings.size() - 1; i >= 0; i--) {
+ AndroidPackage pkg = callingSharedPkgSettings.valueAt(i).pkg;
+ if (pkg != null && requestsQueryAllPackages(pkg)) {
+ return false;
+ }
}
- return false;
}
} finally {
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
@@ -813,6 +1021,11 @@ public class AppsFilter {
}
try {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mQueriesViaComponent");
+ if (mQueriesViaComponentRequireRecompute) {
+ mStateProvider.runWithState((settings, users) -> {
+ recomputeComponentVisibility(settings);
+ });
+ }
if (mQueriesViaComponent.contains(callingAppId, targetAppId)) {
if (DEBUG_LOGGING) {
log(callingSetting, targetPkgSetting, "queries component");
@@ -825,7 +1038,7 @@ public class AppsFilter {
try {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mImplicitlyQueryable");
- final int targetUid = UserHandle.getUid(userId, targetAppId);
+ final int targetUid = UserHandle.getUid(targetUserId, targetAppId);
if (mImplicitlyQueryable.contains(callingUid, targetUid)) {
if (DEBUG_LOGGING) {
log(callingSetting, targetPkgSetting, "implicitly queryable for user");
@@ -863,13 +1076,20 @@ public class AppsFilter {
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
-
return true;
} finally {
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
}
+
+ private static boolean requestsQueryAllPackages(@NonNull AndroidPackage pkg) {
+ // we're not guaranteed to have permissions yet analyzed at package add, so we inspect the
+ // package directly
+ return pkg.getRequestedPermissions().contains(
+ Manifest.permission.QUERY_ALL_PACKAGES);
+ }
+
/** Returns {@code true} if the source package instruments the target package. */
private static boolean pkgInstruments(PackageSetting source, PackageSetting target) {
try {
diff --git a/services/core/java/com/android/server/pm/PackageAbiHelperImpl.java b/services/core/java/com/android/server/pm/PackageAbiHelperImpl.java
index 0bd8b28ee6ac..fc58968a7325 100644
--- a/services/core/java/com/android/server/pm/PackageAbiHelperImpl.java
+++ b/services/core/java/com/android/server/pm/PackageAbiHelperImpl.java
@@ -133,8 +133,10 @@ final class PackageAbiHelperImpl implements PackageAbiHelper {
@Override
public NativeLibraryPaths getNativeLibraryPaths(AndroidPackage pkg, PackageSetting pkgSetting,
File appLib32InstallDir) {
- return getNativeLibraryPaths(new Abis(pkg, pkgSetting), appLib32InstallDir,
- pkg.getCodePath(), pkg.getBaseCodePath(), pkg.isSystem(),
+ // Trying to derive the paths, thus need the raw ABI info from the parsed package, and the
+ // current state in PackageSetting is irrelevant.
+ return getNativeLibraryPaths(new Abis(pkg.getPrimaryCpuAbi(), pkg.getSecondaryCpuAbi()),
+ appLib32InstallDir, pkg.getCodePath(), pkg.getBaseCodePath(), pkg.isSystem(),
pkgSetting.getPkgState().isUpdatedSystemApp());
}
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 7ab05c4f762c..de8ad6b7db13 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -2108,6 +2108,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
baseApk = apk;
}
+ // Validate and add Dex Metadata (.dm).
final File dexMetadataFile = DexMetadataHelper.findDexMetadataForFile(addedFile);
if (dexMetadataFile != null) {
if (!FileUtils.isValidExtFilename(dexMetadataFile.getName())) {
@@ -2295,6 +2296,13 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
throw new PackageManagerException(INSTALL_FAILED_MISSING_SPLIT,
"Missing split for " + mPackageName);
}
+
+ final boolean isInstallerShell = (mInstallerUid == Process.SHELL_UID);
+ if (isInstallerShell && isIncrementalInstallation() && mIncrementalFileStorages != null) {
+ if (!baseApk.debuggable && !baseApk.profilableByShell) {
+ mIncrementalFileStorages.disableReadLogs();
+ }
+ }
}
private void resolveAndStageFile(File origFile, File targetFile)
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index ae8b3a0e9acc..dc7ed34fb0be 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -2988,7 +2988,7 @@ public class PackageManagerService extends IPackageManager.Stub
t.traceEnd();
t.traceBegin("read user settings");
- mFirstBoot = !mSettings.readLPw(mUserManager.getUsers(false));
+ mFirstBoot = !mSettings.readLPw(mInjector.getUserManagerInternal().getUsers(false));
t.traceEnd();
// Clean up orphaned packages for which the code path doesn't exist
@@ -3175,6 +3175,10 @@ public class PackageManagerService extends IPackageManager.Stub
psit.remove();
logCriticalInfo(Log.WARN, "System package " + ps.name
+ " no longer exists; it's data will be wiped");
+
+ // Assume package is truly gone and wipe residual permissions.
+ mPermissionManager.updatePermissions(ps.name, null);
+
// Actual deletion of code and data will be handled by later
// reconciliation step
} else {
@@ -3427,7 +3431,7 @@ public class PackageManagerService extends IPackageManager.Stub
// boot, then we need to initialize the default preferred apps across
// all defined users.
if (!mOnlyCore && (mPromoteSystemApps || mFirstBoot)) {
- for (UserInfo user : mUserManager.getUsers(true)) {
+ for (UserInfo user : mInjector.getUserManagerInternal().getUsers(true)) {
mSettings.applyDefaultPreferredAppsLPw(user.id);
primeDomainVerificationsLPw(user.id);
}
@@ -12144,15 +12148,17 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
- // Ensure the package is signed with at least the minimum signature scheme version
- // required for its target SDK.
- int minSignatureSchemeVersion =
- ApkSignatureVerifier.getMinimumSignatureSchemeVersionForTargetSdk(
- pkg.getTargetSdkVersion());
- if (pkg.getSigningDetails().signatureSchemeVersion < minSignatureSchemeVersion) {
- throw new PackageManagerException(INSTALL_PARSE_FAILED_NO_CERTIFICATES,
- "No signature found in package of version " + minSignatureSchemeVersion
- + " or newer for package " + pkg.getPackageName());
+ // If the package is not on a system partition ensure it is signed with at least the
+ // minimum signature scheme version required for its target SDK.
+ if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
+ int minSignatureSchemeVersion =
+ ApkSignatureVerifier.getMinimumSignatureSchemeVersionForTargetSdk(
+ pkg.getTargetSdkVersion());
+ if (pkg.getSigningDetails().signatureSchemeVersion < minSignatureSchemeVersion) {
+ throw new PackageManagerException(INSTALL_PARSE_FAILED_NO_CERTIFICATES,
+ "No signature found in package of version " + minSignatureSchemeVersion
+ + " or newer for package " + pkg.getPackageName());
+ }
}
}
}
@@ -12362,7 +12368,7 @@ public class PackageManagerService extends IPackageManager.Stub
ksms.addScannedPackageLPw(pkg);
mComponentResolver.addAllComponents(pkg, chatty);
- mAppsFilter.addPackage(pkgSetting, mSettings.mPackages);
+ mAppsFilter.addPackage(pkgSetting);
// Don't allow ephemeral applications to define new permissions groups.
if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
@@ -12536,8 +12542,6 @@ public class PackageManagerService extends IPackageManager.Stub
void cleanPackageDataStructuresLILPw(AndroidPackage pkg, boolean chatty) {
mComponentResolver.removeAllComponents(pkg, chatty);
- mAppsFilter.removePackage(getPackageSetting(pkg.getPackageName()),
- mInjector.getUserManagerInternal().getUserIds(), mSettings.mPackages);
mPermissionManager.removeAllPermissions(pkg, chatty);
final int instrumentationSize = ArrayUtils.size(pkg.getInstrumentations());
@@ -14264,7 +14268,7 @@ public class PackageManagerService extends IPackageManager.Stub
// Okay!
targetPackageSetting.setInstallerPackageName(installerPackageName);
mSettings.addInstallerPackageNames(targetPackageSetting.installSource);
- mAppsFilter.addPackage(targetPackageSetting, mSettings.mPackages);
+ mAppsFilter.addPackage(targetPackageSetting);
scheduleWriteSettingsLocked();
}
}
@@ -18717,6 +18721,7 @@ public class PackageManagerService extends IPackageManager.Stub
clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL, true);
clearDefaultBrowserIfNeeded(packageName);
mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
+ mAppsFilter.removePackage(getPackageSetting(packageName));
removedAppId = mSettings.removePackageLPw(packageName);
if (outInfo != null) {
outInfo.removedAppId = removedAppId;
@@ -22138,7 +22143,7 @@ public class PackageManagerService extends IPackageManager.Stub
}
for (String packageName : apkList) {
setSystemAppHiddenUntilInstalled(packageName, true);
- for (UserInfo user : mUserManager.getUsers(false)) {
+ for (UserInfo user : mInjector.getUserManagerInternal().getUsers(false)) {
setSystemAppInstallState(packageName, false, user.id);
}
}
@@ -23474,6 +23479,7 @@ public class PackageManagerService extends IPackageManager.Stub
scheduleWritePackageRestrictionsLocked(userId);
scheduleWritePackageListLocked(userId);
primeDomainVerificationsLPw(userId);
+ mAppsFilter.onUsersChanged();
}
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
index 1fce07b0cbf1..03f4708c09c4 100644
--- a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
+++ b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
@@ -595,8 +595,8 @@ public class PackageManagerServiceUtils {
/** Returns true to force apk verification if the package is considered privileged. */
static boolean isApkVerificationForced(@Nullable PackageSetting ps) {
- return ps != null && ps.isPrivileged() && (
- isApkVerityEnabled() || isLegacyApkVerityEnabled());
+ // TODO(b/154310064): re-enable.
+ return false;
}
/**
diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java
index 8ccf837f64dc..6cd66c642a06 100644
--- a/services/core/java/com/android/server/pm/StagingManager.java
+++ b/services/core/java/com/android/server/pm/StagingManager.java
@@ -53,6 +53,7 @@ import android.os.ParcelableException;
import android.os.PowerManager;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManagerInternal;
import android.os.storage.IStorageManager;
@@ -969,19 +970,19 @@ public class StagingManager {
// name and the session we are checking is not a parent session either.
continue;
}
-
- // From here on, stagedSession is a non-parent active staged session
-
// Check if stagedSession has an active parent session or not
if (stagedSession.hasParentSessionId()) {
int parentId = stagedSession.getParentSessionId();
PackageInstallerSession parentSession = mStagedSessions.get(parentId);
- if (parentSession == null || parentSession.isStagedAndInTerminalState()) {
+ if (parentSession == null || parentSession.isStagedAndInTerminalState()
+ || parentSession.isDestroyed()) {
// Parent session has been abandoned or terminated already
continue;
}
}
+ // From here on, stagedSession is a non-parent active staged session
+
// Check if session is one of the active sessions
if (session.sessionId == stagedSession.sessionId) {
Slog.w(TAG, "Session " + session.sessionId + " is already staged");
@@ -1155,6 +1156,11 @@ public class StagingManager {
}
private void checkStateAndResume(@NonNull PackageInstallerSession session) {
+ // Do not resume session if boot completed already
+ if (SystemProperties.getBoolean("sys.boot_completed", false)) {
+ return;
+ }
+
if (!session.isCommitted()) {
// Session hasn't been committed yet, ignore.
return;
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 2a6997cba4bb..27924a68ff48 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -751,13 +751,19 @@ public class UserManagerService extends IUserManager.Stub {
}
public @NonNull List<UserInfo> getUsers(boolean excludeDying) {
- return getUsers(/*excludePartial= */ true, excludeDying, /* excludePreCreated= */ true);
+ return getUsers(/*excludePartial= */ true, excludeDying, /* excludePreCreated= */
+ true);
}
@Override
public @NonNull List<UserInfo> getUsers(boolean excludePartial, boolean excludeDying,
boolean excludePreCreated) {
checkManageOrCreateUsersPermission("query users");
+ return getUsersInternal(excludePartial, excludeDying, excludePreCreated);
+ }
+
+ private @NonNull List<UserInfo> getUsersInternal(boolean excludePartial, boolean excludeDying,
+ boolean excludePreCreated) {
synchronized (mUsersLock) {
ArrayList<UserInfo> users = new ArrayList<UserInfo>(mUsers.size());
final int userSize = mUsers.size();
@@ -3291,11 +3297,13 @@ public class UserManagerService extends IUserManager.Stub {
final TimingsTraceAndSlog t = new TimingsTraceAndSlog();
t.traceBegin("createUser-" + flags);
final long sessionId = logUserCreateJourneyBegin(nextProbableUserId, userType, flags);
+ UserInfo newUser = null;
try {
- return createUserInternalUncheckedNoTracing(name, userType, flags, parentId,
- preCreate, disallowedPackages, t);
+ newUser = createUserInternalUncheckedNoTracing(name, userType, flags, parentId,
+ preCreate, disallowedPackages, t);
+ return newUser;
} finally {
- logUserCreateJourneyFinish(sessionId, nextProbableUserId);
+ logUserCreateJourneyFinish(sessionId, nextProbableUserId, newUser != null);
t.traceEnd();
}
}
@@ -3314,10 +3322,11 @@ public class UserManagerService extends IUserManager.Stub {
return sessionId;
}
- private void logUserCreateJourneyFinish(long sessionId, @UserIdInt int userId) {
+ private void logUserCreateJourneyFinish(long sessionId, @UserIdInt int userId, boolean finish) {
FrameworkStatsLog.write(FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED, sessionId, userId,
FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED__EVENT__CREATE_USER,
- FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED__STATE__FINISH);
+ finish ? FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED__STATE__FINISH
+ : FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED__STATE__NONE);
}
private UserInfo createUserInternalUncheckedNoTracing(@Nullable String name,
@@ -5042,6 +5051,12 @@ public class UserManagerService extends IUserManager.Stub {
}
@Override
+ public @NonNull List<UserInfo> getUsers(boolean excludeDying) {
+ return UserManagerService.this.getUsersInternal(/*excludePartial= */ true,
+ excludeDying, /* excludePreCreated= */ true);
+ }
+
+ @Override
public boolean isUserUnlockingOrUnlocked(@UserIdInt int userId) {
int state;
synchronized (mUserStates) {
diff --git a/services/core/java/com/android/server/pm/dex/ArtManagerService.java b/services/core/java/com/android/server/pm/dex/ArtManagerService.java
index 51e07faf8443..8000c639139f 100644
--- a/services/core/java/com/android/server/pm/dex/ArtManagerService.java
+++ b/services/core/java/com/android/server/pm/dex/ArtManagerService.java
@@ -63,6 +63,10 @@ import libcore.io.IoUtils;
import java.io.File;
import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
import java.util.Objects;
/**
@@ -557,6 +561,20 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub {
private static final int TRON_COMPILATION_FILTER_FAKE_RUN_FROM_APK = 12;
private static final int TRON_COMPILATION_FILTER_FAKE_RUN_FROM_APK_FALLBACK = 13;
private static final int TRON_COMPILATION_FILTER_FAKE_RUN_FROM_VDEX_FALLBACK = 14;
+ // Filter with IORap
+ private static final int TRON_COMPILATION_FILTER_ASSUMED_VERIFIED_IORAP = 15;
+ private static final int TRON_COMPILATION_FILTER_EXTRACT_IORAP = 16;
+ private static final int TRON_COMPILATION_FILTER_VERIFY_IORAP = 17;
+ private static final int TRON_COMPILATION_FILTER_QUICKEN_IORAP = 18;
+ private static final int TRON_COMPILATION_FILTER_SPACE_PROFILE_IORAP = 19;
+ private static final int TRON_COMPILATION_FILTER_SPACE_IORAP = 20;
+ private static final int TRON_COMPILATION_FILTER_SPEED_PROFILE_IORAP = 21;
+ private static final int TRON_COMPILATION_FILTER_SPEED_IORAP = 22;
+ private static final int TRON_COMPILATION_FILTER_EVERYTHING_PROFILE_IORAP = 23;
+ private static final int TRON_COMPILATION_FILTER_EVERYTHING_IORAP = 24;
+ private static final int TRON_COMPILATION_FILTER_FAKE_RUN_FROM_APK_IORAP = 25;
+ private static final int TRON_COMPILATION_FILTER_FAKE_RUN_FROM_APK_FALLBACK_IORAP = 26;
+ private static final int TRON_COMPILATION_FILTER_FAKE_RUN_FROM_VDEX_FALLBACK_IORAP = 27;
// Constants used for logging compilation reason to TRON.
// DO NOT CHANGE existing values.
@@ -623,6 +641,22 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub {
return TRON_COMPILATION_FILTER_FAKE_RUN_FROM_APK_FALLBACK;
case "run-from-vdex-fallback" :
return TRON_COMPILATION_FILTER_FAKE_RUN_FROM_VDEX_FALLBACK;
+ case "assume-verified-iorap" : return TRON_COMPILATION_FILTER_ASSUMED_VERIFIED_IORAP;
+ case "extract-iorap" : return TRON_COMPILATION_FILTER_EXTRACT_IORAP;
+ case "verify-iorap" : return TRON_COMPILATION_FILTER_VERIFY_IORAP;
+ case "quicken-iorap" : return TRON_COMPILATION_FILTER_QUICKEN_IORAP;
+ case "space-profile-iorap" : return TRON_COMPILATION_FILTER_SPACE_PROFILE_IORAP;
+ case "space-iorap" : return TRON_COMPILATION_FILTER_SPACE_IORAP;
+ case "speed-profile-iorap" : return TRON_COMPILATION_FILTER_SPEED_PROFILE_IORAP;
+ case "speed-iorap" : return TRON_COMPILATION_FILTER_SPEED_IORAP;
+ case "everything-profile-iorap" :
+ return TRON_COMPILATION_FILTER_EVERYTHING_PROFILE_IORAP;
+ case "everything-iorap" : return TRON_COMPILATION_FILTER_EVERYTHING_IORAP;
+ case "run-from-apk-iorap" : return TRON_COMPILATION_FILTER_FAKE_RUN_FROM_APK_IORAP;
+ case "run-from-apk-fallback-iorap" :
+ return TRON_COMPILATION_FILTER_FAKE_RUN_FROM_APK_FALLBACK_IORAP;
+ case "run-from-vdex-fallback-iorap" :
+ return TRON_COMPILATION_FILTER_FAKE_RUN_FROM_VDEX_FALLBACK_IORAP;
default: return TRON_COMPILATION_FILTER_UNKNOWN;
}
}
@@ -640,9 +674,12 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub {
}
private class ArtManagerInternalImpl extends ArtManagerInternal {
+ private static final String IORAP_DIR = "/data/misc/iorapd";
+ private static final String TAG = "ArtManagerInternalImpl";
+
@Override
public PackageOptimizationInfo getPackageOptimizationInfo(
- ApplicationInfo info, String abi) {
+ ApplicationInfo info, String abi, String activityName) {
String compilationReason;
String compilationFilter;
try {
@@ -662,11 +699,45 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub {
compilationReason = "error";
}
+ if (checkIorapCompiledTrace(info.packageName, activityName, info.longVersionCode)) {
+ compilationFilter = compilationFilter + "-iorap";
+ }
+
int compilationFilterTronValue = getCompilationFilterTronValue(compilationFilter);
int compilationReasonTronValue = getCompilationReasonTronValue(compilationReason);
return new PackageOptimizationInfo(
compilationFilterTronValue, compilationReasonTronValue);
}
+
+ /*
+ * Checks the existence of IORap compiled trace for an app.
+ *
+ * @return true if the compiled trace exists and the size is greater than 1kb.
+ */
+ private boolean checkIorapCompiledTrace(
+ String packageName, String activityName, long version) {
+ // For example: /data/misc/iorapd/com.google.android.GoogleCamera/
+ // 60092239/com.android.camera.CameraLauncher/compiled_traces/compiled_trace.pb
+ Path tracePath = Paths.get(IORAP_DIR,
+ packageName,
+ Long.toString(version),
+ activityName,
+ "compiled_traces",
+ "compiled_trace.pb");
+ try {
+ boolean exists = Files.exists(tracePath);
+ Log.d(TAG, tracePath.toString() + (exists? " exists" : " doesn't exist"));
+ if (exists) {
+ long bytes = Files.size(tracePath);
+ Log.d(TAG, tracePath.toString() + " size is " + Long.toString(bytes));
+ return bytes > 0L;
+ }
+ return exists;
+ } catch (IOException e) {
+ Log.d(TAG, e.getMessage());
+ 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 d3f3ba1dc6bb..1b11e2d0860d 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -2509,6 +2509,9 @@ public class PermissionManagerService extends IPermissionManager.Stub {
for (String permissionName : requestedPermissions) {
BasePermission permission = mSettings.getPermission(permissionName);
+ if (permission == null) {
+ continue;
+ }
if (Objects.equals(permission.getSourcePackageName(), PLATFORM_PACKAGE_NAME)
&& permission.isRuntime() && !permission.isRemoved()) {
if (permission.isHardOrSoftRestricted()
diff --git a/services/core/java/com/android/server/policy/PermissionPolicyService.java b/services/core/java/com/android/server/policy/PermissionPolicyService.java
index 3ee5f5097d59..37f088b170eb 100644
--- a/services/core/java/com/android/server/policy/PermissionPolicyService.java
+++ b/services/core/java/com/android/server/policy/PermissionPolicyService.java
@@ -825,7 +825,15 @@ public final class PermissionPolicyService extends SystemService {
return;
}
- if (pkgInfo == null || pkg == null || pkgInfo.requestedPermissions == null) {
+ if (pkgInfo == null || pkg == null || pkgInfo.applicationInfo == null
+ || pkgInfo.requestedPermissions == null) {
+ return;
+ }
+
+ final int uid = pkgInfo.applicationInfo.uid;
+ if (uid == Process.ROOT_UID || uid == Process.SYSTEM_UID) {
+ // Root and system server always pass permission checks, so don't touch their app
+ // ops to keep compatibility.
return;
}
diff --git a/services/core/java/com/android/server/power/batterysaver/BatterySaverController.java b/services/core/java/com/android/server/power/batterysaver/BatterySaverController.java
index 8b6e9a46ca91..2e5c0f460c7a 100644
--- a/services/core/java/com/android/server/power/batterysaver/BatterySaverController.java
+++ b/services/core/java/com/android/server/power/batterysaver/BatterySaverController.java
@@ -510,7 +510,8 @@ public class BatterySaverController implements BatterySaverPolicyListener {
if (getPowerSaveModeChangedListenerPackage().isPresent()) {
intent = new Intent(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED)
.setPackage(getPowerSaveModeChangedListenerPackage().get())
- .addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
+ .addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
+ | Intent.FLAG_RECEIVER_FOREGROUND);
mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
}
diff --git a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
index 7fe21e32cbaf..09fd33d5b4ed 100644
--- a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
+++ b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
@@ -212,7 +212,7 @@ public class StatsPullAtomService extends SystemService {
private static final int DIMENSION_KEY_SIZE_HARD_LIMIT = 800;
private static final int DIMENSION_KEY_SIZE_SOFT_LIMIT = 500;
private static final long APP_OPS_SAMPLING_INITIALIZATION_DELAY_MILLIS = 45000;
- private static final int APP_OPS_SIZE_ESTIMATE = 5000;
+ private static final int APP_OPS_SIZE_ESTIMATE = 2000;
private static final String RESULT_RECEIVER_CONTROLLER_KEY = "controller_activity";
/**
@@ -236,6 +236,17 @@ public class StatsPullAtomService extends SystemService {
private static final String DANGEROUS_PERMISSION_STATE_SAMPLE_RATE =
"dangerous_permission_state_sample_rate";
+ /** Parameters relating to ProcStats data upload. */
+ // Maximum shards to use when generating StatsEvent objects from ProcStats.
+ private static final int MAX_PROCSTATS_SHARDS = 5;
+ // Should match MAX_PAYLOAD_SIZE in StatsEvent, minus a small amount for overhead/metadata.
+ private static final int MAX_PROCSTATS_SHARD_SIZE = 48 * 1024; // 48 KB
+ // In ProcessStats, we measure the size of a raw ProtoOutputStream, before compaction. This
+ // typically runs 35-45% larger than the compacted size that will be written to StatsEvent.
+ // Hence, we can allow a little more room in each shard before moving to the next. Make this
+ // 20% as a conservative estimate.
+ private static final int MAX_PROCSTATS_RAW_SHARD_SIZE = (int) (MAX_PROCSTATS_SHARD_SIZE * 1.20);
+
private final Object mThermalLock = new Object();
@GuardedBy("mThermalLock")
private IThermalService mThermalService;
@@ -309,8 +320,7 @@ public class StatsPullAtomService extends SystemService {
private StatsPullAtomCallbackImpl mStatsCallbackImpl;
- private final Object mAppOpsSamplingRateLock = new Object();
- @GuardedBy("mAppOpsSamplingRateLock")
+ @GuardedBy("mAttributedAppOpsLock")
private int mAppOpsSamplingRate = 0;
private final Object mDangerousAppOpsListLock = new Object();
@GuardedBy("mDangerousAppOpsListLock")
@@ -2554,19 +2564,26 @@ public class StatsPullAtomService extends SystemService {
long lastHighWaterMark = readProcStatsHighWaterMark(section);
List<ParcelFileDescriptor> statsFiles = new ArrayList<>();
+ ProtoOutputStream[] protoStreams = new ProtoOutputStream[MAX_PROCSTATS_SHARDS];
+ for (int i = 0; i < protoStreams.length; i++) {
+ protoStreams[i] = new ProtoOutputStream();
+ }
+
ProcessStats procStats = new ProcessStats(false);
+ // Force processStatsService to aggregate all in-storage and in-memory data.
long highWaterMark = processStatsService.getCommittedStatsMerged(
lastHighWaterMark, section, true, statsFiles, procStats);
+ procStats.dumpAggregatedProtoForStatsd(protoStreams, MAX_PROCSTATS_RAW_SHARD_SIZE);
- // aggregate the data together for westworld consumption
- ProtoOutputStream proto = new ProtoOutputStream();
- procStats.dumpAggregatedProtoForStatsd(proto);
-
- StatsEvent e = StatsEvent.newBuilder()
- .setAtomId(atomTag)
- .writeByteArray(proto.getBytes())
- .build();
- pulledData.add(e);
+ for (ProtoOutputStream proto : protoStreams) {
+ if (proto.getBytes().length > 0) {
+ StatsEvent e = StatsEvent.newBuilder()
+ .setAtomId(atomTag)
+ .writeByteArray(proto.getBytes())
+ .build();
+ pulledData.add(e);
+ }
+ }
new File(mBaseDir.getAbsolutePath() + "/" + section + "_" + lastHighWaterMark)
.delete();
@@ -3066,7 +3083,7 @@ public class StatsPullAtomService extends SystemService {
int pullDangerousPermissionStateLocked(int atomTag, List<StatsEvent> pulledData) {
final long token = Binder.clearCallingIdentity();
float samplingRate = DeviceConfig.getFloat(DeviceConfig.NAMESPACE_PERMISSIONS,
- DANGEROUS_PERMISSION_STATE_SAMPLE_RATE, 0.02f);
+ DANGEROUS_PERMISSION_STATE_SAMPLE_RATE, 0.015f);
Set<Integer> reportedUids = new HashSet<>();
try {
PackageManager pm = mContext.getPackageManager();
@@ -3461,23 +3478,21 @@ public class StatsPullAtomService extends SystemService {
HistoricalOps histOps = ops.get(EXTERNAL_STATS_SYNC_TIMEOUT_MILLIS,
TimeUnit.MILLISECONDS);
- synchronized (mAppOpsSamplingRateLock) {
- if (mAppOpsSamplingRate == 0) {
- mContext.getMainThreadHandler().postDelayed(new Runnable() {
- @Override
- public void run() {
- try {
- estimateAppOpsSamplingRate();
- } catch (Throwable e) {
- Slog.e(TAG, "AppOps sampling ratio estimation failed: ", e);
- synchronized (mAppOpsSamplingRateLock) {
- mAppOpsSamplingRate = min(mAppOpsSamplingRate, 10);
- }
+ if (mAppOpsSamplingRate == 0) {
+ mContext.getMainThreadHandler().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ estimateAppOpsSamplingRate();
+ } catch (Throwable e) {
+ Slog.e(TAG, "AppOps sampling ratio estimation failed: ", e);
+ synchronized (mAttributedAppOpsLock) {
+ mAppOpsSamplingRate = min(mAppOpsSamplingRate, 10);
}
}
- }, APP_OPS_SAMPLING_INITIALIZATION_DELAY_MILLIS);
- mAppOpsSamplingRate = 100;
- }
+ }
+ }, APP_OPS_SAMPLING_INITIALIZATION_DELAY_MILLIS);
+ mAppOpsSamplingRate = 100;
}
List<AppOpEntry> opsList =
@@ -3485,9 +3500,7 @@ public class StatsPullAtomService extends SystemService {
int newSamplingRate = sampleAppOps(pulledData, opsList, atomTag, mAppOpsSamplingRate);
- synchronized (mAppOpsSamplingRateLock) {
- mAppOpsSamplingRate = min(mAppOpsSamplingRate, newSamplingRate);
- }
+ mAppOpsSamplingRate = min(mAppOpsSamplingRate, newSamplingRate);
} catch (Throwable t) {
// TODO: catch exceptions at a more granular level
Slog.e(TAG, "Could not read appops", t);
@@ -3526,7 +3539,7 @@ public class StatsPullAtomService extends SystemService {
}
int estimatedSamplingRate = (int) constrain(
appOpsTargetCollectionSize * 100 / estimatedSize, 0, 100);
- synchronized (mAppOpsSamplingRateLock) {
+ synchronized (mAttributedAppOpsLock) {
mAppOpsSamplingRate = min(mAppOpsSamplingRate, estimatedSamplingRate);
}
}
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index 4ba58bd259fc..39e839dfc7e4 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -52,6 +52,7 @@ import android.view.WindowInsetsController.Appearance;
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.inputmethod.SoftInputShowHideReason;
import com.android.internal.statusbar.IStatusBar;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.statusbar.NotificationVisibility;
@@ -61,6 +62,7 @@ import com.android.internal.util.DumpUtils;
import com.android.internal.view.AppearanceRegion;
import com.android.server.LocalServices;
import com.android.server.UiThread;
+import com.android.server.inputmethod.InputMethodManagerInternal;
import com.android.server.notification.NotificationDelegate;
import com.android.server.policy.GlobalActionsProvider;
import com.android.server.power.ShutdownThread;
@@ -1402,6 +1404,17 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
}
@Override
+ public void hideCurrentInputMethodForBubbles() {
+ final long token = Binder.clearCallingIdentity();
+ try {
+ InputMethodManagerInternal.get().hideCurrentInputMethod(
+ SoftInputShowHideReason.HIDE_BUBBLES);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
+ @Override
public void grantInlineReplyUriPermission(String key, Uri uri, UserHandle user,
String packageName) {
enforceStatusBarService();
diff --git a/services/core/java/com/android/server/storage/AppFuseBridge.java b/services/core/java/com/android/server/storage/AppFuseBridge.java
index 9d6a64701e85..b00540fd2a52 100644
--- a/services/core/java/com/android/server/storage/AppFuseBridge.java
+++ b/services/core/java/com/android/server/storage/AppFuseBridge.java
@@ -56,6 +56,15 @@ public class AppFuseBridge implements Runnable {
public ParcelFileDescriptor addBridge(MountScope mountScope)
throws FuseUnavailableMountException, NativeDaemonConnectorException {
+ /*
+ ** Dead Lock between Java lock (AppFuseBridge.java) and Native lock (FuseBridgeLoop.cc)
+ **
+ ** (Thread A) Got Java lock (addBrdige) -> Try to get Native lock (native_add_brdige)
+ ** (Thread B) Got Native lock (FuseBrdigeLoop.start) -> Try to get Java lock (onClosed)
+ **
+ ** Guarantee the lock order (native lock -> java lock) when adding Bridge.
+ */
+ native_lock();
try {
synchronized (this) {
Preconditions.checkArgument(mScopes.indexOfKey(mountScope.mountId) < 0);
@@ -73,6 +82,7 @@ public class AppFuseBridge implements Runnable {
return result;
}
} finally {
+ native_unlock();
IoUtils.closeQuietly(mountScope);
}
}
@@ -159,4 +169,6 @@ public class AppFuseBridge implements Runnable {
private native void native_delete(long loop);
private native void native_start_loop(long loop);
private native int native_add_bridge(long loop, int mountId, int deviceId);
+ private native void native_lock();
+ private native void native_unlock();
}
diff --git a/services/core/java/com/android/server/storage/StorageSessionController.java b/services/core/java/com/android/server/storage/StorageSessionController.java
index 0fd77b9c03dd..37df5481d3c4 100644
--- a/services/core/java/com/android/server/storage/StorageSessionController.java
+++ b/services/core/java/com/android/server/storage/StorageSessionController.java
@@ -27,7 +27,6 @@ import android.content.pm.PackageManager;
import android.content.pm.ProviderInfo;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
-import android.os.Handler;
import android.os.IVold;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
@@ -238,7 +237,7 @@ public final class StorageSessionController {
*
* Does nothing if {@link #shouldHandle} is {@code false}
**/
- public void onReset(IVold vold, Handler handler) {
+ public void onReset(IVold vold, Runnable resetHandlerRunnable) {
if (!shouldHandle(null)) {
return;
}
@@ -280,7 +279,7 @@ public final class StorageSessionController {
connection.close();
}
- handler.removeCallbacksAndMessages(null);
+ resetHandlerRunnable.run();
synchronized (mLock) {
mConnections.clear();
mIsResetting = false;
diff --git a/services/core/java/com/android/server/storage/StorageUserConnection.java b/services/core/java/com/android/server/storage/StorageUserConnection.java
index 94a250236200..ed5706752cb2 100644
--- a/services/core/java/com/android/server/storage/StorageUserConnection.java
+++ b/services/core/java/com/android/server/storage/StorageUserConnection.java
@@ -62,7 +62,7 @@ import java.util.concurrent.TimeoutException;
public final class StorageUserConnection {
private static final String TAG = "StorageUserConnection";
- public static final int REMOTE_TIMEOUT_SECONDS = 5;
+ public static final int REMOTE_TIMEOUT_SECONDS = 20;
private final Object mLock = new Object();
private final Context mContext;
@@ -202,6 +202,7 @@ public final class StorageUserConnection {
try {
if (!latch.await(REMOTE_TIMEOUT_SECONDS, TimeUnit.SECONDS)) {
// TODO(b/140025078): Call ActivityManager ANR API?
+ Slog.wtf(TAG, "Failed to bind to the ExternalStorageService for user " + mUserId);
throw new TimeoutException("Latch wait for " + reason + " elapsed");
}
} catch (InterruptedException e) {
diff --git a/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java b/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java
index 41aa4ee65f30..7cb59dcbfb9b 100644
--- a/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java
+++ b/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java
@@ -21,6 +21,7 @@ import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningAppProcessInfo;
import android.content.Context;
+import android.media.IResourceManagerService;
import android.media.tv.TvInputManager;
import android.media.tv.tunerresourcemanager.CasSessionRequest;
import android.media.tv.tunerresourcemanager.IResourcesReclaimListener;
@@ -53,7 +54,7 @@ import java.util.Set;
*
* @hide
*/
-public class TunerResourceManagerService extends SystemService {
+public class TunerResourceManagerService extends SystemService implements IBinder.DeathRecipient {
private static final String TAG = "TunerResourceManagerService";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
@@ -76,6 +77,7 @@ public class TunerResourceManagerService extends SystemService {
private TvInputManager mTvInputManager;
private ActivityManager mActivityManager;
+ private IResourceManagerService mMediaResourceManager;
private UseCasePriorityHints mPriorityCongfig = new UseCasePriorityHints();
// An internal resource request count to help generate resource handle.
@@ -102,6 +104,22 @@ public class TunerResourceManagerService extends SystemService {
mActivityManager =
(ActivityManager) getContext().getSystemService(Context.ACTIVITY_SERVICE);
mPriorityCongfig.parse();
+
+ if (mMediaResourceManager == null) {
+ IBinder mediaResourceManagerBinder = getBinderService("media.resource_manager");
+ if (mediaResourceManagerBinder == null) {
+ Slog.w(TAG, "Resource Manager Service not available.");
+ return;
+ }
+ try {
+ mediaResourceManagerBinder.linkToDeath(this, /*flags*/ 0);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Could not link to death of native resource manager service.");
+ return;
+ }
+ mMediaResourceManager = IResourceManagerService.Stub.asInterface(
+ mediaResourceManagerBinder);
+ }
}
private final class BinderService extends ITunerResourceManager.Stub {
@@ -380,6 +398,19 @@ public class TunerResourceManagerService extends SystemService {
}
}
+ /**
+ * Handle the death of the native resource manager service
+ */
+ @Override
+ public void binderDied() {
+ if (DEBUG) {
+ Slog.w(TAG, "Native media resource manager service has died");
+ }
+ synchronized (mLock) {
+ mMediaResourceManager = null;
+ }
+ }
+
@VisibleForTesting
protected void registerClientProfileInternal(ResourceClientProfile profile,
IResourcesReclaimListener listener, int[] clientId) {
@@ -399,6 +430,16 @@ public class TunerResourceManagerService extends SystemService {
? Binder.getCallingPid() /*callingPid*/
: mTvInputManager.getClientPid(profile.getTvInputSessionId()); /*tvAppId*/
+ // Update Media Resource Manager with the tvAppId
+ if (profile.getTvInputSessionId() != null && mMediaResourceManager != null) {
+ try {
+ mMediaResourceManager.overridePid(Binder.getCallingPid(), pid);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Could not overridePid in resourceManagerSercice,"
+ + " remote exception: " + e);
+ }
+ }
+
ClientProfile clientProfile = new ClientProfile.Builder(clientId[0])
.tvInputSessionId(profile.getTvInputSessionId())
.useCase(profile.getUseCase())
@@ -415,6 +456,15 @@ public class TunerResourceManagerService extends SystemService {
Slog.d(TAG, "unregisterClientProfile(clientId=" + clientId + ")");
}
removeClientProfile(clientId);
+ // Remove the Media Resource Manager callingPid to tvAppId mapping
+ if (mMediaResourceManager != null) {
+ try {
+ mMediaResourceManager.overridePid(Binder.getCallingPid(), -1);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Could not overridePid in resourceManagerSercice when unregister,"
+ + " remote exception: " + e);
+ }
+ }
}
@VisibleForTesting
diff --git a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
index fb29f9a93215..189b21fb81a6 100644
--- a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
+++ b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
@@ -842,7 +842,8 @@ class ActivityMetricsLogger {
? PackageOptimizationInfo.createWithNoInfo()
: artManagerInternal.getPackageOptimizationInfo(
info.applicationInfo,
- info.launchedActivityAppRecordRequiredAbi);
+ info.launchedActivityAppRecordRequiredAbi,
+ info.launchedActivityName);
builder.addTaggedData(PACKAGE_OPTIMIZATION_COMPILATION_REASON,
packageOptimizationInfo.getCompilationReason());
builder.addTaggedData(PACKAGE_OPTIMIZATION_COMPILATION_FILTER,
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 01eb9c5cb3d9..319fd18faca5 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -2198,14 +2198,19 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
@Override
boolean isFocusable() {
+ return super.isFocusable() && (canReceiveKeys() || isAlwaysFocusable());
+ }
+
+ boolean canReceiveKeys() {
// TODO(156521483): Propagate the state down the hierarchy instead of checking the parent
- boolean canReceiveKeys = getWindowConfiguration().canReceiveKeys()
- && getTask().getWindowConfiguration().canReceiveKeys();
- return super.isFocusable() && (canReceiveKeys || isAlwaysFocusable());
+ return getWindowConfiguration().canReceiveKeys()
+ && (task == null || task.getWindowConfiguration().canReceiveKeys());
}
boolean isResizeable() {
- return ActivityInfo.isResizeableMode(info.resizeMode) || info.supportsPictureInPicture();
+ return mAtmService.mForceResizableActivities
+ || ActivityInfo.isResizeableMode(info.resizeMode)
+ || info.supportsPictureInPicture();
}
/** @return whether this activity is non-resizeable or forced to be resizeable */
@@ -2370,10 +2375,10 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
// For the apps below Q, there can be only one app which has the focused window per
// process, because legacy apps may not be ready for a multi-focus system.
return false;
+
}
}
- return (getWindowConfiguration().canReceiveKeys() || isAlwaysFocusable())
- && getDisplay() != null;
+ return (canReceiveKeys() || isAlwaysFocusable()) && getDisplay() != null;
}
/**
@@ -3355,6 +3360,13 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
final long origId = Binder.clearCallingIdentity();
try {
+ // Link the fixed rotation transform to this activity since we are transferring the
+ // starting window.
+ if (fromActivity.hasFixedRotationTransform()) {
+ mDisplayContent.handleTopActivityLaunchingInDifferentOrientation(this,
+ false /* checkOpening */);
+ }
+
// Transfer the starting window over to the new token.
mStartingData = fromActivity.mStartingData;
startingSurface = fromActivity.startingSurface;
@@ -4331,9 +4343,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
* screenshot.
*/
boolean shouldUseAppThemeSnapshot() {
- return mDisablePreviewScreenshots || forAllWindows(w -> {
- return mWmService.isSecureLocked(w);
- }, true /* topToBottom */);
+ return mDisablePreviewScreenshots || forAllWindows(WindowState::isSecureLocked,
+ true /* topToBottom */);
}
/**
@@ -6446,14 +6457,15 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
@Override
public boolean matchParentBounds() {
- if (super.matchParentBounds() && mCompatDisplayInsets == null) {
+ final Rect overrideBounds = getResolvedOverrideBounds();
+ if (overrideBounds.isEmpty()) {
return true;
}
- // An activity in size compatibility mode may have resolved override bounds, so the exact
- // bounds should also be checked. Otherwise IME window will show with offset. See
- // {@link DisplayContent#isImeAttachedToApp}.
+ // An activity in size compatibility mode may have override bounds which equals to its
+ // parent bounds, so the exact bounds should also be checked to allow IME window to attach
+ // to the activity. See {@link DisplayContent#isImeAttachedToApp}.
final WindowContainer parent = getParent();
- return parent == null || parent.getBounds().equals(getResolvedOverrideBounds());
+ return parent == null || parent.getBounds().equals(overrideBounds);
}
@Override
@@ -7717,24 +7729,25 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
outAppBounds.set(outBounds);
}
} else {
- outBounds.set(0, 0, mWidth, mHeight);
- getFrameByOrientation(outAppBounds, orientation);
- if (orientationRequested && !canChangeOrientation
- && (outAppBounds.width() > outAppBounds.height()) != (mWidth > mHeight)) {
- // The orientation is mismatched but the display cannot rotate. The bounds will
- // fit to the short side of display.
- if (orientation == ORIENTATION_LANDSCAPE) {
- outAppBounds.bottom = (int) ((float) mWidth * mWidth / mHeight);
- outAppBounds.right = mWidth;
- } else {
- outAppBounds.bottom = mHeight;
- outAppBounds.right = (int) ((float) mHeight * mHeight / mWidth);
+ if (orientationRequested) {
+ getFrameByOrientation(outBounds, orientation);
+ if ((outBounds.width() > outBounds.height()) != (mWidth > mHeight)) {
+ // The orientation is mismatched but the display cannot rotate. The bounds
+ // will fit to the short side of display.
+ if (orientation == ORIENTATION_LANDSCAPE) {
+ outBounds.bottom = (int) ((float) mWidth * mWidth / mHeight);
+ outBounds.right = mWidth;
+ } else {
+ outBounds.bottom = mHeight;
+ outBounds.right = (int) ((float) mHeight * mHeight / mWidth);
+ }
+ outBounds.offset(
+ getHorizontalCenterOffset(mWidth, outBounds.width()), 0 /* dy */);
}
- outAppBounds.offset(getHorizontalCenterOffset(outBounds.width(),
- outAppBounds.width()), 0 /* dy */);
} else {
- outAppBounds.set(outBounds);
+ outBounds.set(0, 0, mWidth, mHeight);
}
+ outAppBounds.set(outBounds);
}
if (rotation != ROTATION_UNDEFINED) {
diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index 4bede4c3623f..b4bc0f5b3a32 100644
--- a/services/core/java/com/android/server/wm/ActivityStack.java
+++ b/services/core/java/com/android/server/wm/ActivityStack.java
@@ -813,7 +813,7 @@ class ActivityStack extends Task {
/** Resume next focusable stack after reparenting to another display. */
void postReparent() {
adjustFocusToNextFocusableTask("reparent", true /* allowFocusSelf */,
- true /* moveParentsToTop */);
+ true /* moveDisplayToTop */);
mRootWindowContainer.resumeFocusedStacksTopActivities();
// Update visibility of activities before notifying WM. This way it won't try to resize
// windows that are no longer visible.
diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
index 1f9e8609c2ad..407b9fcbca74 100644
--- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
@@ -73,6 +73,7 @@ import static com.android.server.wm.RootWindowContainer.MATCH_TASK_IN_STACKS_OR_
import static com.android.server.wm.RootWindowContainer.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE;
import static com.android.server.wm.RootWindowContainer.TAG_STATES;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION;
+import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_RECENTS;
import static com.android.server.wm.Task.FLAG_FORCE_HIDDEN_FOR_PINNED_TASK;
import static com.android.server.wm.Task.LOCK_TASK_AUTH_LAUNCHABLE;
import static com.android.server.wm.Task.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
@@ -1809,7 +1810,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks {
for (int i = mStoppingActivities.size() - 1; i >= 0; --i) {
final ActivityRecord s = mStoppingActivities.get(i);
final boolean animating = s.isAnimating(TRANSITION | PARENTS,
- ANIMATION_TYPE_APP_TRANSITION);
+ ANIMATION_TYPE_APP_TRANSITION | ANIMATION_TYPE_RECENTS);
if (DEBUG_STATES) Slog.v(TAG, "Stopping " + s + ": nowVisible=" + s.nowVisible
+ " animating=" + animating + " finishing=" + s.finishing);
if (!animating || mService.mShuttingDown) {
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 6dd1ea934497..cf453c7feef8 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -3824,7 +3824,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
}
userId = activity.mUserId;
}
- return !DevicePolicyCache.getInstance().getScreenCaptureDisabled(userId);
+ return DevicePolicyCache.getInstance().isScreenCaptureAllowed(userId, false);
}
@Override
@@ -5413,7 +5413,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
final boolean hideDialogsSet = Settings.Global.getInt(mContext.getContentResolver(),
HIDE_ERROR_DIALOGS, 0) != 0;
mShowDialogs = inputMethodExists
- && ActivityTaskManager.currentUiModeSupportsErrorDialogs(mContext)
+ && ActivityTaskManager.currentUiModeSupportsErrorDialogs(config)
&& !hideDialogsSet;
}
@@ -6826,7 +6826,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
}
mWindowManager.closeSystemDialogs(reason);
- mRootWindowContainer.closeSystemDialogs();
+ mRootWindowContainer.closeSystemDialogActivities(reason);
}
// Call into AM outside the synchronized block.
mAmInternal.broadcastCloseSystemDialogs(reason);
diff --git a/services/core/java/com/android/server/wm/AppTaskImpl.java b/services/core/java/com/android/server/wm/AppTaskImpl.java
index 8fa811915fc2..dd1d55b2d54d 100644
--- a/services/core/java/com/android/server/wm/AppTaskImpl.java
+++ b/services/core/java/com/android/server/wm/AppTaskImpl.java
@@ -83,7 +83,8 @@ class AppTaskImpl extends IAppTask.Stub {
if (task == null) {
throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
}
- return mService.getRecentTasks().createRecentTaskInfo(task);
+ return mService.getRecentTasks().createRecentTaskInfo(task,
+ false /* stripExtras */);
} finally {
Binder.restoreCallingIdentity(origId);
}
diff --git a/services/core/java/com/android/server/wm/BLASTSyncEngine.java b/services/core/java/com/android/server/wm/BLASTSyncEngine.java
index efcb558fef66..6305fda4924c 100644
--- a/services/core/java/com/android/server/wm/BLASTSyncEngine.java
+++ b/services/core/java/com/android/server/wm/BLASTSyncEngine.java
@@ -16,17 +16,19 @@
package com.android.server.wm;
-import android.view.SurfaceControl;
+import android.util.ArrayMap;
+import android.util.ArraySet;
-import java.util.HashMap;
+import java.util.Set;
/**
- * Utility class for collecting and merging transactions from various sources asynchronously.
+ * Utility class for collecting WindowContainers that will merge transactions.
* For example to use to synchronously resize all the children of a window container
* 1. Open a new sync set, and pass the listener that will be invoked
* int id startSyncSet(TransactionReadyListener)
* the returned ID will be eventually passed to the TransactionReadyListener in combination
- * with the prepared transaction. You also use it to refer to the operation in future steps.
+ * with a set of WindowContainers that are ready, meaning onTransactionReady was called for
+ * those WindowContainers. You also use it to refer to the operation in future steps.
* 2. Ask each child to participate:
* addToSyncSet(int id, WindowContainer wc)
* if the child thinks it will be affected by a configuration change (a.k.a. has a visible
@@ -38,35 +40,37 @@ import java.util.HashMap;
* setReady(int id)
* 5. If there were no sub windows anywhere in the hierarchy to wait on, then
* transactionReady is immediately invoked, otherwise all the windows are poked
- * to redraw and to deliver a buffer to WMS#finishDrawing.
- * Once all this drawing is complete the combined transaction of all the buffers
- * and pending transaction hierarchy changes will be delivered to the TransactionReadyListener
+ * to redraw and to deliver a buffer to {@link WindowState#finishDrawing}.
+ * Once all this drawing is complete the WindowContainer that's ready will be added to the
+ * set of ready WindowContainers. When the final onTransactionReady is called, it will merge
+ * the transactions of the all the WindowContainers and will be delivered to the
+ * TransactionReadyListener
*/
class BLASTSyncEngine {
private static final String TAG = "BLASTSyncEngine";
interface TransactionReadyListener {
- void onTransactionReady(int mSyncId, SurfaceControl.Transaction mergedTransaction);
+ void onTransactionReady(int mSyncId, Set<WindowContainer> windowContainersReady);
};
// Holds state associated with a single synchronous set of operations.
class SyncState implements TransactionReadyListener {
int mSyncId;
- SurfaceControl.Transaction mMergedTransaction;
int mRemainingTransactions;
TransactionReadyListener mListener;
boolean mReady = false;
+ Set<WindowContainer> mWindowContainersReady = new ArraySet<>();
private void tryFinish() {
if (mRemainingTransactions == 0 && mReady) {
- mListener.onTransactionReady(mSyncId, mMergedTransaction);
+ mListener.onTransactionReady(mSyncId, mWindowContainersReady);
mPendingSyncs.remove(mSyncId);
}
}
- public void onTransactionReady(int mSyncId, SurfaceControl.Transaction mergedTransaction) {
+ public void onTransactionReady(int mSyncId, Set<WindowContainer> windowContainersReady) {
mRemainingTransactions--;
- mMergedTransaction.merge(mergedTransaction);
+ mWindowContainersReady.addAll(windowContainersReady);
tryFinish();
}
@@ -86,14 +90,13 @@ class BLASTSyncEngine {
SyncState(TransactionReadyListener l, int id) {
mListener = l;
mSyncId = id;
- mMergedTransaction = new SurfaceControl.Transaction();
mRemainingTransactions = 0;
}
};
- int mNextSyncId = 0;
+ private int mNextSyncId = 0;
- final HashMap<Integer, SyncState> mPendingSyncs = new HashMap();
+ private final ArrayMap<Integer, SyncState> mPendingSyncs = new ArrayMap<>();
BLASTSyncEngine() {
}
diff --git a/services/core/java/com/android/server/wm/BarController.java b/services/core/java/com/android/server/wm/BarController.java
index 8b14095874e3..26e0790a7604 100644
--- a/services/core/java/com/android/server/wm/BarController.java
+++ b/services/core/java/com/android/server/wm/BarController.java
@@ -59,6 +59,7 @@ public class BarController {
private final int mTransparentFlag;
private final int mStatusBarManagerId;
private final int mTranslucentWmFlag;
+ private final int mWindowType;
protected final Handler mHandler;
private final Object mServiceAquireLock = new Object();
private StatusBarManagerInternal mStatusBarInternal;
@@ -77,13 +78,14 @@ public class BarController {
private OnBarVisibilityChangedListener mVisibilityChangeListener;
BarController(String tag, int displayId, int transientFlag, int unhideFlag, int translucentFlag,
- int statusBarManagerId, int translucentWmFlag, int transparentFlag) {
+ int statusBarManagerId, int windowType, int translucentWmFlag, int transparentFlag) {
mTag = "BarController." + tag;
mDisplayId = displayId;
mTransientFlag = transientFlag;
mUnhideFlag = unhideFlag;
mTranslucentFlag = translucentFlag;
mStatusBarManagerId = statusBarManagerId;
+ mWindowType = windowType;
mTranslucentWmFlag = translucentWmFlag;
mTransparentFlag = transparentFlag;
mHandler = new BarHandler();
@@ -168,7 +170,12 @@ public class BarController {
}
boolean isTransparentAllowed(WindowState win) {
- return win == null || win.letterboxNotIntersectsOrFullyContains(mContentFrame);
+ if (win == null) {
+ return true;
+ }
+ final Rect rotatedContentFrame = win.mToken.getFixedRotationBarContentFrame(mWindowType);
+ final Rect contentFrame = rotatedContentFrame != null ? rotatedContentFrame : mContentFrame;
+ return win.letterboxNotIntersectsOrFullyContains(contentFrame);
}
boolean setBarShowingLw(final boolean show) {
diff --git a/services/core/java/com/android/server/wm/DisplayArea.java b/services/core/java/com/android/server/wm/DisplayArea.java
index b2fab9ae98c5..8260cb31acda 100644
--- a/services/core/java/com/android/server/wm/DisplayArea.java
+++ b/services/core/java/com/android/server/wm/DisplayArea.java
@@ -290,7 +290,7 @@ public class DisplayArea<T extends WindowContainer> extends WindowContainer<T> {
mDimmer.resetDimStates();
}
- if (mDimmer.updateDims(getSyncTransaction(), mTmpDimBoundsRect)) {
+ if (mDimmer.updateDims(getPendingTransaction(), mTmpDimBoundsRect)) {
scheduleAnimation();
}
}
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 4e19a5224bb4..9b5d94ebb1ac 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -32,6 +32,7 @@ import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_USER;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
+import static android.content.res.Configuration.ORIENTATION_UNDEFINED;
import static android.os.Build.VERSION_CODES.N;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static android.util.DisplayMetrics.DENSITY_DEFAULT;
@@ -209,6 +210,7 @@ import com.android.internal.util.function.pooled.PooledConsumer;
import com.android.internal.util.function.pooled.PooledFunction;
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.internal.util.function.pooled.PooledPredicate;
+import com.android.server.inputmethod.InputMethodManagerInternal;
import com.android.server.policy.WindowManagerPolicy;
import com.android.server.protolog.common.ProtoLog;
import com.android.server.wm.utils.DisplayRotationUtil;
@@ -728,7 +730,11 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
// Sets mBehindIme for each window. Windows behind IME can get IME insets.
if (w.mBehindIme != mTmpWindowsBehindIme) {
w.mBehindIme = mTmpWindowsBehindIme;
- mWinInsetsChanged.add(w);
+ if (getInsetsStateController().getRawInsetsState().getSourceOrDefaultVisibility(
+ ITYPE_IME)) {
+ // If IME is invisible, behind IME or not doesn't make the insets different.
+ mWinInsetsChanged.add(w);
+ }
}
if (w == mInputMethodWindow) {
mTmpWindowsBehindIme = true;
@@ -1424,7 +1430,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
*/
@Surface.Rotation
int rotationForActivityInDifferentOrientation(@NonNull ActivityRecord r) {
- if (!mWmService.mIsFixedRotationTransformEnabled) {
+ if (!WindowManagerService.ENABLE_FIXED_ROTATION_TRANSFORM) {
return ROTATION_UNDEFINED;
}
if (r.inMultiWindowMode()
@@ -1452,7 +1458,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
*/
boolean handleTopActivityLaunchingInDifferentOrientation(@NonNull ActivityRecord r,
boolean checkOpening) {
- if (!mWmService.mIsFixedRotationTransformEnabled) {
+ if (!WindowManagerService.ENABLE_FIXED_ROTATION_TRANSFORM) {
return false;
}
if (r.isFinishingFixedRotationTransform()) {
@@ -1463,9 +1469,10 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
return true;
}
if (checkOpening) {
- if (!mAppTransition.isTransitionSet() && !mOpeningApps.contains(r)) {
+ if (!mAppTransition.isTransitionSet() || !mOpeningApps.contains(r)) {
// Apply normal rotation animation in case of the activity set different requested
- // orientation without activity switch.
+ // orientation without activity switch, or the transition is unset due to starting
+ // window was transferred ({@link #mSkipAppTransitionAnimation}).
return false;
}
} else if (r != topRunningActivity()) {
@@ -1526,12 +1533,12 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
}
/**
- * Sets the provided record to {@link mFixedRotationLaunchingApp} if possible to apply fixed
+ * Sets the provided record to {@link #mFixedRotationLaunchingApp} if possible to apply fixed
* rotation transform to it and indicate that the display may be rotated after it is launched.
*/
void setFixedRotationLaunchingApp(@NonNull ActivityRecord r, @Surface.Rotation int rotation) {
final WindowToken prevRotatedLaunchingApp = mFixedRotationLaunchingApp;
- if (prevRotatedLaunchingApp != null && prevRotatedLaunchingApp == r
+ if (prevRotatedLaunchingApp == r
&& r.getWindowConfiguration().getRotation() == rotation) {
// The given launching app and target rotation are the same as the existing ones.
return;
@@ -2175,6 +2182,10 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
return (mDisplay.getFlags() & FLAG_PRIVATE) != 0;
}
+ boolean isTrusted() {
+ return mDisplay.isTrusted();
+ }
+
/**
* Returns the topmost stack on the display that is compatible with the input windowing mode and
* activity type. Null is no compatible stack on the display.
@@ -3522,7 +3533,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
}
boolean canShowIme() {
- if (isUntrustedVirtualDisplay()) {
+ if (!isTrusted()) {
return false;
}
return mWmService.mDisplayWindowSettings.shouldShowImeLocked(this)
@@ -3556,6 +3567,14 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
private void updateImeControlTarget() {
mInputMethodControlTarget = computeImeControlTarget();
mInsetsStateController.onImeControlTargetChanged(mInputMethodControlTarget);
+
+ final WindowState win = mInputMethodControlTarget != null
+ ? mInputMethodControlTarget.getWindow() : null;
+ final IBinder token = win != null ? win.mClient.asBinder() : null;
+ // Note: not allowed to call into IMMS with the WM lock held, hence the post.
+ mWmService.mH.post(() ->
+ InputMethodManagerInternal.get().reportImeControl(token)
+ );
}
private void updateImeParent() {
@@ -3777,7 +3796,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
}
boolean hasSecureWindowOnScreen() {
- final WindowState win = getWindow(w -> w.isOnScreen() && mWmService.isSecureLocked(w));
+ final WindowState win = getWindow(w -> w.isOnScreen() && w.isSecureLocked());
return win != null;
}
@@ -4753,15 +4772,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
// VR virtual display will be used to run and render 2D app within a VR experience.
&& mDisplayId != mWmService.mVr2dDisplayId
// Do not show system decorations on untrusted virtual display.
- && !isUntrustedVirtualDisplay();
- }
-
- /**
- * @return {@code true} if the display is non-system created virtual display.
- */
- boolean isUntrustedVirtualDisplay() {
- return mDisplay.getType() == Display.TYPE_VIRTUAL
- && mDisplay.getOwnerUid() != Process.SYSTEM_UID;
+ && isTrusted();
}
/**
@@ -5647,8 +5658,12 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
}
if (animatingRecents != null && animatingRecents == mFixedRotationLaunchingApp) {
- // Because it won't affect display orientation, just finish the transform.
- animatingRecents.finishFixedRotationTransform();
+ // The recents activity should be going to be invisible (switch to another app or
+ // return to original top). Only clear the top launching record without finishing
+ // the transform immediately because it won't affect display orientation. And before
+ // the visibility is committed, the recents activity may perform relayout which may
+ // cause unexpected configuration change if the rotated configuration is restored.
+ // The transform will be finished when the transition is done.
setFixedRotationLaunchingAppUnchecked(null);
} else {
// If there is already a launching activity that is not the recents, before its
@@ -5659,6 +5674,16 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
}
}
+ /**
+ * Return {@code true} if there is an ongoing animation to the "Recents" activity and this
+ * activity as a fixed orientation so shouldn't be rotated.
+ */
+ boolean isTopFixedOrientationRecentsAnimating() {
+ return mAnimatingRecents != null
+ && mAnimatingRecents.getRequestedConfigurationOrientation()
+ != ORIENTATION_UNDEFINED && !hasTopFixedRotationLaunchingApp();
+ }
+
@Override
public void onAppTransitionFinishedLocked(IBinder token) {
final ActivityRecord r = getActivityRecord(token);
@@ -5669,12 +5694,36 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
if (r == null || r == mAnimatingRecents) {
return;
}
- if (mFixedRotationLaunchingApp != null
- && mFixedRotationLaunchingApp.hasFixedRotationTransform(r)) {
- continueUpdateOrientationForDiffOrienLaunchingApp();
- } else {
+ if (mFixedRotationLaunchingApp == null) {
+ // In most cases this is a no-op if the activity doesn't have fixed rotation.
+ // Otherwise it could be from finishing recents animation while the display has
+ // different orientation.
r.finishFixedRotationTransform();
+ return;
+ }
+ if (mFixedRotationLaunchingApp.hasFixedRotationTransform(r)) {
+ if (mFixedRotationLaunchingApp.hasAnimatingFixedRotationTransition()) {
+ // Waiting until all of the associated activities have done animation, or the
+ // orientation would be updated too early and cause flickering.
+ return;
+ }
+ } else {
+ // Handle a corner case that the task of {@link #mFixedRotationLaunchingApp} is no
+ // longer animating but the corresponding transition finished event won't notify.
+ // E.g. activity A transferred starting window to B, only A will receive transition
+ // finished event. A doesn't have fixed rotation but B is the rotated launching app.
+ final Task task = r.getTask();
+ if (task == null || task != mFixedRotationLaunchingApp.getTask()) {
+ // Different tasks won't be in one activity transition animation.
+ return;
+ }
+ if (task.isAppTransitioning()) {
+ return;
+ // Continue to update orientation because the transition of the top rotated
+ // launching activity is done.
+ }
}
+ continueUpdateOrientationForDiffOrienLaunchingApp();
}
@Override
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index e244b5551d19..72b014cab2bb 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -151,6 +151,7 @@ import android.util.IntArray;
import android.util.Pair;
import android.util.PrintWriterPrinter;
import android.util.Slog;
+import android.util.SparseArray;
import android.view.DisplayCutout;
import android.view.Gravity;
import android.view.InputChannel;
@@ -199,6 +200,7 @@ import com.android.server.wallpaper.WallpaperManagerInternal;
import com.android.server.wm.utils.InsetUtils;
import java.io.PrintWriter;
+import java.util.function.Consumer;
/**
* The policy that provides the basic behaviors and states of a display to show UI.
@@ -471,6 +473,7 @@ public class DisplayPolicy {
View.NAVIGATION_BAR_UNHIDE,
View.NAVIGATION_BAR_TRANSLUCENT,
StatusBarManager.WINDOW_NAVIGATION_BAR,
+ TYPE_NAVIGATION_BAR,
FLAG_TRANSLUCENT_NAVIGATION,
View.NAVIGATION_BAR_TRANSPARENT);
@@ -1171,6 +1174,11 @@ public class DisplayPolicy {
displayFrames.mDisplayCutoutSafe.top);
}
+ @VisibleForTesting
+ StatusBarController getStatusBarController() {
+ return mStatusBarController;
+ }
+
WindowState getStatusBar() {
return mStatusBar;
}
@@ -1469,13 +1477,16 @@ public class DisplayPolicy {
}
private void simulateLayoutDecorWindow(WindowState win, DisplayFrames displayFrames,
- InsetsState insetsState, WindowFrames simulatedWindowFrames, Runnable layout) {
+ InsetsState insetsState, WindowFrames simulatedWindowFrames,
+ SparseArray<Rect> contentFrames, Consumer<Rect> layout) {
win.setSimulatedWindowFrames(simulatedWindowFrames);
+ final Rect contentFrame = new Rect();
try {
- layout.run();
+ layout.accept(contentFrame);
} finally {
win.setSimulatedWindowFrames(null);
}
+ contentFrames.put(win.mAttrs.type, contentFrame);
mDisplayContent.getInsetsStateController().computeSimulatedState(insetsState, win,
displayFrames, simulatedWindowFrames);
}
@@ -1487,24 +1498,25 @@ public class DisplayPolicy {
* state and some temporal states. In other words, it doesn't change the window frames used to
* show on screen.
*/
- void simulateLayoutDisplay(DisplayFrames displayFrames, InsetsState insetsState, int uiMode) {
+ void simulateLayoutDisplay(DisplayFrames displayFrames, InsetsState insetsState,
+ SparseArray<Rect> barContentFrames) {
displayFrames.onBeginLayout();
updateInsetsStateForDisplayCutout(displayFrames, insetsState);
insetsState.setDisplayFrame(displayFrames.mUnrestricted);
final WindowFrames simulatedWindowFrames = new WindowFrames();
if (mNavigationBar != null) {
- simulateLayoutDecorWindow(
- mNavigationBar, displayFrames, insetsState, simulatedWindowFrames,
- () -> layoutNavigationBar(displayFrames, uiMode, mLastNavVisible,
+ simulateLayoutDecorWindow(mNavigationBar, displayFrames, insetsState,
+ simulatedWindowFrames, barContentFrames,
+ contentFrame -> layoutNavigationBar(displayFrames,
+ mDisplayContent.getConfiguration().uiMode, mLastNavVisible,
mLastNavTranslucent, mLastNavAllowedHidden,
- mLastNotificationShadeForcesShowingNavigation,
- false /* isRealLayout */));
+ mLastNotificationShadeForcesShowingNavigation, contentFrame));
}
if (mStatusBar != null) {
- simulateLayoutDecorWindow(
- mStatusBar, displayFrames, insetsState, simulatedWindowFrames,
- () -> layoutStatusBar(displayFrames, mLastSystemUiFlags,
- false /* isRealLayout */));
+ simulateLayoutDecorWindow(mStatusBar, displayFrames, insetsState,
+ simulatedWindowFrames, barContentFrames,
+ contentFrame -> layoutStatusBar(displayFrames, mLastSystemUiFlags,
+ contentFrame));
}
layoutScreenDecorWindows(displayFrames, simulatedWindowFrames);
postAdjustDisplayFrames(displayFrames);
@@ -1556,9 +1568,10 @@ public class DisplayPolicy {
boolean updateSysUiVisibility = layoutNavigationBar(displayFrames, uiMode, navVisible,
navTranslucent, navAllowedHidden, notificationShadeForcesShowingNavigation,
- true /* isRealLayout */);
+ null /* simulatedContentFrame */);
if (DEBUG_LAYOUT) Slog.i(TAG, "mDock rect:" + displayFrames.mDock);
- updateSysUiVisibility |= layoutStatusBar(displayFrames, sysui, true /* isRealLayout */);
+ updateSysUiVisibility |= layoutStatusBar(displayFrames, sysui,
+ null /* simulatedContentFrame */);
if (updateSysUiVisibility) {
updateSystemUiVisibilityLw();
}
@@ -1579,10 +1592,9 @@ public class DisplayPolicy {
navControlTarget instanceof WindowState ? (WindowState) navControlTarget : null;
final InsetsState requestedState = navControllingWin != null
? navControllingWin.getRequestedInsetsState() : null;
- final InsetsSource navSource = requestedState != null
- ? requestedState.peekSource(ITYPE_NAVIGATION_BAR) : null;
- final boolean navVisible = navSource != null
- ? navSource.isVisible() : InsetsState.getDefaultVisibility(ITYPE_NAVIGATION_BAR);
+ final boolean navVisible = requestedState != null
+ ? requestedState.getSourceOrDefaultVisibility(ITYPE_NAVIGATION_BAR)
+ : InsetsState.getDefaultVisibility(ITYPE_NAVIGATION_BAR);
final boolean showBarsByTouch = navControllingWin != null
&& navControllingWin.mAttrs.insetsFlags.behavior == BEHAVIOR_SHOW_BARS_BY_TOUCH;
// When the navigation bar isn't visible, we put up a fake input window to catch all
@@ -1731,7 +1743,8 @@ public class DisplayPolicy {
displayFrames.mContent.set(dockFrame);
}
- private boolean layoutStatusBar(DisplayFrames displayFrames, int sysui, boolean isRealLayout) {
+ private boolean layoutStatusBar(DisplayFrames displayFrames, int sysui,
+ Rect simulatedContentFrame) {
// decide where the status bar goes ahead of time
if (mStatusBar == null) {
return false;
@@ -1754,12 +1767,14 @@ public class DisplayPolicy {
displayFrames.mStable.top = Math.max(displayFrames.mStable.top,
displayFrames.mDisplayCutoutSafe.top);
- if (isRealLayout) {
- // Tell the bar controller where the collapsed status bar content is.
- sTmpRect.set(windowFrames.mContentFrame);
- sTmpRect.intersect(displayFrames.mDisplayCutoutSafe);
- sTmpRect.top = windowFrames.mContentFrame.top; // Ignore top display cutout inset
- sTmpRect.bottom = displayFrames.mStable.top; // Use collapsed status bar size
+ // Tell the bar controller where the collapsed status bar content is.
+ sTmpRect.set(windowFrames.mContentFrame);
+ sTmpRect.intersect(displayFrames.mDisplayCutoutSafe);
+ sTmpRect.top = windowFrames.mContentFrame.top; // Ignore top display cutout inset
+ sTmpRect.bottom = displayFrames.mStable.top; // Use collapsed status bar size
+ if (simulatedContentFrame != null) {
+ simulatedContentFrame.set(sTmpRect);
+ } else {
mStatusBarController.setContentFrame(sTmpRect);
}
@@ -1796,7 +1811,7 @@ public class DisplayPolicy {
private boolean layoutNavigationBar(DisplayFrames displayFrames, int uiMode, boolean navVisible,
boolean navTranslucent, boolean navAllowedHidden,
- boolean statusBarForcesShowingNavigation, boolean isRealLayout) {
+ boolean statusBarForcesShowingNavigation, Rect simulatedContentFrame) {
if (mNavigationBar == null) {
return false;
}
@@ -1818,10 +1833,11 @@ public class DisplayPolicy {
if (navBarPosition == NAV_BAR_BOTTOM) {
// It's a system nav bar or a portrait screen; nav bar goes on bottom.
- final int top = cutoutSafeUnrestricted.bottom
- - getNavigationBarHeight(rotation, uiMode);
final int topNavBar = cutoutSafeUnrestricted.bottom
- getNavigationBarFrameHeight(rotation, uiMode);
+ final int top = mNavButtonForcedVisible
+ ? topNavBar
+ : cutoutSafeUnrestricted.bottom - getNavigationBarHeight(rotation, uiMode);
navigationFrame.set(0, topNavBar, displayWidth, displayFrames.mUnrestricted.bottom);
displayFrames.mStable.bottom = displayFrames.mStableFullscreen.bottom = top;
if (transientNavBarShowing) {
@@ -1900,7 +1916,9 @@ public class DisplayPolicy {
navigationFrame /* visibleFrame */, sTmpRect /* decorFrame */,
navigationFrame /* stableFrame */);
mNavigationBar.computeFrame(displayFrames);
- if (isRealLayout) {
+ if (simulatedContentFrame != null) {
+ simulatedContentFrame.set(windowFrames.mContentFrame);
+ } else {
mNavigationBarPosition = navBarPosition;
mNavigationBarController.setContentFrame(windowFrames.mContentFrame);
}
@@ -2372,12 +2390,13 @@ public class DisplayPolicy {
final boolean requestedFullscreen = (fl & FLAG_FULLSCREEN) != 0
|| (requestedSysUiFl & View.SYSTEM_UI_FLAG_FULLSCREEN) != 0
|| (ViewRootImpl.sNewInsetsMode == NEW_INSETS_MODE_FULL
- && !win.getRequestedInsetsState().getSource(ITYPE_STATUS_BAR).isVisible());
+ && !win.getRequestedInsetsState().getSourceOrDefaultVisibility(
+ ITYPE_STATUS_BAR));
final boolean requestedHideNavigation =
(requestedSysUiFl & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) != 0
|| (ViewRootImpl.sNewInsetsMode == NEW_INSETS_MODE_FULL
- && !win.getRequestedInsetsState().getSource(ITYPE_NAVIGATION_BAR)
- .isVisible());
+ && !win.getRequestedInsetsState().getSourceOrDefaultVisibility(
+ ITYPE_NAVIGATION_BAR));
// TYPE_BASE_APPLICATION windows are never considered floating here because they don't get
// cropped / shifted to the displayFrame in WindowState.
@@ -3187,24 +3206,32 @@ public class DisplayPolicy {
return;
}
if (ViewRootImpl.sNewInsetsMode == NEW_INSETS_MODE_FULL) {
- if (swipeTarget == mNavigationBar
- && !getInsetsPolicy().isHidden(ITYPE_NAVIGATION_BAR)) {
- // Don't show status bar when swiping on already visible navigation bar
- return;
- }
final InsetsSourceProvider provider = swipeTarget.getControllableInsetProvider();
final InsetsControlTarget controlTarget = provider != null
? provider.getControlTarget() : null;
- // No transient mode on lockscreen (in notification shade window).
if (controlTarget == null || controlTarget == getNotificationShade()) {
+ // No transient mode on lockscreen (in notification shade window).
return;
}
+
+ if (swipeTarget == mNavigationBar
+ && !getInsetsPolicy().isHidden(ITYPE_NAVIGATION_BAR)) {
+ // Don't show status bar when swiping on already visible navigation bar.
+ // But restore the position of navigation bar if it has been moved by the control
+ // target.
+ controlTarget.showInsets(Type.navigationBars(), false);
+ return;
+ }
+
+ int insetsTypesToShow = Type.systemBars();
+
if (controlTarget.canShowTransient()) {
- mDisplayContent.getInsetsPolicy().showTransient(IntArray.wrap(
+ insetsTypesToShow &= ~mDisplayContent.getInsetsPolicy().showTransient(IntArray.wrap(
new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR}));
- } else {
- controlTarget.showInsets(Type.systemBars(), false);
+ }
+ if (insetsTypesToShow != 0) {
+ controlTarget.showInsets(insetsTypesToShow, false);
}
} else {
boolean sb = mStatusBarController.checkShowTransientBarLw();
@@ -3755,7 +3782,8 @@ public class DisplayPolicy {
&& (behavior == BEHAVIOR_SHOW_BARS_BY_SWIPE
|| behavior == BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE)
&& getInsetsPolicy().isHidden(ITYPE_NAVIGATION_BAR)
- && win != getNotificationShade();
+ && win != getNotificationShade()
+ && !win.isActivityTypeDream();
}
/**
diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java
index 831491dd145e..37ecee8e3db3 100644
--- a/services/core/java/com/android/server/wm/DisplayRotation.java
+++ b/services/core/java/com/android/server/wm/DisplayRotation.java
@@ -430,6 +430,15 @@ public class DisplayRotation {
"Deferring rotation, still finishing previous rotation");
return false;
}
+
+ if (mDisplayContent.mFixedRotationTransitionListener
+ .isTopFixedOrientationRecentsAnimating()) {
+ // During the recents animation, the closing app might still be considered on top.
+ // In order to ignore its requested orientation to avoid a sensor led rotation (e.g
+ // user rotating the device while the recents animation is running), we ignore
+ // rotation update while the animation is running.
+ return false;
+ }
}
if (!mService.mDisplayEnabled) {
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index 8734b5efa45d..0e2611d1ddb9 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -477,12 +477,11 @@ final class InputMonitor {
mService.getRecentsAnimationController();
final boolean shouldApplyRecentsInputConsumer = recentsAnimationController != null
&& recentsAnimationController.shouldApplyInputConsumer(w.mActivityRecord);
- if (inputChannel == null || inputWindowHandle == null || w.mRemoved
- || (w.cantReceiveTouchInput() && !shouldApplyRecentsInputConsumer)) {
+ if (inputWindowHandle == null || w.mRemoved) {
if (w.mWinAnimator.hasSurface()) {
mInputTransaction.setInputWindowInfo(
- w.mWinAnimator.mSurfaceController.getClientViewRootSurface(),
- mInvalidInputWindow);
+ w.mWinAnimator.mSurfaceController.getClientViewRootSurface(),
+ mInvalidInputWindow);
}
// Skip this window because it cannot possibly receive input.
return;
@@ -491,9 +490,23 @@ final class InputMonitor {
final int flags = w.mAttrs.flags;
final int privateFlags = w.mAttrs.privateFlags;
final int type = w.mAttrs.type;
- final boolean hasFocus = w.isFocused();
final boolean isVisible = w.isVisibleLw();
+ // Assign an InputInfo with type to the overlay window which can't receive input event.
+ // This is used to omit Surfaces from occlusion detection.
+ if (inputChannel == null
+ || (w.cantReceiveTouchInput() && !shouldApplyRecentsInputConsumer)) {
+ if (!w.mWinAnimator.hasSurface()) {
+ return;
+ }
+ populateOverlayInputInfo(inputWindowHandle, w.getName(), type, isVisible);
+ mInputTransaction.setInputWindowInfo(
+ w.mWinAnimator.mSurfaceController.getClientViewRootSurface(),
+ inputWindowHandle);
+ return;
+ }
+
+ final boolean hasFocus = w.isFocused();
if (mAddRecentsAnimationInputConsumerHandle && shouldApplyRecentsInputConsumer) {
if (recentsAnimationController.updateInputConsumerForApp(
mRecentsAnimationInputConsumer.mWindowHandle, hasFocus)) {
@@ -555,6 +568,22 @@ final class InputMonitor {
}
}
+ private static void populateOverlayInputInfo(final InputWindowHandle inputWindowHandle,
+ final String name, final int type, final boolean isVisible) {
+ inputWindowHandle.name = name;
+ inputWindowHandle.layoutParamsType = type;
+ inputWindowHandle.dispatchingTimeoutNanos =
+ WindowManagerService.DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
+ inputWindowHandle.visible = isVisible;
+ inputWindowHandle.canReceiveKeys = false;
+ inputWindowHandle.hasFocus = false;
+ inputWindowHandle.ownerPid = myPid();
+ inputWindowHandle.ownerUid = myUid();
+ inputWindowHandle.inputFeatures = INPUT_FEATURE_NO_INPUT_CHANNEL;
+ inputWindowHandle.scaleFactor = 1;
+ inputWindowHandle.layoutParamsFlags = FLAG_NOT_TOUCH_MODAL;
+ }
+
/**
* Helper function to generate an InputInfo with type SECURE_SYSTEM_OVERLAY. This input
* info will not have an input channel or be touchable, but is used to omit Surfaces
@@ -564,16 +593,7 @@ final class InputMonitor {
static void setTrustedOverlayInputInfo(SurfaceControl sc, SurfaceControl.Transaction t,
int displayId, String name) {
InputWindowHandle inputWindowHandle = new InputWindowHandle(null, displayId);
- inputWindowHandle.name = name;
- inputWindowHandle.layoutParamsType = TYPE_SECURE_SYSTEM_OVERLAY;
- inputWindowHandle.dispatchingTimeoutNanos = -1;
- inputWindowHandle.visible = true;
- inputWindowHandle.canReceiveKeys = false;
- inputWindowHandle.hasFocus = false;
- inputWindowHandle.ownerPid = myPid();
- inputWindowHandle.ownerUid = myUid();
- inputWindowHandle.inputFeatures = INPUT_FEATURE_NO_INPUT_CHANNEL;
- inputWindowHandle.scaleFactor = 1;
+ populateOverlayInputInfo(inputWindowHandle, name, TYPE_SECURE_SYSTEM_OVERLAY, true);
t.setInputWindowInfo(sc, inputWindowHandle);
}
}
diff --git a/services/core/java/com/android/server/wm/InsetsPolicy.java b/services/core/java/com/android/server/wm/InsetsPolicy.java
index 035f2015fe91..254356d673e3 100644
--- a/services/core/java/com/android/server/wm/InsetsPolicy.java
+++ b/services/core/java/com/android/server/wm/InsetsPolicy.java
@@ -42,6 +42,7 @@ import android.view.InsetsState.InternalInsetsType;
import android.view.SurfaceControl;
import android.view.SyncRtSurfaceTransactionApplier;
import android.view.ViewRootImpl;
+import android.view.WindowInsets.Type.InsetsType;
import android.view.WindowInsetsAnimation;
import android.view.WindowInsetsAnimation.Bounds;
import android.view.WindowInsetsAnimationControlListener;
@@ -110,15 +111,20 @@ class InsetsPolicy {
abortTransient();
}
mFocusedWin = focusedWin;
- mStateController.onBarControlTargetChanged(getStatusControlTarget(focusedWin),
- getFakeStatusControlTarget(focusedWin),
- getNavControlTarget(focusedWin),
- getFakeNavControlTarget(focusedWin));
+ boolean forceShowsSystemBarsForWindowingMode = forceShowsSystemBarsForWindowingMode();
+ InsetsControlTarget statusControlTarget = getStatusControlTarget(focusedWin,
+ forceShowsSystemBarsForWindowingMode);
+ InsetsControlTarget navControlTarget = getNavControlTarget(focusedWin,
+ forceShowsSystemBarsForWindowingMode);
+ mStateController.onBarControlTargetChanged(statusControlTarget,
+ getFakeControlTarget(focusedWin, statusControlTarget),
+ navControlTarget,
+ getFakeControlTarget(focusedWin, navControlTarget));
if (ViewRootImpl.sNewInsetsMode != ViewRootImpl.NEW_INSETS_MODE_FULL) {
return;
}
- mStatusBar.updateVisibility(getStatusControlTarget(focusedWin), ITYPE_STATUS_BAR);
- mNavBar.updateVisibility(getNavControlTarget(focusedWin), ITYPE_NAVIGATION_BAR);
+ mStatusBar.updateVisibility(statusControlTarget, ITYPE_STATUS_BAR);
+ mNavBar.updateVisibility(navControlTarget, ITYPE_NAVIGATION_BAR);
mPolicy.updateHideNavInputEventReceiver();
}
@@ -127,14 +133,16 @@ class InsetsPolicy {
return provider != null && provider.hasWindow() && !provider.getSource().isVisible();
}
- void showTransient(IntArray types) {
+ @InsetsType int showTransient(IntArray types) {
+ @InsetsType int showingTransientTypes = 0;
boolean changed = false;
for (int i = types.size() - 1; i >= 0; i--) {
final int type = types.get(i);
- if (mShowingTransientTypes.indexOf(type) != -1) {
+ if (!isHidden(type)) {
continue;
}
- if (!isHidden(type)) {
+ showingTransientTypes |= InsetsState.toPublicType(type);
+ if (mShowingTransientTypes.indexOf(type) != -1) {
continue;
}
mShowingTransientTypes.add(type);
@@ -161,6 +169,7 @@ class InsetsPolicy {
}
});
}
+ return showingTransientTypes;
}
void hideTransient() {
@@ -192,18 +201,6 @@ class InsetsPolicy {
state = new InsetsState(state);
state.setSourceVisible(mShowingTransientTypes.get(i), false);
}
- if (mFocusedWin != null && getStatusControlTarget(mFocusedWin) == mDummyControlTarget) {
- if (state == originalState) {
- state = new InsetsState(state);
- }
- state.setSourceVisible(ITYPE_STATUS_BAR, mFocusedWin.getRequestedInsetsState());
- }
- if (mFocusedWin != null && getNavControlTarget(mFocusedWin) == mDummyControlTarget) {
- if (state == originalState) {
- state = new InsetsState(state);
- }
- state.setSourceVisible(ITYPE_NAVIGATION_BAR, mFocusedWin.getRequestedInsetsState());
- }
return state;
}
@@ -245,16 +242,13 @@ class InsetsPolicy {
updateBarControlTarget(mFocusedWin);
}
- private @Nullable InsetsControlTarget getFakeStatusControlTarget(
- @Nullable WindowState focused) {
- return getStatusControlTarget(focused) == mDummyControlTarget ? focused : null;
- }
-
- private @Nullable InsetsControlTarget getFakeNavControlTarget(@Nullable WindowState focused) {
- return getNavControlTarget(focused) == mDummyControlTarget ? focused : null;
+ private @Nullable InsetsControlTarget getFakeControlTarget(@Nullable WindowState focused,
+ InsetsControlTarget realControlTarget) {
+ return realControlTarget == mDummyControlTarget ? focused : null;
}
- private @Nullable InsetsControlTarget getStatusControlTarget(@Nullable WindowState focusedWin) {
+ private @Nullable InsetsControlTarget getStatusControlTarget(@Nullable WindowState focusedWin,
+ boolean forceShowsSystemBarsForWindowingMode) {
if (mShowingTransientTypes.indexOf(ITYPE_STATUS_BAR) != -1) {
return mDummyControlTarget;
}
@@ -262,7 +256,7 @@ class InsetsPolicy {
// Notification shade has control anyways, no reason to force anything.
return focusedWin;
}
- if (forceShowsSystemBarsForWindowingMode()) {
+ if (forceShowsSystemBarsForWindowingMode) {
// Status bar is forcibly shown for the windowing mode which is a steady state.
// We don't want the client to control the status bar, and we will dispatch the real
// visibility of status bar to the client.
@@ -282,7 +276,8 @@ class InsetsPolicy {
return focusedWin;
}
- private @Nullable InsetsControlTarget getNavControlTarget(@Nullable WindowState focusedWin) {
+ private @Nullable InsetsControlTarget getNavControlTarget(@Nullable WindowState focusedWin,
+ boolean forceShowsSystemBarsForWindowingMode) {
if (mShowingTransientTypes.indexOf(ITYPE_NAVIGATION_BAR) != -1) {
return mDummyControlTarget;
}
@@ -290,7 +285,7 @@ class InsetsPolicy {
// Notification shade has control anyways, no reason to force anything.
return focusedWin;
}
- if (forceShowsSystemBarsForWindowingMode()) {
+ if (forceShowsSystemBarsForWindowingMode) {
// Navigation bar is forcibly shown for the windowing mode which is a steady state.
// We don't want the client to control the navigation bar, and we will dispatch the real
// visibility of navigation bar to the client.
@@ -373,7 +368,7 @@ class InsetsPolicy {
final WindowState controllingWin =
controlTarget instanceof WindowState ? (WindowState) controlTarget : null;
setVisible(controllingWin == null
- || controllingWin.getRequestedInsetsState().getSource(type).isVisible());
+ || controllingWin.getRequestedInsetsState().getSourceOrDefaultVisibility(type));
}
private void setVisible(boolean visible) {
@@ -392,7 +387,10 @@ class InsetsPolicy {
InsetsPolicyAnimationControlCallbacks mControlCallbacks;
InsetsPolicyAnimationControlListener(boolean show, Runnable finishCallback, int types) {
- super(show, false /* hasCallbacks */, types);
+
+ super(show, false /* hasCallbacks */, types, false /* disable */,
+ (int) (mDisplayContent.getDisplayMetrics().density * FLOATING_IME_BOTTOM_INSET
+ + 0.5f));
mFinishCallback = finishCallback;
mControlCallbacks = new InsetsPolicyAnimationControlCallbacks(this);
}
@@ -484,6 +482,12 @@ class InsetsPolicy {
WindowInsetsAnimation animation,
Bounds bounds) {
}
+
+ @Override
+ public void reportPerceptible(int types, boolean perceptible) {
+ // No-op for now - only client windows report perceptibility for now, with policy
+ // controllers assumed to always be perceptible.
+ }
}
}
}
diff --git a/services/core/java/com/android/server/wm/InsetsStateController.java b/services/core/java/com/android/server/wm/InsetsStateController.java
index bf9a78489167..63083faaddb1 100644
--- a/services/core/java/com/android/server/wm/InsetsStateController.java
+++ b/services/core/java/com/android/server/wm/InsetsStateController.java
@@ -246,7 +246,7 @@ class InsetsStateController {
// (e.g., z-order) have changed. They can affect the insets states that we dispatch to
// the clients.
for (int i = winInsetsChanged.size() - 1; i >= 0; i--) {
- winInsetsChanged.get(i).notifyInsetsChanged();
+ mDispatchInsetsChanged.accept(winInsetsChanged.get(i));
}
}
winInsetsChanged.clear();
@@ -254,8 +254,9 @@ class InsetsStateController {
void onInsetsModified(InsetsControlTarget windowState, InsetsState state) {
boolean changed = false;
- for (int i = state.getSourcesCount() - 1; i >= 0; i--) {
- final InsetsSource source = state.sourceAt(i);
+ for (int i = 0; i < InsetsState.SIZE; i++) {
+ final InsetsSource source = state.peekSource(i);
+ if (source == null) continue;
final InsetsSourceProvider provider = mProviders.get(source.getType());
if (provider == null) {
continue;
diff --git a/services/core/java/com/android/server/wm/LockTaskController.java b/services/core/java/com/android/server/wm/LockTaskController.java
index 4a0da75cdad8..892ee717e21f 100644
--- a/services/core/java/com/android/server/wm/LockTaskController.java
+++ b/services/core/java/com/android/server/wm/LockTaskController.java
@@ -175,7 +175,7 @@ public class LockTaskController {
* {@link ActivityManager#LOCK_TASK_MODE_NONE}, {@link ActivityManager#LOCK_TASK_MODE_LOCKED},
* {@link ActivityManager#LOCK_TASK_MODE_PINNED}
*/
- private int mLockTaskModeState = LOCK_TASK_MODE_NONE;
+ private volatile int mLockTaskModeState = LOCK_TASK_MODE_NONE;
/**
* This is ActivityStackSupervisor's Handler.
@@ -500,24 +500,29 @@ public class LockTaskController {
// This method should only be called on the handler thread
private void performStopLockTask(int userId) {
+ // Update the internal mLockTaskModeState early to avoid the scenario that SysUI queries
+ // mLockTaskModeState (from setStatusBarState) and gets staled state.
+ // TODO: revisit this approach.
+ // The race condition raised above can be addressed by moving this function out of handler
+ // thread, which makes it guarded by ATMS#mGlobalLock as ATMS#getLockTaskModeState.
+ final int oldLockTaskModeState = mLockTaskModeState;
+ mLockTaskModeState = LOCK_TASK_MODE_NONE;
// When lock task ends, we enable the status bars.
try {
- setStatusBarState(LOCK_TASK_MODE_NONE, userId);
- setKeyguardState(LOCK_TASK_MODE_NONE, userId);
- if (mLockTaskModeState == LOCK_TASK_MODE_PINNED) {
+ setStatusBarState(mLockTaskModeState, userId);
+ setKeyguardState(mLockTaskModeState, userId);
+ if (oldLockTaskModeState == LOCK_TASK_MODE_PINNED) {
lockKeyguardIfNeeded();
}
if (getDevicePolicyManager() != null) {
getDevicePolicyManager().notifyLockTaskModeChanged(false, null, userId);
}
- if (mLockTaskModeState == LOCK_TASK_MODE_PINNED) {
+ if (oldLockTaskModeState == LOCK_TASK_MODE_PINNED) {
getStatusBarService().showPinningEnterExitToast(false /* entering */);
}
- mWindowManager.onLockTaskStateChanged(LOCK_TASK_MODE_NONE);
+ mWindowManager.onLockTaskStateChanged(mLockTaskModeState);
} catch (RemoteException ex) {
throw new RuntimeException(ex);
- } finally {
- mLockTaskModeState = LOCK_TASK_MODE_NONE;
}
}
diff --git a/services/core/java/com/android/server/wm/RecentTasks.java b/services/core/java/com/android/server/wm/RecentTasks.java
index 24bb7c8d5560..1b58fc1d2d3e 100644
--- a/services/core/java/com/android/server/wm/RecentTasks.java
+++ b/services/core/java/com/android/server/wm/RecentTasks.java
@@ -961,7 +961,7 @@ class RecentTasks {
continue;
}
- res.add(createRecentTaskInfo(task));
+ res.add(createRecentTaskInfo(task, true /* stripExtras */));
}
return res;
}
@@ -1832,9 +1832,9 @@ class RecentTasks {
/**
* Creates a new RecentTaskInfo from a Task.
*/
- ActivityManager.RecentTaskInfo createRecentTaskInfo(Task tr) {
+ ActivityManager.RecentTaskInfo createRecentTaskInfo(Task tr, boolean stripExtras) {
ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
- tr.fillTaskInfo(rti);
+ tr.fillTaskInfo(rti, stripExtras);
// Fill in some deprecated values
rti.id = rti.isRunning ? rti.taskId : INVALID_TASK_ID;
rti.persistentId = rti.taskId;
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 583663c5455f..2d30b737b274 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -40,6 +40,7 @@ import static android.view.WindowManager.TRANSIT_CRASHING_ACTIVITY_CLOSE;
import static android.view.WindowManager.TRANSIT_NONE;
import static android.view.WindowManager.TRANSIT_SHOW_SINGLE_TASK_DISPLAY;
+import static com.android.server.policy.PhoneWindowManager.SYSTEM_DIALOG_REASON_ASSIST;
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
import static com.android.server.wm.ActivityStack.ActivityState.FINISHING;
@@ -662,10 +663,10 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
}
}
- void setSecureSurfaceState(int userId, boolean disabled) {
+ void setSecureSurfaceState(int userId) {
forAllWindows((w) -> {
if (w.mHasSurface && userId == w.mShowUserId) {
- w.mWinAnimator.setSecureLocked(disabled);
+ w.mWinAnimator.setSecureLocked(w.isSecureLocked());
}
}, true /* traverseTopToBottom */);
}
@@ -3121,14 +3122,25 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
return hasVisibleActivities;
}
- void closeSystemDialogs() {
+ void closeSystemDialogActivities(String reason) {
forAllActivities((r) -> {
- if ((r.info.flags & ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
- r.finishIfPossible("close-sys", true /* oomAdj */);
+ if ((r.info.flags & ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0
+ || shouldCloseAssistant(r, reason)) {
+ r.finishIfPossible(reason, true /* oomAdj */);
}
});
}
+ private boolean shouldCloseAssistant(ActivityRecord r, String reason) {
+ if (!r.isActivityTypeAssistant()) return false;
+ if (reason == SYSTEM_DIALOG_REASON_ASSIST) return false;
+ // When the assistant is configured to be on top of the dream, it will have higher z-order
+ // than other activities. If it is also opaque, it will prevent other activities from
+ // starting. We want to close the assistant on closeSystemDialogs to allow other activities
+ // to start, e.g. on home button press.
+ return mWmService.mAssistantOnTopOfDream;
+ }
+
FinishDisabledPackageActivitiesHelper mFinishDisabledPackageActivitiesHelper =
new FinishDisabledPackageActivitiesHelper();
class FinishDisabledPackageActivitiesHelper {
diff --git a/services/core/java/com/android/server/wm/StatusBarController.java b/services/core/java/com/android/server/wm/StatusBarController.java
index cac992a67541..3564e0bce5f5 100644
--- a/services/core/java/com/android/server/wm/StatusBarController.java
+++ b/services/core/java/com/android/server/wm/StatusBarController.java
@@ -17,6 +17,7 @@
package com.android.server.wm;
import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
+import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
import static com.android.server.wm.WindowManagerInternal.AppTransitionListener;
@@ -90,6 +91,7 @@ public class StatusBarController extends BarController {
View.STATUS_BAR_UNHIDE,
View.STATUS_BAR_TRANSLUCENT,
StatusBarManager.WINDOW_STATUS_BAR,
+ TYPE_STATUS_BAR,
FLAG_TRANSLUCENT_STATUS,
View.STATUS_BAR_TRANSPARENT);
}
diff --git a/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java b/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java
index 5633b6be87b9..837f1b523b68 100644
--- a/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java
+++ b/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java
@@ -239,9 +239,6 @@ class SurfaceAnimationRunner {
}
private void applyTransformation(RunningAnimation a, Transaction t, long currentPlayTime) {
- if (a.mAnimSpec.needsEarlyWakeup()) {
- t.setEarlyWakeup();
- }
a.mAnimSpec.apply(t, a.mLeash, currentPlayTime);
}
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 56ad9643e619..a7b120942163 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -939,14 +939,15 @@ class Task extends WindowContainer<WindowContainer> {
/** Sets the original intent, _without_ updating the calling uid or package. */
private void setIntent(Intent _intent, ActivityInfo info) {
+ final boolean isLeaf = isLeafTask();
if (intent == null) {
mNeverRelinquishIdentity =
(info.flags & FLAG_RELINQUISH_TASK_IDENTITY) == 0;
- } else if (mNeverRelinquishIdentity) {
+ } else if (mNeverRelinquishIdentity && isLeaf) {
return;
}
- affinity = isLeafTask() ? info.taskAffinity : null;
+ affinity = isLeaf ? info.taskAffinity : null;
if (intent == null) {
// If this task already has an intent associated with it, don't set the root
// affinity -- we don't want it changing after initially set, but the initially
@@ -2638,7 +2639,7 @@ class Task extends WindowContainer<WindowContainer> {
*/
ActivityStack adjustFocusToNextFocusableTask(String reason) {
return adjustFocusToNextFocusableTask(reason, false /* allowFocusSelf */,
- true /* moveParentsToTop */);
+ true /* moveDisplayToTop */);
}
/** Return the next focusable task by looking from the siblings and parent tasks */
@@ -2661,11 +2662,11 @@ class Task extends WindowContainer<WindowContainer> {
* Find next proper focusable task and make it focused.
* @param reason The reason of making the adjustment.
* @param allowFocusSelf Is the focus allowed to remain on the same task.
- * @param moveParentsToTop Whether to move parents to top while making the task focused.
+ * @param moveDisplayToTop Whether to move display to top while making the task focused.
* @return The root task that now got the focus, {@code null} if none found.
*/
ActivityStack adjustFocusToNextFocusableTask(String reason, boolean allowFocusSelf,
- boolean moveParentsToTop) {
+ boolean moveDisplayToTop) {
ActivityStack focusableTask = (ActivityStack) getNextFocusableTask(allowFocusSelf);
if (focusableTask == null) {
focusableTask = mRootWindowContainer.getNextFocusableStack((ActivityStack) this,
@@ -2676,10 +2677,17 @@ class Task extends WindowContainer<WindowContainer> {
}
final ActivityStack rootTask = (ActivityStack) focusableTask.getRootTask();
- if (!moveParentsToTop) {
- // Only move the next stack to top in its task container.
+ if (!moveDisplayToTop) {
+ // There may be multiple task layers above this task, so when relocating the task to the
+ // top, we should move this task and each of its parent task that below display area to
+ // the top of each layer.
WindowContainer parent = focusableTask.getParent();
- parent.positionChildAt(POSITION_TOP, focusableTask, false /* includingParents */);
+ WindowContainer next = focusableTask;
+ do {
+ parent.positionChildAt(POSITION_TOP, next, false /* includingParents */);
+ next = parent;
+ parent = next.getParent();
+ } while (next.asTask() != null && parent != null);
return rootTask;
}
@@ -2917,6 +2925,19 @@ class Task extends WindowContainer<WindowContainer> {
}
boolean cropWindowsToStackBounds() {
+ // Don't crop HOME/RECENTS windows to stack bounds. This is because in split-screen
+ // they extend past their stack and sysui uses the stack surface to control cropping.
+ // TODO(b/158242495): get rid of this when drag/drop can use surface bounds.
+ if (isActivityTypeHome() || isActivityTypeRecents()) {
+ // Make sure this is the top-most non-organizer root task (if not top-most, it means
+ // another translucent task could be above this, so this needs to stay cropped.
+ final Task rootTask = getRootTask();
+ final Task topNonOrgTask =
+ rootTask.mCreatedByOrganizer ? rootTask.getTopMostTask() : rootTask;
+ if (this == topNonOrgTask || isDescendantOf(topNonOrgTask)) {
+ return false;
+ }
+ }
return isResizeable();
}
@@ -3486,7 +3507,7 @@ class Task extends WindowContainer<WindowContainer> {
updateShadowsRadius(isFocused(), getSyncTransaction());
- if (mDimmer.updateDims(getSyncTransaction(), mTmpDimBoundsRect)) {
+ if (mDimmer.updateDims(getPendingTransaction(), mTmpDimBoundsRect)) {
scheduleAnimation();
}
}
@@ -3530,11 +3551,19 @@ class Task extends WindowContainer<WindowContainer> {
}
}
+
/**
* Fills in a {@link TaskInfo} with information from this task. Note that the base intent in the
* task info will not include any extras or clip data.
*/
void fillTaskInfo(TaskInfo info) {
+ fillTaskInfo(info, true /* stripExtras */);
+ }
+
+ /**
+ * Fills in a {@link TaskInfo} with information from this task.
+ */
+ void fillTaskInfo(TaskInfo info, boolean stripExtras) {
getNumRunningActivities(mReuseActivitiesReport);
info.userId = mUserId;
info.stackId = getRootTaskId();
@@ -3545,7 +3574,9 @@ class Task extends WindowContainer<WindowContainer> {
// Make a copy of base intent because this is like a snapshot info.
// Besides, {@link RecentTasks#getRecentTasksImpl} may modify it.
final int baseIntentFlags = baseIntent == null ? 0 : baseIntent.getFlags();
- info.baseIntent = baseIntent == null ? new Intent() : baseIntent.cloneFilter();
+ info.baseIntent = baseIntent == null
+ ? new Intent()
+ : stripExtras ? baseIntent.cloneFilter() : new Intent(baseIntent);
info.baseIntent.setFlags(baseIntentFlags);
info.baseActivity = mReuseActivitiesReport.base != null
? mReuseActivitiesReport.base.intent.getComponent()
@@ -3567,6 +3598,7 @@ class Task extends WindowContainer<WindowContainer> {
final Task top = getTopMostTask();
info.resizeMode = top != null ? top.mResizeMode : mResizeMode;
info.topActivityType = top.getActivityType();
+ info.isResizeable = isResizeable();
ActivityRecord rootActivity = top.getRootActivity();
if (rootActivity == null || rootActivity.pictureInPictureArgs.empty()) {
@@ -3664,20 +3696,6 @@ class Task extends WindowContainer<WindowContainer> {
final int otherWindowingMode = other.getWindowingMode();
if (otherWindowingMode == WINDOWING_MODE_FULLSCREEN) {
- // In this case the home stack isn't resizeable even though we are in split-screen
- // mode. We still want the primary splitscreen stack to be visible as there will be
- // a slight hint of it in the status bar area above the non-resizeable home
- // activity. In addition, if the fullscreen assistant is over primary splitscreen
- // stack, the stack should still be visible in the background as long as the recents
- // animation is running.
- final int activityType = other.getActivityType();
- if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
- if (activityType == ACTIVITY_TYPE_HOME
- || (activityType == ACTIVITY_TYPE_ASSISTANT
- && mWmService.getRecentsAnimationController() != null)) {
- break;
- }
- }
if (other.isTranslucent(starting)) {
// Can be visible behind a translucent fullscreen stack.
gotTranslucentFullscreen = true;
diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java
index 102c2a6364f4..7b690383f5f9 100644
--- a/services/core/java/com/android/server/wm/TaskDisplayArea.java
+++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java
@@ -17,6 +17,7 @@
package com.android.server.wm;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
@@ -99,6 +100,9 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> {
private ActivityStack mRootPinnedTask;
private ActivityStack mRootSplitScreenPrimaryTask;
+ // TODO(b/159029784): Remove when getStack() behavior is cleaned-up
+ private ActivityStack mRootRecentsTask;
+
private final ArrayList<ActivityStack> mTmpAlwaysOnTopStacks = new ArrayList<>();
private final ArrayList<ActivityStack> mTmpNormalStacks = new ArrayList<>();
private final ArrayList<ActivityStack> mTmpHomeStacks = new ArrayList<>();
@@ -122,10 +126,6 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> {
private final RootWindowContainer.FindTaskResult
mTmpFindTaskResult = new RootWindowContainer.FindTaskResult();
- // Indicates whether the Assistant should show on top of the Dream (respectively, above
- // everything else on screen). Otherwise, it will be put under always-on-top stacks.
- private final boolean mAssistantOnTopOfDream;
-
/**
* If this is the same as {@link #getFocusedStack} then the activity on the top of the focused
* stack has been resumed. If stacks are changing position this will hold the old stack until
@@ -151,9 +151,6 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> {
mDisplayContent = displayContent;
mRootWindowContainer = service.mRoot;
mAtmService = service.mAtmService;
-
- mAssistantOnTopOfDream = mWmService.mContext.getResources().getBoolean(
- com.android.internal.R.bool.config_assistantOnTopOfDream);
}
/**
@@ -163,6 +160,8 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> {
ActivityStack getStack(int windowingMode, int activityType) {
if (activityType == ACTIVITY_TYPE_HOME) {
return mRootHomeTask;
+ } else if (activityType == ACTIVITY_TYPE_RECENTS) {
+ return mRootRecentsTask;
}
if (windowingMode == WINDOWING_MODE_PINNED) {
return mRootPinnedTask;
@@ -199,6 +198,10 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> {
return mRootHomeTask;
}
+ @Nullable ActivityStack getRootRecentsTask() {
+ return mRootRecentsTask;
+ }
+
ActivityStack getRootPinnedTask() {
return mRootPinnedTask;
}
@@ -207,6 +210,15 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> {
return mRootSplitScreenPrimaryTask;
}
+ ActivityStack getRootSplitScreenSecondaryTask() {
+ for (int i = mChildren.size() - 1; i >= 0; --i) {
+ if (mChildren.get(i).inSplitScreenSecondaryWindowingMode()) {
+ return mChildren.get(i);
+ }
+ }
+ return null;
+ }
+
ArrayList<Task> getVisibleTasks() {
final ArrayList<Task> visibleTasks = new ArrayList<>();
forAllTasks(task -> {
@@ -237,6 +249,16 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> {
} else {
mRootHomeTask = stack;
}
+ } else if (stack.isActivityTypeRecents()) {
+ if (mRootRecentsTask != null) {
+ if (!stack.isDescendantOf(mRootRecentsTask)) {
+ throw new IllegalArgumentException("addStackReferenceIfNeeded: recents stack="
+ + mRootRecentsTask + " already exist on display=" + this
+ + " stack=" + stack);
+ }
+ } else {
+ mRootRecentsTask = stack;
+ }
}
if (!stack.isRootTask()) {
@@ -264,6 +286,8 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> {
void removeStackReferenceIfNeeded(ActivityStack stack) {
if (stack == mRootHomeTask) {
mRootHomeTask = null;
+ } else if (stack == mRootRecentsTask) {
+ mRootRecentsTask = null;
} else if (stack == mRootPinnedTask) {
mRootPinnedTask = null;
} else if (stack == mRootSplitScreenPrimaryTask) {
@@ -299,8 +323,17 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> {
@Override
void positionChildAt(int position, ActivityStack child, boolean includingParents) {
- final boolean moveToTop = (position == POSITION_TOP || position == getChildCount());
+ final boolean moveToTop = position >= getChildCount() - 1;
final boolean moveToBottom = (position == POSITION_BOTTOM || position == 0);
+
+ // Reset mPreferredTopFocusableStack before positioning to top or {@link
+ // ActivityStackSupervisor#updateTopResumedActivityIfNeeded()} won't update the top
+ // resumed activity.
+ final boolean wasContained = mChildren.contains(child);
+ if (moveToTop && wasContained && child.isFocusable()) {
+ mPreferredTopFocusableStack = null;
+ }
+
if (child.getWindowConfiguration().isAlwaysOnTop() && !moveToTop) {
// This stack is always-on-top, override the default behavior.
Slog.w(TAG_WM, "Ignoring move of always-on-top stack=" + this + " to bottom");
@@ -313,7 +346,7 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> {
}
// We don't allow untrusted display to top when task stack moves to top,
// until user tapping this display to change display position as top intentionally.
- if (mDisplayContent.isUntrustedVirtualDisplay() && !getParent().isOnTop()) {
+ if (!mDisplayContent.isTrusted() && !getParent().isOnTop()) {
includingParents = false;
}
final int targetPosition = findPositionForStack(position, child, false /* adding */);
@@ -330,6 +363,17 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> {
child.updateTaskMovement(moveToTop);
mDisplayContent.setLayoutNeeded();
+
+ // The insert position may be adjusted to non-top when there is always-on-top stack. Since
+ // the original position is preferred to be top, the stack should have higher priority when
+ // we are looking for top focusable stack. The condition {@code wasContained} restricts the
+ // preferred stack is set only when moving an existing stack to top instead of adding a new
+ // stack that may be too early (e.g. in the middle of launching or reparenting).
+ if (moveToTop && child.isFocusableAndVisible()) {
+ mPreferredTopFocusableStack = child;
+ } else if (mPreferredTopFocusableStack == child) {
+ mPreferredTopFocusableStack = null;
+ }
}
/**
@@ -341,7 +385,7 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> {
* @return the priority of the stack
*/
private int getPriority(ActivityStack stack) {
- if (mAssistantOnTopOfDream && stack.isActivityTypeAssistant()) return 4;
+ if (mWmService.mAssistantOnTopOfDream && stack.isActivityTypeAssistant()) return 4;
if (stack.isActivityTypeDream()) return 3;
if (stack.inPinnedWindowingMode()) return 2;
if (stack.isAlwaysOnTop()) return 1;
@@ -520,14 +564,16 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> {
// Apps and their containers are not allowed to specify an orientation while using
// root tasks...except for the home stack if it is not resizable and currently
// visible (top of) its root task.
- if (mRootHomeTask != null && mRootHomeTask.isVisible()) {
- final Task topMost = mRootHomeTask.getTopMostTask();
- final boolean resizable = topMost != null && topMost.isResizeable();
- if (!(resizable && mRootHomeTask.matchParentBounds())) {
- final int orientation = mRootHomeTask.getOrientation();
- if (orientation != SCREEN_ORIENTATION_UNSET) {
- return orientation;
- }
+ if (mRootHomeTask != null && mRootHomeTask.isVisible()
+ && !mRootHomeTask.isResizeable()) {
+ // Manually nest one-level because because getOrientation() checks fillsParent()
+ // which checks that requestedOverrideBounds() is empty. However, in this case,
+ // it is not empty because it's been overridden to maintain the fullscreen size
+ // within a smaller split-root.
+ final Task topHomeTask = mRootHomeTask.getTopMostTask();
+ final int orientation = topHomeTask.getOrientation();
+ if (orientation != SCREEN_ORIENTATION_UNSET) {
+ return orientation;
}
}
return SCREEN_ORIENTATION_UNSPECIFIED;
@@ -727,29 +773,10 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> {
"positionStackAt: Can only have one task on display=" + this);
}
- final boolean movingToTop = wasContained && position >= getStackCount() - 1;
- // Reset mPreferredTopFocusableStack before positioning to top or {@link
- // ActivityStackSupervisor#updateTopResumedActivityIfNeeded()} won't update the top
- // resumed activity.
- if (movingToTop && stack.isFocusable()) {
- mPreferredTopFocusableStack = null;
- }
-
// Since positionChildAt() is called during the creation process of pinned stacks,
// ActivityStack#getStack() can be null.
positionStackAt(position, stack, includingParents);
- // The insert position may be adjusted to non-top when there is always-on-top stack. Since
- // the original position is preferred to be top, the stack should have higher priority when
- // we are looking for top focusable stack. The condition {@code wasContained} restricts the
- // preferred stack is set only when moving an existing stack to top instead of adding a new
- // stack that may be too early (e.g. in the middle of launching or reparenting).
- if (movingToTop && stack.isFocusableAndVisible()) {
- mPreferredTopFocusableStack = stack;
- } else if (mPreferredTopFocusableStack == stack) {
- mPreferredTopFocusableStack = null;
- }
-
if (updateLastFocusedStackReason != null) {
final ActivityStack currentFocusedStack = getFocusedStack();
if (currentFocusedStack != prevFocusedStack) {
@@ -1497,8 +1524,7 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> {
@Nullable
ActivityStack getOrCreateRootHomeTask(boolean onTop) {
ActivityStack homeTask = getRootHomeTask();
- if (homeTask == null && mDisplayContent.supportsSystemDecorations()
- && !mDisplayContent.isUntrustedVirtualDisplay()) {
+ if (homeTask == null && mDisplayContent.supportsSystemDecorations()) {
homeTask = createStack(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_HOME, onTop);
}
return homeTask;
@@ -1741,21 +1767,23 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> {
// reparenting stack finished.
// Keep the order from bottom to top.
int numStacks = getStackCount();
+
+ final boolean splitScreenActivated = toDisplayArea.isSplitScreenModeActivated();
+ final ActivityStack rootStack = splitScreenActivated ? toDisplayArea
+ .getTopStackInWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY) : null;
for (int stackNdx = 0; stackNdx < numStacks; stackNdx++) {
final ActivityStack stack = getStackAt(stackNdx);
// Always finish non-standard type stacks.
if (destroyContentOnRemoval || !stack.isActivityTypeStandardOrUndefined()) {
stack.finishAllActivitiesImmediately();
} else {
- // If default display is in split-window mode, set windowing mode of the
- // stack to split-screen secondary. Otherwise, set the windowing mode to
- // undefined by default to let stack inherited the windowing mode from the
- // new display.
- final int windowingMode = toDisplayArea.isSplitScreenModeActivated()
- ? WINDOWING_MODE_SPLIT_SCREEN_SECONDARY
- : WINDOWING_MODE_UNDEFINED;
- stack.reparent(toDisplayArea, true /* onTop */);
- stack.setWindowingMode(windowingMode);
+ // Reparent the stack to the root task of secondary-split-screen or display area.
+ stack.reparent(stack.supportsSplitScreenWindowingMode() && rootStack != null
+ ? rootStack : toDisplayArea, POSITION_TOP);
+
+ // Set the windowing mode to undefined by default to let the stack inherited the
+ // windowing mode.
+ stack.setWindowingMode(WINDOWING_MODE_UNDEFINED);
lastReparentedStack = stack;
}
// Stacks may be removed from this display. Ensure each stack will be processed
@@ -1763,6 +1791,17 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> {
stackNdx -= numStacks - getStackCount();
numStacks = getStackCount();
}
+ if (lastReparentedStack != null && splitScreenActivated) {
+ if (!lastReparentedStack.supportsSplitScreenWindowingMode()) {
+ mAtmService.getTaskChangeNotificationController()
+ .notifyActivityDismissingDockedStack();
+ toDisplayArea.onSplitScreenModeDismissed(lastReparentedStack);
+ } else if (rootStack != null) {
+ // update focus
+ rootStack.moveToFront("display-removed");
+ }
+ }
+
mRemoved = true;
return lastReparentedStack;
diff --git a/services/core/java/com/android/server/wm/TaskOrganizerController.java b/services/core/java/com/android/server/wm/TaskOrganizerController.java
index 1da1d116b938..574f37b87443 100644
--- a/services/core/java/com/android/server/wm/TaskOrganizerController.java
+++ b/services/core/java/com/android/server/wm/TaskOrganizerController.java
@@ -455,7 +455,7 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub {
task.fillTaskInfo(mTmpTaskInfo);
boolean changed = lastInfo == null
|| mTmpTaskInfo.topActivityType != lastInfo.topActivityType
- || mTmpTaskInfo.isResizable() != lastInfo.isResizable()
+ || mTmpTaskInfo.isResizeable != lastInfo.isResizeable
|| mTmpTaskInfo.pictureInPictureParams != lastInfo.pictureInPictureParams
|| !TaskDescription.equals(mTmpTaskInfo.taskDescription, lastInfo.taskDescription);
if (!changed) {
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java
index 1a2672bd0132..51cf858715b4 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotController.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java
@@ -28,6 +28,7 @@ import android.app.ActivityManager.TaskSnapshot;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.GraphicBuffer;
+import android.graphics.Insets;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.RecordingCanvas;
@@ -37,8 +38,11 @@ import android.os.Environment;
import android.os.Handler;
import android.util.ArraySet;
import android.util.Slog;
+import android.view.InsetsSource;
+import android.view.InsetsState;
import android.view.SurfaceControl;
import android.view.ThreadedRenderer;
+import android.view.WindowInsets;
import android.view.WindowManager.LayoutParams;
import com.android.internal.annotations.VisibleForTesting;
@@ -475,9 +479,12 @@ class TaskSnapshotController {
final int color = ColorUtils.setAlphaComponent(
task.getTaskDescription().getBackgroundColor(), 255);
final LayoutParams attrs = mainWindow.getAttrs();
+ final InsetsPolicy insetsPolicy = mainWindow.getDisplayContent().getInsetsPolicy();
+ final InsetsState insetsState = insetsPolicy.getInsetsForDispatch(mainWindow);
+ final Rect systemBarInsets = getSystemBarInsets(mainWindow.getFrameLw(), insetsState);
final SystemBarBackgroundPainter decorPainter = new SystemBarBackgroundPainter(attrs.flags,
attrs.privateFlags, attrs.systemUiVisibility, task.getTaskDescription(),
- mHighResTaskSnapshotScale, mainWindow.getRequestedInsetsState());
+ mHighResTaskSnapshotScale, insetsState);
final int taskWidth = task.getBounds().width();
final int taskHeight = task.getBounds().height();
final int width = (int) (taskWidth * mHighResTaskSnapshotScale);
@@ -488,7 +495,7 @@ class TaskSnapshotController {
node.setClipToBounds(false);
final RecordingCanvas c = node.start(width, height);
c.drawColor(color);
- decorPainter.setInsets(mainWindow.getContentInsets(), mainWindow.getStableInsets());
+ decorPainter.setInsets(systemBarInsets);
decorPainter.drawDecors(c, null /* statusBarExcludeFrame */);
node.end(c);
final Bitmap hwBitmap = ThreadedRenderer.createHardwareBitmap(node, width, height);
@@ -593,6 +600,13 @@ class TaskSnapshotController {
return 0;
}
+ static Rect getSystemBarInsets(Rect frame, InsetsState state) {
+ return state.calculateInsets(frame, null /* ignoringVisibilityState */,
+ false /* isScreenRound */, false /* alwaysConsumeSystemBars */,
+ null /* displayCutout */, 0 /* legacySoftInputMode */, 0 /* legacySystemUiFlags */,
+ null /* typeSideMap */).getInsets(WindowInsets.Type.systemBars()).toRect();
+ }
+
void dump(PrintWriter pw, String prefix) {
pw.println(prefix + "mHighResTaskSnapshotScale=" + mHighResTaskSnapshotScale);
mCache.dump(pw, prefix);
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
index e26f1e1fe06f..f1f576220a9a 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
@@ -39,10 +39,9 @@ import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
import static com.android.internal.policy.DecorView.NAVIGATION_BAR_COLOR_VIEW_ATTRIBUTES;
import static com.android.internal.policy.DecorView.STATUS_BAR_COLOR_VIEW_ATTRIBUTES;
-import static com.android.internal.policy.DecorView.getColorViewLeftInset;
-import static com.android.internal.policy.DecorView.getColorViewTopInset;
import static com.android.internal.policy.DecorView.getNavigationBarRect;
import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_STARTING_WINDOW;
+import static com.android.server.wm.TaskSnapshotController.getSystemBarInsets;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
@@ -131,9 +130,8 @@ class TaskSnapshotSurface implements StartingSurface {
private final IWindowSession mSession;
private final WindowManagerService mService;
private final Rect mTaskBounds;
- private final Rect mStableInsets = new Rect();
- private final Rect mContentInsets = new Rect();
private final Rect mFrame = new Rect();
+ private final Rect mSystemBarInsets = new Rect();
private TaskSnapshot mSnapshot;
private final RectF mTmpSnapshotSize = new RectF();
private final RectF mTmpDstFrame = new RectF();
@@ -174,6 +172,7 @@ class TaskSnapshotSurface implements StartingSurface {
final int windowFlags;
final int windowPrivateFlags;
final int currentOrientation;
+ final InsetsState insetsState;
synchronized (service.mGlobalLock) {
final WindowState mainWindow = activity.findMainWindow();
final Task task = activity.getTask();
@@ -241,6 +240,10 @@ class TaskSnapshotSurface implements StartingSurface {
taskBounds = new Rect();
task.getBounds(taskBounds);
currentOrientation = topFullscreenOpaqueWindow.getConfiguration().orientation;
+
+ final InsetsPolicy insetsPolicy = topFullscreenOpaqueWindow.getDisplayContent()
+ .getInsetsPolicy();
+ insetsState = insetsPolicy.getInsetsForDispatch(topFullscreenOpaqueWindow);
}
try {
final int res = session.addToDisplay(window, window.mSeq, layoutParams,
@@ -255,8 +258,7 @@ class TaskSnapshotSurface implements StartingSurface {
}
final TaskSnapshotSurface snapshotSurface = new TaskSnapshotSurface(service, window,
surfaceControl, snapshot, layoutParams.getTitle(), taskDescription, sysUiVis,
- windowFlags, windowPrivateFlags, taskBounds,
- currentOrientation, topFullscreenOpaqueWindow.getRequestedInsetsState());
+ windowFlags, windowPrivateFlags, taskBounds, currentOrientation, insetsState);
window.setOuter(snapshotSurface);
try {
session.relayout(window, window.mSeq, layoutParams, -1, -1, View.VISIBLE, 0, -1,
@@ -266,7 +268,9 @@ class TaskSnapshotSurface implements StartingSurface {
} catch (RemoteException e) {
// Local call.
}
- snapshotSurface.setFrames(tmpFrame, tmpContentInsets, tmpStableInsets);
+
+ final Rect systemBarInsets = getSystemBarInsets(tmpFrame, insetsState);
+ snapshotSurface.setFrames(tmpFrame, systemBarInsets);
snapshotSurface.drawSnapshot();
return snapshotSurface;
}
@@ -315,13 +319,12 @@ class TaskSnapshotSurface implements StartingSurface {
}
@VisibleForTesting
- void setFrames(Rect frame, Rect contentInsets, Rect stableInsets) {
+ void setFrames(Rect frame, Rect systemBarInsets) {
mFrame.set(frame);
- mContentInsets.set(contentInsets);
- mStableInsets.set(stableInsets);
+ mSystemBarInsets.set(systemBarInsets);
mSizeMismatch = (mFrame.width() != mSnapshot.getSnapshot().getWidth()
|| mFrame.height() != mSnapshot.getSnapshot().getHeight());
- mSystemBarBackgroundPainter.setInsets(contentInsets, stableInsets);
+ mSystemBarBackgroundPainter.setInsets(systemBarInsets);
}
private void drawSnapshot() {
@@ -453,9 +456,7 @@ class TaskSnapshotSurface implements StartingSurface {
);
// However, we also need to make space for the navigation bar on the left side.
- final int colorViewLeftInset = getColorViewLeftInset(mStableInsets.left,
- mContentInsets.left);
- frame.offset(colorViewLeftInset, 0);
+ frame.offset(mSystemBarInsets.left, 0);
return frame;
}
@@ -540,8 +541,6 @@ class TaskSnapshotSurface implements StartingSurface {
*/
static class SystemBarBackgroundPainter {
- private final Rect mContentInsets = new Rect();
- private final Rect mStableInsets = new Rect();
private final Paint mStatusBarPaint = new Paint();
private final Paint mNavigationBarPaint = new Paint();
private final int mStatusBarColor;
@@ -551,6 +550,7 @@ class TaskSnapshotSurface implements StartingSurface {
private final int mSysUiVis;
private final float mScale;
private final InsetsState mInsetsState;
+ private final Rect mSystemBarInsets = new Rect();
SystemBarBackgroundPainter(int windowFlags, int windowPrivateFlags, int sysUiVis,
TaskDescription taskDescription, float scale, InsetsState insetsState) {
@@ -576,9 +576,8 @@ class TaskSnapshotSurface implements StartingSurface {
mInsetsState = insetsState;
}
- void setInsets(Rect contentInsets, Rect stableInsets) {
- mContentInsets.set(contentInsets);
- mStableInsets.set(stableInsets);
+ void setInsets(Rect systemBarInsets) {
+ mSystemBarInsets.set(systemBarInsets);
}
int getStatusBarColorViewHeight() {
@@ -589,7 +588,7 @@ class TaskSnapshotSurface implements StartingSurface {
mSysUiVis, mStatusBarColor, mWindowFlags, forceBarBackground)
: STATUS_BAR_COLOR_VIEW_ATTRIBUTES.isVisible(
mInsetsState, mStatusBarColor, mWindowFlags, forceBarBackground)) {
- return (int) (getColorViewTopInset(mStableInsets.top, mContentInsets.top) * mScale);
+ return (int) (mSystemBarInsets.top * mScale);
} else {
return 0;
}
@@ -615,8 +614,7 @@ class TaskSnapshotSurface implements StartingSurface {
int statusBarHeight) {
if (statusBarHeight > 0 && Color.alpha(mStatusBarColor) != 0
&& (alreadyDrawnFrame == null || c.getWidth() > alreadyDrawnFrame.right)) {
- final int rightInset = (int) (DecorView.getColorViewRightInset(mStableInsets.right,
- mContentInsets.right) * mScale);
+ final int rightInset = (int) (mSystemBarInsets.right * mScale);
final int left = alreadyDrawnFrame != null ? alreadyDrawnFrame.right : 0;
c.drawRect(left, 0, c.getWidth() - rightInset, statusBarHeight, mStatusBarPaint);
}
@@ -625,8 +623,8 @@ class TaskSnapshotSurface implements StartingSurface {
@VisibleForTesting
void drawNavigationBarBackground(Canvas c) {
final Rect navigationBarRect = new Rect();
- getNavigationBarRect(c.getWidth(), c.getHeight(), mStableInsets, mContentInsets,
- navigationBarRect, mScale);
+ getNavigationBarRect(c.getWidth(), c.getHeight(), mSystemBarInsets, navigationBarRect,
+ mScale);
final boolean visible = isNavigationBarColorViewVisible();
if (visible && Color.alpha(mNavigationBarColor) != 0 && !navigationBarRect.isEmpty()) {
c.drawRect(navigationBarRect, mNavigationBarPaint);
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index 92a9e30c2f0a..9d0bac9dd290 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -17,6 +17,10 @@
package com.android.server.wm;
import static com.android.server.wm.ProtoLogGroup.WM_SHOW_TRANSACTIONS;
+import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_ALL;
+import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION;
+import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_RECENTS;
+import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_SCREEN_ROTATION;
import static com.android.server.wm.WindowContainer.AnimationFlags.CHILDREN;
import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_TRACE;
@@ -52,6 +56,9 @@ public class WindowAnimator {
/** Is any window animating? */
private boolean mLastRootAnimating;
+ /** True if we are running any animations that require expensive composition. */
+ private boolean mRunningExpensiveAnimations;
+
final Choreographer.FrameCallback mAnimationFrameCallback;
/** Time of current animation step. Reset on each iteration */
@@ -165,12 +172,8 @@ public class WindowAnimator {
mService.mWatermark.drawIfNeeded();
}
- SurfaceControl.mergeToGlobalTransaction(mTransaction);
} catch (RuntimeException e) {
Slog.wtf(TAG, "Unhandled exception in Window Manager", e);
- } finally {
- mService.closeSurfaceTransaction("WindowAnimator");
- ProtoLog.i(WM_SHOW_TRANSACTIONS, "<<< CLOSE TRANSACTION animate");
}
final boolean hasPendingLayoutChanges = mService.mRoot.hasPendingLayoutChanges(this);
@@ -179,21 +182,36 @@ public class WindowAnimator {
mService.mWindowPlacerLocked.requestTraversal();
}
- final boolean rootAnimating = mService.mRoot.isAnimating(TRANSITION | CHILDREN);
+ final boolean rootAnimating = mService.mRoot.isAnimating(TRANSITION | CHILDREN /* flags */,
+ ANIMATION_TYPE_ALL /* typesToCheck */);
if (rootAnimating && !mLastRootAnimating) {
- // Usually app transitions but quite a load onto the system already (with all the things
- // happening in app), so pause task snapshot persisting to not increase the load.
- mService.mTaskSnapshotController.setPersisterPaused(true);
Trace.asyncTraceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "animating", 0);
}
if (!rootAnimating && mLastRootAnimating) {
mService.mWindowPlacerLocked.requestTraversal();
- mService.mTaskSnapshotController.setPersisterPaused(false);
Trace.asyncTraceEnd(Trace.TRACE_TAG_WINDOW_MANAGER, "animating", 0);
}
-
mLastRootAnimating = rootAnimating;
+ final boolean runningExpensiveAnimations =
+ mService.mRoot.isAnimating(TRANSITION | CHILDREN /* flags */,
+ ANIMATION_TYPE_APP_TRANSITION | ANIMATION_TYPE_SCREEN_ROTATION
+ | ANIMATION_TYPE_RECENTS /* typesToCheck */);
+ if (runningExpensiveAnimations && !mRunningExpensiveAnimations) {
+ // Usually app transitions put quite a load onto the system already (with all the things
+ // happening in app), so pause task snapshot persisting to not increase the load.
+ mService.mTaskSnapshotController.setPersisterPaused(true);
+ mTransaction.setEarlyWakeupStart();
+ } else if (!runningExpensiveAnimations && mRunningExpensiveAnimations) {
+ mService.mTaskSnapshotController.setPersisterPaused(false);
+ mTransaction.setEarlyWakeupEnd();
+ }
+ mRunningExpensiveAnimations = runningExpensiveAnimations;
+
+ SurfaceControl.mergeToGlobalTransaction(mTransaction);
+ mService.closeSurfaceTransaction("WindowAnimator");
+ ProtoLog.i(WM_SHOW_TRANSACTIONS, "<<< CLOSE TRANSACTION animate");
+
if (mRemoveReplacedWindows) {
mService.mRoot.removeReplacedWindows();
mRemoveReplacedWindows = false;
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 6406f0ae51a6..1a6d85547c92 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -93,6 +93,7 @@ import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.LinkedList;
+import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
@@ -179,6 +180,8 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
* Applied as part of the animation pass in "prepareSurfaces".
*/
protected final SurfaceAnimator mSurfaceAnimator;
+ private boolean mAnyParentAnimating;
+
final SurfaceFreezer mSurfaceFreezer;
protected final WindowManagerService mWmService;
@@ -1032,7 +1035,8 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
* @return Whether this child is on top of the window hierarchy.
*/
boolean isOnTop() {
- return getParent().getTopChild() == this && getParent().isOnTop();
+ final WindowContainer parent = getParent();
+ return parent != null && parent.getTopChild() == this && parent.isOnTop();
}
/** Returns the top child container. */
@@ -1893,6 +1897,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
}
boolean needsZBoost() {
+ if (mNeedsZBoost) return true;
for (int i = 0; i < mChildren.size(); i++) {
if (mChildren.get(i).needsZBoost()) {
return true;
@@ -2459,21 +2464,16 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
*/
@Nullable
WindowContainer getAnimatingContainer(int flags, int typesToCheck) {
- int animationType = mSurfaceAnimator.getAnimationType();
- if (mSurfaceAnimator.isAnimating() && (animationType & typesToCheck) > 0) {
- return this;
- }
- if ((flags & TRANSITION) != 0 && isWaitingForTransitionStart()) {
+ if (isSelfAnimating(flags, typesToCheck)) {
return this;
}
if ((flags & PARENTS) != 0) {
- final WindowContainer parent = getParent();
- if (parent != null) {
- final WindowContainer wc = parent.getAnimatingContainer(
- flags & ~CHILDREN, typesToCheck);
- if (wc != null) {
- return wc;
+ WindowContainer parent = getParent();
+ while (parent != null) {
+ if (parent.isSelfAnimating(flags, typesToCheck)) {
+ return parent;
}
+ parent = parent.getParent();
}
}
if ((flags & CHILDREN) != 0) {
@@ -2489,6 +2489,21 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
}
/**
+ * Internal method only to be used during {@link #getAnimatingContainer(int, int)}.DO NOT CALL
+ * FROM OUTSIDE.
+ */
+ protected boolean isSelfAnimating(int flags, int typesToCheck) {
+ if (mSurfaceAnimator.isAnimating()
+ && (mSurfaceAnimator.getAnimationType() & typesToCheck) > 0) {
+ return true;
+ }
+ if ((flags & TRANSITION) != 0 && isWaitingForTransitionStart()) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
* @deprecated Use {@link #getAnimatingContainer(int, int)} instead.
*/
@Nullable
@@ -2672,11 +2687,13 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
}
@Override
- public void onTransactionReady(int mSyncId, SurfaceControl.Transaction mergedTransaction) {
- mergedTransaction.merge(mBLASTSyncTransaction);
- mUsingBLASTSyncTransaction = false;
+ public void onTransactionReady(int mSyncId, Set<WindowContainer> windowContainersReady) {
+ if (mWaitingListener == null) {
+ return;
+ }
- mWaitingListener.onTransactionReady(mWaitingSyncId, mergedTransaction);
+ windowContainersReady.add(this);
+ mWaitingListener.onTransactionReady(mWaitingSyncId, windowContainersReady);
mWaitingListener = null;
mWaitingSyncId = -1;
@@ -2727,4 +2744,9 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
boolean useBLASTSync() {
return mUsingBLASTSyncTransaction;
}
+
+ void mergeBlastSyncTransaction(Transaction t) {
+ t.merge(mBLASTSyncTransaction);
+ mUsingBLASTSyncTransaction = false;
+ }
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 0590288a7f8b..52fb941ebfc0 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -139,7 +139,6 @@ import android.app.IActivityManager;
import android.app.IActivityTaskManager;
import android.app.IAssistDataReceiver;
import android.app.WindowConfiguration;
-import android.app.admin.DevicePolicyCache;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
@@ -369,7 +368,8 @@ public class WindowManagerService extends IWindowManager.Stub
static final long DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS = 5000 * 1000000L;
// Poll interval in milliseconds for watching boot animation finished.
- private static final int BOOT_ANIMATION_POLL_INTERVAL = 200;
+ // TODO(b/159045990) Migrate to SystemService.waitForState with dedicated thread.
+ private static final int BOOT_ANIMATION_POLL_INTERVAL = 50;
// The name of the boot animation service in init.rc.
private static final String BOOT_ANIMATION_SERVICE = "bootanim";
@@ -415,6 +415,13 @@ public class WindowManagerService extends IWindowManager.Stub
static boolean sEnableTripleBuffering = !SystemProperties.getBoolean(
DISABLE_TRIPLE_BUFFERING_PROPERTY, false);
+ /**
+ * Allows a fullscreen windowing mode activity to launch in its desired orientation directly
+ * when the display has different orientation.
+ */
+ static final boolean ENABLE_FIXED_ROTATION_TRANSFORM =
+ SystemProperties.getBoolean("persist.wm.fixed_rotation_transform", true);
+
// Enums for animation scale update types.
@Retention(RetentionPolicy.SOURCE)
@IntDef({WINDOW_ANIMATION_SCALE, TRANSITION_ANIMATION_SCALE, ANIMATION_DURATION_SCALE})
@@ -431,10 +438,6 @@ public class WindowManagerService extends IWindowManager.Stub
/** System UI can create more window context... */
private static final int SYSTEM_UI_MULTIPLIER = 2;
- // TODO(b/143053092): Remove the settings if it becomes stable.
- private static final String FIXED_ROTATION_TRANSFORM_SETTING_NAME = "fixed_rotation_transform";
- boolean mIsFixedRotationTransformEnabled;
-
final WindowManagerConstants mConstants;
final WindowTracing mWindowTracing;
@@ -528,6 +531,10 @@ public class WindowManagerService extends IWindowManager.Stub
final boolean mAllowBootMessages;
+ // Indicates whether the Assistant should show on top of the Dream (respectively, above
+ // everything else on screen). Otherwise, it will be put under always-on-top stacks.
+ final boolean mAssistantOnTopOfDream;
+
final boolean mLimitedAlphaCompositing;
final int mMaxUiWidth;
@@ -761,8 +768,6 @@ public class WindowManagerService extends IWindowManager.Stub
DEVELOPMENT_ENABLE_SIZECOMPAT_FREEFORM);
private final Uri mRenderShadowsInCompositorUri = Settings.Global.getUriFor(
DEVELOPMENT_RENDER_SHADOWS_IN_COMPOSITOR);
- private final Uri mFixedRotationTransformUri = Settings.Global.getUriFor(
- FIXED_ROTATION_TRANSFORM_SETTING_NAME);
public SettingsObserver() {
super(new Handler());
@@ -787,8 +792,6 @@ public class WindowManagerService extends IWindowManager.Stub
UserHandle.USER_ALL);
resolver.registerContentObserver(mRenderShadowsInCompositorUri, false, this,
UserHandle.USER_ALL);
- resolver.registerContentObserver(mFixedRotationTransformUri, false, this,
- UserHandle.USER_ALL);
}
@Override
@@ -832,11 +835,6 @@ public class WindowManagerService extends IWindowManager.Stub
return;
}
- if (mFixedRotationTransformUri.equals(uri)) {
- updateFixedRotationTransform();
- return;
- }
-
@UpdateAnimationScaleMode
final int mode;
if (mWindowAnimationScaleUri.equals(uri)) {
@@ -856,7 +854,6 @@ public class WindowManagerService extends IWindowManager.Stub
void loadSettings() {
updateSystemUiSettings();
updatePointerLocation();
- updateFixedRotationTransform();
}
void updateSystemUiSettings() {
@@ -928,17 +925,6 @@ public class WindowManagerService extends IWindowManager.Stub
mAtmService.mSizeCompatFreeform = sizeCompatFreeform;
}
-
- void updateFixedRotationTransform() {
- final int enabled = Settings.Global.getInt(mContext.getContentResolver(),
- FIXED_ROTATION_TRANSFORM_SETTING_NAME, 2);
- if (enabled == 2) {
- // Make sure who read the settings won't use inconsistent default value.
- Settings.Global.putInt(mContext.getContentResolver(),
- FIXED_ROTATION_TRANSFORM_SETTING_NAME, 1);
- }
- mIsFixedRotationTransformEnabled = enabled != 0;
- }
}
private void setShadowRenderer() {
@@ -1181,6 +1167,8 @@ public class WindowManagerService extends IWindowManager.Stub
com.android.internal.R.bool.config_disableTransitionAnimation);
mPerDisplayFocusEnabled = context.getResources().getBoolean(
com.android.internal.R.bool.config_perDisplayFocusEnabled);
+ mAssistantOnTopOfDream = context.getResources().getBoolean(
+ com.android.internal.R.bool.config_assistantOnTopOfDream);
mInputManager = inputManager; // Must be before createDisplayContentLocked.
mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
@@ -1881,16 +1869,6 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
- boolean isSecureLocked(WindowState w) {
- if ((w.mAttrs.flags&WindowManager.LayoutParams.FLAG_SECURE) != 0) {
- return true;
- }
- if (DevicePolicyCache.getInstance().getScreenCaptureDisabled(w.mShowUserId)) {
- return true;
- }
- return false;
- }
-
/**
* Set whether screen capture is disabled for all windows of a specific user from
* the device policy cache.
@@ -1904,8 +1882,7 @@ public class WindowManagerService extends IWindowManager.Stub
synchronized (mGlobalLock) {
// Update secure surface for all windows belonging to this user.
- mRoot.setSecureSurfaceState(userId,
- DevicePolicyCache.getInstance().getScreenCaptureDisabled(userId));
+ mRoot.setSecureSurfaceState(userId);
}
}
@@ -2255,7 +2232,7 @@ public class WindowManagerService extends IWindowManager.Stub
&& (win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0;
wallpaperMayMove |= (flagChanges & FLAG_SHOW_WALLPAPER) != 0;
if ((flagChanges & FLAG_SECURE) != 0 && winAnimator.mSurfaceController != null) {
- winAnimator.mSurfaceController.setSecure(isSecureLocked(win));
+ winAnimator.mSurfaceController.setSecure(win.isSecureLocked());
}
win.mRelayoutCalled = true;
@@ -2877,15 +2854,13 @@ public class WindowManagerService extends IWindowManager.Stub
aspectRatio);
}
- public void getStackBounds(int windowingMode, int activityType, Rect bounds) {
- synchronized (mGlobalLock) {
- final ActivityStack stack = mRoot.getStack(windowingMode, activityType);
- if (stack != null) {
- stack.getBounds(bounds);
- return;
- }
- bounds.setEmpty();
+ void getStackBounds(int windowingMode, int activityType, Rect bounds) {
+ final ActivityStack stack = mRoot.getStack(windowingMode, activityType);
+ if (stack != null) {
+ stack.getBounds(bounds);
+ return;
}
+ bounds.setEmpty();
}
/**
@@ -7150,9 +7125,6 @@ public class WindowManagerService extends IWindowManager.Stub
+ "not exist: %d", displayId);
return false;
}
- if (displayContent.isUntrustedVirtualDisplay()) {
- return false;
- }
return displayContent.supportsSystemDecorations();
}
}
@@ -7171,7 +7143,7 @@ public class WindowManagerService extends IWindowManager.Stub
+ "does not exist: %d", displayId);
return;
}
- if (displayContent.isUntrustedVirtualDisplay()) {
+ if (!displayContent.isTrusted()) {
throw new SecurityException("Attempted to set system decors flag to an "
+ "untrusted virtual display: " + displayId);
}
@@ -7219,7 +7191,7 @@ public class WindowManagerService extends IWindowManager.Stub
+ "exist: %d", displayId);
return;
}
- if (displayContent.isUntrustedVirtualDisplay()) {
+ if (!displayContent.isTrusted()) {
throw new SecurityException("Attempted to set IME flag to an untrusted "
+ "virtual display: " + displayId);
}
diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java
index a3faa86758cd..fbc5afadac6b 100644
--- a/services/core/java/com/android/server/wm/WindowOrganizerController.java
+++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java
@@ -44,6 +44,7 @@ import android.window.IWindowOrganizerController;
import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.function.pooled.PooledConsumer;
import com.android.internal.util.function.pooled.PooledLambda;
@@ -51,6 +52,7 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Set;
/**
* Server side implementation for the interface for organizing windows
@@ -142,7 +144,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
// operations so we don't end up splitting effects between the WM
// pending transaction and the BLASTSync transaction.
if (syncId >= 0) {
- mBLASTSyncEngine.addToSyncSet(syncId, wc);
+ addToSyncSet(syncId, wc);
}
int containerEffect = applyWindowContainerChange(wc, entry.getValue());
@@ -164,7 +166,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
continue;
}
if (syncId >= 0) {
- mBLASTSyncEngine.addToSyncSet(syncId, wc);
+ addToSyncSet(syncId, wc);
}
effects |= sanitizeAndApplyHierarchyOp(wc, hop);
}
@@ -396,21 +398,33 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
return mDisplayAreaOrganizerController;
}
+ @VisibleForTesting
int startSyncWithOrganizer(IWindowContainerTransactionCallback callback) {
int id = mBLASTSyncEngine.startSyncSet(this);
mTransactionCallbacksByPendingSyncId.put(id, callback);
return id;
}
+ @VisibleForTesting
void setSyncReady(int id) {
mBLASTSyncEngine.setReady(id);
}
+ @VisibleForTesting
+ void addToSyncSet(int syncId, WindowContainer wc) {
+ mBLASTSyncEngine.addToSyncSet(syncId, wc);
+ }
+
@Override
- public void onTransactionReady(int mSyncId, SurfaceControl.Transaction mergedTransaction) {
+ public void onTransactionReady(int mSyncId, Set<WindowContainer> windowContainersReady) {
final IWindowContainerTransactionCallback callback =
mTransactionCallbacksByPendingSyncId.get(mSyncId);
+ SurfaceControl.Transaction mergedTransaction = new SurfaceControl.Transaction();
+ for (WindowContainer container : windowContainersReady) {
+ container.mergeBlastSyncTransaction(mergedTransaction);
+ }
+
try {
callback.onTransactionReady(mSyncId, mergedTransaction);
} catch (RemoteException e) {
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 32717d0e1e65..26a1fea1732b 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -176,6 +176,7 @@ import static com.android.server.wm.WindowStateProto.WINDOW_FRAMES;
import android.annotation.CallSuper;
import android.annotation.Nullable;
import android.app.AppOpsManager;
+import android.app.admin.DevicePolicyCache;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Matrix;
@@ -241,8 +242,10 @@ import com.android.server.wm.utils.WmDisplayCutout;
import java.io.PrintWriter;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.Comparator;
import java.util.List;
+import java.util.Set;
import java.util.function.Predicate;
/** A window in the window manager. */
@@ -655,6 +658,15 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
private static final StringBuilder sTmpSB = new StringBuilder();
/**
+ * Whether the next surfacePlacement call should notify that the blast sync is ready.
+ * This is set to true when {@link #finishDrawing(Transaction)} is called so
+ * {@link #onTransactionReady(int, Set)} is called after the next surfacePlacement. This allows
+ * Transactions to get flushed into the syncTransaction before notifying {@link BLASTSyncEngine}
+ * that this WindowState is ready.
+ */
+ private boolean mNotifyBlastOnSurfacePlacement;
+
+ /**
* Compares two window sub-layers and returns -1 if the first is lesser than the second in terms
* of z-order and 1 otherwise.
*/
@@ -705,6 +717,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
static final int BLAST_TIMEOUT_DURATION = 5000; /* milliseconds */
+ private final WindowProcessController mWpcForDisplayConfigChanges;
+
/**
* @return The insets state as requested by the client, i.e. the dispatched insets state
* for which the visibilities are overridden with what the client requested.
@@ -719,8 +733,9 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
void updateRequestedInsetsState(InsetsState state) {
// Only update the sources the client is actually controlling.
- for (int i = state.getSourcesCount() - 1; i >= 0; i--) {
- final InsetsSource source = state.sourceAt(i);
+ for (int i = 0; i < InsetsState.SIZE; i++) {
+ final InsetsSource source = state.peekSource(i);
+ if (source == null) continue;
mRequestedInsetsState.addSource(source);
}
}
@@ -872,6 +887,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
mSubLayer = 0;
mInputWindowHandle = null;
mWinAnimator = null;
+ mWpcForDisplayConfigChanges = null;
return;
}
mDeathRecipient = deathRecipient;
@@ -927,6 +943,11 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
ProtoLog.v(WM_DEBUG_ADD_REMOVE, "Adding %s to %s", this, parentWindow);
parentWindow.addChild(this, sWindowSubLayerComparator);
}
+
+ // System process or invalid process cannot register to display config change.
+ mWpcForDisplayConfigChanges = (s.mPid == MY_PID || s.mPid < 0)
+ ? null
+ : service.mAtmService.getProcessController(s.mPid, s.mUid);
}
void attach() {
@@ -1529,6 +1550,29 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
}
/**
+ * This is a form of rectangle "difference". It cut off each dimension of rect by the amount
+ * that toRemove is "pushing into" it from the outside. Any dimension that fully contains
+ * toRemove won't change.
+ */
+ private void cutRect(Rect rect, Rect toRemove) {
+ if (toRemove.isEmpty()) return;
+ if (toRemove.top < rect.bottom && toRemove.bottom > rect.top) {
+ if (toRemove.right >= rect.right && toRemove.left >= rect.left) {
+ rect.right = toRemove.left;
+ } else if (toRemove.left <= rect.left && toRemove.right <= rect.right) {
+ rect.left = toRemove.right;
+ }
+ }
+ if (toRemove.left < rect.right && toRemove.right > rect.left) {
+ if (toRemove.bottom >= rect.bottom && toRemove.top >= rect.top) {
+ rect.bottom = toRemove.top;
+ } else if (toRemove.top <= rect.top && toRemove.bottom <= rect.bottom) {
+ rect.top = toRemove.bottom;
+ }
+ }
+ }
+
+ /**
* Retrieves the visible bounds of the window.
* @param bounds The rect which gets the bounds.
*/
@@ -1544,6 +1588,20 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
} else {
intersectWithStackBounds = false;
}
+ if (inSplitScreenPrimaryWindowingMode()) {
+ // If this is in the primary split and the home stack is the top visible task in
+ // the secondary split, it means this is "minimized" and thus must prevent
+ // overlapping with home.
+ // TODO(b/158242495): get rid of this when drag/drop can use surface bounds.
+ final ActivityStack rootSecondary =
+ task.getDisplayArea().getRootSplitScreenSecondaryTask();
+ if (rootSecondary.isActivityTypeHome() || rootSecondary.isActivityTypeRecents()) {
+ final WindowContainer topTask = rootSecondary.getTopChild();
+ if (topTask.isVisible()) {
+ cutRect(mTmpRect, topTask.getBounds());
+ }
+ }
+ }
}
bounds.set(mWindowFrames.mVisibleFrame);
@@ -1707,6 +1765,14 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
&& mActivityRecord.getActivityType() == ACTIVITY_TYPE_DREAM;
}
+ boolean isSecureLocked() {
+ if ((mAttrs.flags & WindowManager.LayoutParams.FLAG_SECURE) != 0) {
+ return true;
+ }
+ return !DevicePolicyCache.getInstance().isScreenCaptureAllowed(mShowUserId,
+ mOwnerCanAddInternalSystemWindow);
+ }
+
/**
* Whether this window's drawn state might affect the drawn states of the app token.
*
@@ -2302,6 +2368,10 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
return false;
}
+ if (inPinnedWindowingMode()) {
+ return false;
+ }
+
final boolean windowsAreFocusable = mActivityRecord == null || mActivityRecord.windowsAreFocusable();
if (!windowsAreFocusable) {
// This window can't be an IME target if the app's windows should not be focusable.
@@ -2793,7 +2863,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
// Do not allow untrusted virtual display to receive keys unless user intentionally
// touches the display.
return fromUserTouch || getDisplayContent().isOnTop()
- || !getDisplayContent().isUntrustedVirtualDisplay();
+ || getDisplayContent().isTrusted();
}
@Override
@@ -3375,6 +3445,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
private void setTouchableRegionCropIfNeeded(InputWindowHandle handle) {
final Task task = getTask();
if (task == null || !task.cropWindowsToStackBounds()) {
+ handle.setTouchableRegionCrop(null);
return;
}
@@ -3463,13 +3534,10 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
/** @return {@code true} if the process registered to a display as a config listener. */
private boolean registeredForDisplayConfigChanges() {
final WindowState parentWindow = getParentWindow();
- final Session session = parentWindow != null ? parentWindow.mSession : mSession;
- // System process or invalid process cannot register to display config change.
- if (session.mPid == MY_PID || session.mPid < 0) return false;
- WindowProcessController app =
- mWmService.mAtmService.getProcessController(session.mPid, session.mUid);
- if (app == null || !app.registeredForDisplayConfigChanges()) return false;
- return true;
+ final WindowProcessController wpc = parentWindow != null
+ ? parentWindow.mWpcForDisplayConfigChanges
+ : mWpcForDisplayConfigChanges;
+ return wpc != null && wpc.registeredForDisplayConfigChanges();
}
void reportResized() {
@@ -3576,6 +3644,9 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
@Override
public void notifyInsetsControlChanged() {
ProtoLog.d(WM_DEBUG_IME, "notifyInsetsControlChanged for %s ", this);
+ if (mAppDied || mRemoved) {
+ return;
+ }
final InsetsStateController stateController =
getDisplayContent().getInsetsStateController();
try {
@@ -5049,13 +5120,12 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
mWindowFrames.updateLastInsetValues();
}
- @Nullable
@Override
- WindowContainer<WindowState> getAnimatingContainer(int flags, int typesToCheck) {
+ protected boolean isSelfAnimating(int flags, int typesToCheck) {
if (mControllableInsetProvider != null) {
- return null;
+ return false;
}
- return super.getAnimatingContainer(flags, typesToCheck);
+ return super.isSelfAnimating(flags, typesToCheck);
}
void startAnimation(Animation anim) {
@@ -5118,17 +5188,18 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
float9[Matrix.MSKEW_Y] = mWinAnimator.mDtDx;
float9[Matrix.MSKEW_X] = mWinAnimator.mDtDy;
float9[Matrix.MSCALE_Y] = mWinAnimator.mDsDy;
- int x = mSurfacePosition.x;
- int y = mSurfacePosition.y;
+ transformSurfaceInsetsPosition(mTmpPoint, mAttrs.surfaceInsets);
+ int x = mSurfacePosition.x + mTmpPoint.x;
+ int y = mSurfacePosition.y + mTmpPoint.y;
// We might be on a display which has been re-parented to a view in another window, so here
// computes the global location of our display.
DisplayContent dc = getDisplayContent();
while (dc != null && dc.getParentWindow() != null) {
final WindowState displayParent = dc.getParentWindow();
- x += displayParent.mWindowFrames.mFrame.left - displayParent.mAttrs.surfaceInsets.left
+ x += displayParent.mWindowFrames.mFrame.left
+ (dc.getLocationInParentWindow().x * displayParent.mGlobalScale + 0.5f);
- y += displayParent.mWindowFrames.mFrame.top - displayParent.mAttrs.surfaceInsets.top
+ y += displayParent.mWindowFrames.mFrame.top
+ (dc.getLocationInParentWindow().y * displayParent.mGlobalScale + 0.5f);
dc = displayParent.getDisplayContent();
}
@@ -5244,10 +5315,10 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
return mWillReplaceWindow;
}
- private void applyDims(Dimmer dimmer) {
+ private void applyDims() {
if (!mAnimatingExit && mAppDied) {
mIsDimming = true;
- dimmer.dimAbove(getSyncTransaction(), this, DEFAULT_DIM_AMOUNT_DEAD_WINDOW);
+ getDimmer().dimAbove(getSyncTransaction(), this, DEFAULT_DIM_AMOUNT_DEAD_WINDOW);
} else if ((mAttrs.flags & FLAG_DIM_BEHIND) != 0 && isVisibleNow() && !mHidden) {
// Only show a dim behind when the following is satisfied:
// 1. The window has the flag FLAG_DIM_BEHIND
@@ -5255,7 +5326,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
// 3. The WS is considered visible according to the isVisible() method
// 4. The WS is not hidden.
mIsDimming = true;
- dimmer.dimBelow(getSyncTransaction(), this, mAttrs.dimAmount);
+ getDimmer().dimBelow(getSyncTransaction(), this, mAttrs.dimAmount);
}
}
@@ -5279,16 +5350,14 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
@Override
void prepareSurfaces() {
- final Dimmer dimmer = getDimmer();
mIsDimming = false;
- if (dimmer != null) {
- applyDims(dimmer);
- }
+ applyDims();
updateSurfacePosition();
// Send information to SufaceFlinger about the priority of the current window.
updateFrameRateSelectionPriorityIfNeeded();
mWinAnimator.prepareSurfaceLocked(true);
+ notifyBlastSyncTransaction();
super.prepareSurfaces();
}
@@ -5386,6 +5455,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
final WindowState imeTarget = getDisplayContent().mInputMethodTarget;
boolean inTokenWithAndAboveImeTarget = imeTarget != null && imeTarget != this
&& imeTarget.mToken == mToken
+ && mAttrs.type != TYPE_APPLICATION_STARTING
&& getParent() != null
&& imeTarget.compareTo(this) <= 0;
return inTokenWithAndAboveImeTarget;
@@ -5779,6 +5849,17 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
mBLASTSyncTransaction.merge(postDrawTransaction);
}
+ mNotifyBlastOnSurfacePlacement = true;
+ return mWinAnimator.finishDrawingLocked(null);
+ }
+
+ @VisibleForTesting
+ void notifyBlastSyncTransaction() {
+ if (!mNotifyBlastOnSurfacePlacement || mWaitingListener == null) {
+ mNotifyBlastOnSurfacePlacement = false;
+ return;
+ }
+
// If localSyncId is >0 then we are syncing with children and will
// invoke transaction ready from our own #transactionReady callback
// we just need to signal our side of the sync (setReady). But if we
@@ -5786,15 +5867,14 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
// be invoked and we need to invoke it ourself.
if (mLocalSyncId >= 0) {
mBLASTSyncEngine.setReady(mLocalSyncId);
- return mWinAnimator.finishDrawingLocked(null);
+ return;
}
- mWaitingListener.onTransactionReady(mWaitingSyncId, mBLASTSyncTransaction);
- mUsingBLASTSyncTransaction = false;
+ mWaitingListener.onTransactionReady(mWaitingSyncId, Collections.singleton(this));
mWaitingSyncId = 0;
mWaitingListener = null;
- return mWinAnimator.finishDrawingLocked(null);
+ mNotifyBlastOnSurfacePlacement = false;
}
private boolean requestResizeForBlastSync() {
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index c0252363a159..508d2d477067 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -247,10 +247,6 @@ class WindowStateAnimator {
private final SurfaceControl.Transaction mPostDrawTransaction =
new SurfaceControl.Transaction();
- // Used to track whether we have called detach children on the way to invisibility, in which
- // case we need to give the client a new Surface if it lays back out to a visible state.
- boolean mChildrenDetached = false;
-
// Set to true after the first frame of the Pinned stack animation
// and reset after the last to ensure we only reset mForceScaleUntilResize
// once per animation.
@@ -425,7 +421,8 @@ class WindowStateAnimator {
// transparent to the app.
// If the children are detached, we don't want to reparent them to the new surface.
// Instead let the children get removed when the old surface is deleted.
- if (mSurfaceController != null && mPendingDestroySurface != null && !mChildrenDetached
+ if (mSurfaceController != null && mPendingDestroySurface != null
+ && !mPendingDestroySurface.mChildrenDetached
&& (mWin.mActivityRecord == null || !mWin.mActivityRecord.isRelaunching())) {
mPostDrawTransaction.reparentChildren(
mPendingDestroySurface.getClientViewRootSurface(),
@@ -461,7 +458,6 @@ class WindowStateAnimator {
if (mSurfaceController != null) {
return mSurfaceController;
}
- mChildrenDetached = false;
if ((mWin.mAttrs.privateFlags & PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY) != 0) {
windowType = SurfaceControl.WINDOW_TYPE_DONT_SCREENSHOT;
@@ -480,7 +476,7 @@ class WindowStateAnimator {
int flags = SurfaceControl.HIDDEN;
final WindowManager.LayoutParams attrs = w.mAttrs;
- if (mService.isSecureLocked(w)) {
+ if (w.isSecureLocked()) {
flags |= SurfaceControl.SECURE;
}
@@ -1365,7 +1361,7 @@ class WindowStateAnimator {
mPostDrawTransaction.reparent(pendingSurfaceControl, null);
// If the children are detached, we don't want to reparent them to the new surface.
// Instead let the children get removed when the old surface is deleted.
- if (!mChildrenDetached) {
+ if (!mPendingDestroySurface.mChildrenDetached) {
mPostDrawTransaction.reparentChildren(
mPendingDestroySurface.getClientViewRootSurface(),
mSurfaceController.mSurfaceControl);
@@ -1596,7 +1592,6 @@ class WindowStateAnimator {
if (mSurfaceController != null) {
mSurfaceController.detachChildren();
}
- mChildrenDetached = true;
// If the children are detached, it means the app is exiting. We don't want to tear the
// content down too early, otherwise we could end up with a flicker. By preserving the
// current surface, we ensure the content remains on screen until the window is completely
diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java
index 0a7ca5a0cf35..b2bfcdc8a900 100644
--- a/services/core/java/com/android/server/wm/WindowSurfaceController.java
+++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java
@@ -90,6 +90,9 @@ class WindowSurfaceController {
private final SurfaceControl.Transaction mTmpTransaction;
+ // Used to track whether we have called detach children on the way to invisibility.
+ boolean mChildrenDetached;
+
WindowSurfaceController(String name, int w, int h, int format,
int flags, WindowStateAnimator animator, int windowType, int ownerUid) {
mAnimator = animator;
@@ -144,6 +147,7 @@ class WindowSurfaceController {
void detachChildren() {
ProtoLog.i(WM_SHOW_TRANSACTIONS, "SEVER CHILDREN");
+ mChildrenDetached = true;
if (mSurfaceControl != null) {
mSurfaceControl.detachChildren();
}
diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java
index d2570023f419..86aacf308068 100644
--- a/services/core/java/com/android/server/wm/WindowToken.java
+++ b/services/core/java/com/android/server/wm/WindowToken.java
@@ -48,6 +48,7 @@ import android.os.Debug;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Slog;
+import android.util.SparseArray;
import android.util.proto.ProtoOutputStream;
import android.view.DisplayAdjustments.FixedRotationAdjustments;
import android.view.DisplayInfo;
@@ -124,7 +125,7 @@ class WindowToken extends WindowContainer<WindowState> {
private static class FixedRotationTransformState {
final DisplayInfo mDisplayInfo;
final DisplayFrames mDisplayFrames;
- final InsetsState mInsetsState;
+ final InsetsState mInsetsState = new InsetsState();
final Configuration mRotatedOverrideConfiguration;
final SeamlessRotator mRotator;
/**
@@ -133,14 +134,14 @@ class WindowToken extends WindowContainer<WindowState> {
*/
final ArrayList<WindowToken> mAssociatedTokens = new ArrayList<>(3);
final ArrayList<WindowContainer<?>> mRotatedContainers = new ArrayList<>(3);
+ final SparseArray<Rect> mBarContentFrames = new SparseArray<>();
boolean mIsTransforming = true;
FixedRotationTransformState(DisplayInfo rotatedDisplayInfo,
- DisplayFrames rotatedDisplayFrames, InsetsState rotatedInsetsState,
- Configuration rotatedConfig, int currentRotation) {
+ DisplayFrames rotatedDisplayFrames, Configuration rotatedConfig,
+ int currentRotation) {
mDisplayInfo = rotatedDisplayInfo;
mDisplayFrames = rotatedDisplayFrames;
- mInsetsState = rotatedInsetsState;
mRotatedOverrideConfiguration = rotatedConfig;
// This will use unrotate as rotate, so the new and old rotation are inverted.
mRotator = new SeamlessRotator(rotatedDisplayInfo.rotation, currentRotation,
@@ -516,6 +517,12 @@ class WindowToken extends WindowContainer<WindowState> {
: null;
}
+ Rect getFixedRotationBarContentFrame(int windowType) {
+ return isFixedRotationTransforming()
+ ? mFixedRotationTransformState.mBarContentFrames.get(windowType)
+ : null;
+ }
+
InsetsState getFixedRotationTransformInsetsState() {
return isFixedRotationTransforming() ? mFixedRotationTransformState.mInsetsState : null;
}
@@ -526,12 +533,12 @@ class WindowToken extends WindowContainer<WindowState> {
if (mFixedRotationTransformState != null) {
return;
}
- final InsetsState insetsState = new InsetsState();
- mDisplayContent.getDisplayPolicy().simulateLayoutDisplay(displayFrames, insetsState,
- mDisplayContent.getConfiguration().uiMode);
mFixedRotationTransformState = new FixedRotationTransformState(info, displayFrames,
- insetsState, new Configuration(config), mDisplayContent.getRotation());
+ new Configuration(config), mDisplayContent.getRotation());
mFixedRotationTransformState.mAssociatedTokens.add(this);
+ mDisplayContent.getDisplayPolicy().simulateLayoutDisplay(displayFrames,
+ mFixedRotationTransformState.mInsetsState,
+ mFixedRotationTransformState.mBarContentFrames);
onConfigurationChanged(getParent().getConfiguration());
notifyFixedRotationTransform(true /* enabled */);
}
@@ -554,6 +561,25 @@ class WindowToken extends WindowContainer<WindowState> {
notifyFixedRotationTransform(true /* enabled */);
}
+ /**
+ * Return {@code true} if one of the associated activity is still animating. Otherwise,
+ * return {@code false}.
+ */
+ boolean hasAnimatingFixedRotationTransition() {
+ if (mFixedRotationTransformState == null) {
+ return false;
+ }
+
+ for (int i = mFixedRotationTransformState.mAssociatedTokens.size() - 1; i >= 0; i--) {
+ final ActivityRecord r =
+ mFixedRotationTransformState.mAssociatedTokens.get(i).asActivityRecord();
+ if (r != null && r.isAnimating(TRANSITION | PARENTS)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
void finishFixedRotationTransform() {
finishFixedRotationTransform(null /* applyDisplayRotation */);
}
diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp
index 4c3f73d2d129..925ad0f57f19 100644
--- a/services/core/jni/Android.bp
+++ b/services/core/jni/Android.bp
@@ -29,6 +29,7 @@ cc_library_static {
"com_android_server_connectivity_Vpn.cpp",
"com_android_server_ConsumerIrService.cpp",
"com_android_server_devicepolicy_CryptoTestHelper.cpp",
+ "com_android_server_gpu_GpuService.cpp",
"com_android_server_HardwarePropertiesManagerService.cpp",
"com_android_server_hdmi_HdmiCecController.cpp",
"com_android_server_input_InputManagerService.cpp",
@@ -98,6 +99,7 @@ cc_defaults {
"libcutils",
"libcrypto",
"liblog",
+ "libgraphicsenv",
"libhardware",
"libhardware_legacy",
"libhidlbase",
diff --git a/services/core/jni/com_android_server_gpu_GpuService.cpp b/services/core/jni/com_android_server_gpu_GpuService.cpp
new file mode 100644
index 000000000000..2359e808d6f6
--- /dev/null
+++ b/services/core/jni/com_android_server_gpu_GpuService.cpp
@@ -0,0 +1,66 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "GpuService-JNI"
+
+#include <binder/IServiceManager.h>
+#include <graphicsenv/IGpuService.h>
+#include <nativehelper/JNIHelp.h>
+#include <nativehelper/scoped_utf_chars.h>
+
+namespace {
+
+static android::sp<android::IGpuService> getGpuService() {
+ static const android::sp<android::IBinder> binder =
+ android::defaultServiceManager()->checkService(android::String16("gpu"));
+ if (!binder) {
+ ALOGE("Failed to get gpu service");
+ return nullptr;
+ }
+
+ return interface_cast<android::IGpuService>(binder);
+}
+
+void setUpdatableDriverPath_native(JNIEnv* env, jobject clazz, jstring jDriverPath) {
+ if (jDriverPath == nullptr) {
+ return;
+ }
+ const android::sp<android::IGpuService> gpuService = getGpuService();
+ if (!gpuService) {
+ return;
+ }
+ ScopedUtfChars driverPath(env, jDriverPath);
+ gpuService->setUpdatableDriverPath(driverPath.c_str());
+}
+
+static const JNINativeMethod gGpuServiceMethods[] = {
+ /* name, signature, funcPtr */
+ {"nSetUpdatableDriverPath", "(Ljava/lang/String;)V",
+ reinterpret_cast<void*>(setUpdatableDriverPath_native)},
+};
+
+const char* const kGpuServiceName = "com/android/server/gpu/GpuService";
+
+} // anonymous namespace
+
+namespace android {
+
+int register_android_server_GpuService(JNIEnv* env) {
+ return jniRegisterNativeMethods(env, kGpuServiceName, gGpuServiceMethods,
+ NELEM(gGpuServiceMethods));
+}
+
+} /* namespace android */
diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
index c7dac787c653..465a3518ab65 100644
--- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
+++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
@@ -3109,9 +3109,7 @@ static jboolean android_location_GnssMeasurementsProvider_start_measurement_coll
result = gnssMeasurementIface_V1_1->setCallback_1_1(cbIface, enableFullTracking);
} else {
if (enableFullTracking == JNI_TRUE) {
- // full tracking mode not supported in 1.0 HAL
- result.assertOk(); // isOk() must be called before result destructor is invoked.
- return JNI_FALSE;
+ ALOGW("Full tracking mode not supported in 1.0 GNSS HAL.");
}
result = gnssMeasurementIface->setCallback(cbIface);
}
diff --git a/services/core/jni/com_android_server_storage_AppFuseBridge.cpp b/services/core/jni/com_android_server_storage_AppFuseBridge.cpp
index e51963340ae1..20210abd0ea8 100644
--- a/services/core/jni/com_android_server_storage_AppFuseBridge.cpp
+++ b/services/core/jni/com_android_server_storage_AppFuseBridge.cpp
@@ -123,6 +123,14 @@ jint com_android_server_storage_AppFuseBridge_add_bridge(
return proxyFd[1].release();
}
+void com_android_server_storage_AppFuseBridge_lock(JNIEnv* env, jobject self) {
+ fuse::FuseBridgeLoop::Lock();
+}
+
+void com_android_server_storage_AppFuseBridge_unlock(JNIEnv* env, jobject self) {
+ fuse::FuseBridgeLoop::Unlock();
+}
+
const JNINativeMethod methods[] = {
{
"native_new",
@@ -143,6 +151,16 @@ const JNINativeMethod methods[] = {
"native_add_bridge",
"(JII)I",
reinterpret_cast<void*>(com_android_server_storage_AppFuseBridge_add_bridge)
+ },
+ {
+ "native_lock",
+ "()V",
+ reinterpret_cast<void*>(com_android_server_storage_AppFuseBridge_lock)
+ },
+ {
+ "native_unlock",
+ "()V",
+ reinterpret_cast<void*>(com_android_server_storage_AppFuseBridge_unlock)
}
};
diff --git a/services/core/jni/onload.cpp b/services/core/jni/onload.cpp
index b988bd45d786..e5d2a83479e0 100644
--- a/services/core/jni/onload.cpp
+++ b/services/core/jni/onload.cpp
@@ -63,6 +63,7 @@ int register_com_android_server_soundtrigger_middleware_ExternalCaptureStateTrac
int register_android_server_com_android_server_pm_PackageManagerShellCommandDataLoader(JNIEnv* env);
int register_android_server_stats_pull_StatsPullAtomService(JNIEnv* env);
int register_android_server_AdbDebuggingManager(JNIEnv* env);
+int register_android_server_GpuService(JNIEnv* env);
};
using namespace android;
@@ -119,5 +120,6 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
register_android_server_com_android_server_pm_PackageManagerShellCommandDataLoader(env);
register_android_server_stats_pull_StatsPullAtomService(env);
register_android_server_AdbDebuggingManager(env);
+ register_android_server_GpuService(env);
return JNI_VERSION_1_4;
}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyCacheImpl.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyCacheImpl.java
index f3a693550b38..d616ed30772a 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyCacheImpl.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyCacheImpl.java
@@ -51,15 +51,15 @@ public class DevicePolicyCacheImpl extends DevicePolicyCache {
}
@Override
- public boolean getScreenCaptureDisabled(int userHandle) {
+ public boolean isScreenCaptureAllowed(int userHandle, boolean ownerCanAddInternalSystemWindow) {
synchronized (mLock) {
- return mScreenCaptureDisabled.get(userHandle);
+ return !mScreenCaptureDisabled.get(userHandle) || ownerCanAddInternalSystemWindow;
}
}
- public void setScreenCaptureDisabled(int userHandle, boolean disabled) {
+ public void setScreenCaptureAllowed(int userHandle, boolean allowed) {
synchronized (mLock) {
- mScreenCaptureDisabled.put(userHandle, disabled);
+ mScreenCaptureDisabled.put(userHandle, !allowed);
}
}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 7b624cae8141..c6b93d6ca4f4 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -7990,7 +7990,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
}
private void updateScreenCaptureDisabled(int userHandle, boolean disabled) {
- mPolicyCache.setScreenCaptureDisabled(userHandle, disabled);
+ mPolicyCache.setScreenCaptureAllowed(userHandle, !disabled);
mHandler.post(() -> {
try {
mInjector.getIWindowManager().refreshScreenCaptureDisabled(userHandle);
@@ -12712,7 +12712,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
for (ResolveInfo receiver : receivers) {
final String packageName = receiver.getComponentInfo().packageName;
if (checkCrossProfilePackagePermissions(packageName, userId,
- requiresPermission)) {
+ requiresPermission)
+ || checkModifyQuietModePermission(packageName, userId)) {
Slog.i(LOG_TAG,
String.format("Sending %s broadcast to %s.", intent.getAction(),
packageName));
@@ -12730,6 +12731,27 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
}
/**
+ * Checks whether the package {@code packageName} has the {@code MODIFY_QUIET_MODE}
+ * permission granted for the user {@code userId}.
+ */
+ private boolean checkModifyQuietModePermission(String packageName, @UserIdInt int userId) {
+ try {
+ final int uid = Objects.requireNonNull(
+ mInjector.getPackageManager().getApplicationInfoAsUser(
+ Objects.requireNonNull(packageName), /* flags= */ 0, userId)).uid;
+ return PackageManager.PERMISSION_GRANTED
+ == ActivityManager.checkComponentPermission(
+ android.Manifest.permission.MODIFY_QUIET_MODE, uid, /* owningUid= */
+ -1, /* exported= */ true);
+ } catch (NameNotFoundException ex) {
+ Slog.w(LOG_TAG,
+ String.format("Cannot find the package %s to check for permissions.",
+ packageName));
+ return false;
+ }
+ }
+
+ /**
* Checks whether the package {@code packageName} has the required permissions to receive
* cross-profile broadcasts on behalf of the user {@code userId}.
*/
diff --git a/services/incremental/BinderIncrementalService.cpp b/services/incremental/BinderIncrementalService.cpp
index e790a196ad64..7132706c4ef1 100644
--- a/services/incremental/BinderIncrementalService.cpp
+++ b/services/incremental/BinderIncrementalService.cpp
@@ -165,6 +165,11 @@ binder::Status BinderIncrementalService::deleteStorage(int32_t storageId) {
return ok();
}
+binder::Status BinderIncrementalService::disableReadLogs(int32_t storageId) {
+ mImpl.disableReadLogs(storageId);
+ return ok();
+}
+
binder::Status BinderIncrementalService::makeDirectory(int32_t storageId, const std::string& path,
int32_t* _aidl_return) {
*_aidl_return = mImpl.makeDir(storageId, path);
diff --git a/services/incremental/BinderIncrementalService.h b/services/incremental/BinderIncrementalService.h
index 68549f5a8ff8..10154946d3ee 100644
--- a/services/incremental/BinderIncrementalService.h
+++ b/services/incremental/BinderIncrementalService.h
@@ -74,7 +74,7 @@ public:
std::vector<uint8_t>* _aidl_return) final;
binder::Status startLoading(int32_t storageId, bool* _aidl_return) final;
binder::Status deleteStorage(int32_t storageId) final;
-
+ binder::Status disableReadLogs(int32_t storageId) final;
binder::Status configureNativeBinaries(int32_t storageId, const std::string& apkFullPath,
const std::string& libDirRelativePath,
const std::string& abi, bool extractNativeLibs,
diff --git a/services/incremental/IncrementalService.cpp b/services/incremental/IncrementalService.cpp
index 885f4d2d34d7..3450c3ae9fb3 100644
--- a/services/incremental/IncrementalService.cpp
+++ b/services/incremental/IncrementalService.cpp
@@ -60,6 +60,7 @@ struct Constants {
static constexpr auto storagePrefix = "st"sv;
static constexpr auto mountpointMdPrefix = ".mountpoint."sv;
static constexpr auto infoMdName = ".info"sv;
+ static constexpr auto readLogsDisabledMarkerName = ".readlogs_disabled"sv;
static constexpr auto libDir = "lib"sv;
static constexpr auto libSuffix = ".so"sv;
static constexpr auto blockSize = 4096;
@@ -172,6 +173,13 @@ std::string makeBindMdName() {
return name;
}
+
+static bool checkReadLogsDisabledMarker(std::string_view root) {
+ const auto markerPath = path::c_str(path::join(root, constants().readLogsDisabledMarkerName));
+ struct stat st;
+ return (::stat(markerPath, &st) == 0);
+}
+
} // namespace
IncrementalService::IncFsMount::~IncFsMount() {
@@ -618,6 +626,32 @@ StorageId IncrementalService::findStorageId(std::string_view path) const {
return it->second->second.storage;
}
+void IncrementalService::disableReadLogs(StorageId storageId) {
+ std::unique_lock l(mLock);
+ const auto ifs = getIfsLocked(storageId);
+ if (!ifs) {
+ LOG(ERROR) << "disableReadLogs failed, invalid storageId: " << storageId;
+ return;
+ }
+ if (!ifs->readLogsEnabled()) {
+ return;
+ }
+ ifs->disableReadLogs();
+ l.unlock();
+
+ const auto metadata = constants().readLogsDisabledMarkerName;
+ if (auto err = mIncFs->makeFile(ifs->control,
+ path::join(ifs->root, constants().mount,
+ constants().readLogsDisabledMarkerName),
+ 0777, idFromMetadata(metadata), {})) {
+ //{.metadata = {metadata.data(), (IncFsSize)metadata.size()}})) {
+ LOG(ERROR) << "Failed to make marker file for storageId: " << storageId;
+ return;
+ }
+
+ setStorageParams(storageId, /*enableReadLogs=*/false);
+}
+
int IncrementalService::setStorageParams(StorageId storageId, bool enableReadLogs) {
const auto ifs = getIfs(storageId);
if (!ifs) {
@@ -627,6 +661,11 @@ int IncrementalService::setStorageParams(StorageId storageId, bool enableReadLog
const auto& params = ifs->dataLoaderStub->params();
if (enableReadLogs) {
+ if (!ifs->readLogsEnabled()) {
+ LOG(ERROR) << "setStorageParams failed, readlogs disabled for storageId: " << storageId;
+ return -EPERM;
+ }
+
if (auto status = mAppOpsManager->checkPermission(kDataUsageStats, kOpUsage,
params.packageName.c_str());
!status.isOk()) {
@@ -1072,6 +1111,11 @@ std::unordered_set<std::string_view> IncrementalService::adoptMountedInstances()
std::move(control), *this);
cleanupFiles.release(); // ifs will take care of that now
+ // Check if marker file present.
+ if (checkReadLogsDisabledMarker(root)) {
+ ifs->disableReadLogs();
+ }
+
std::vector<std::pair<std::string, metadata::BindPoint>> permanentBindPoints;
auto d = openDir(root);
while (auto e = ::readdir(d.get())) {
@@ -1243,6 +1287,11 @@ bool IncrementalService::mountExistingImage(std::string_view root) {
ifs->mountId = mount.storage().id();
mNextId = std::max(mNextId, ifs->mountId + 1);
+ // Check if marker file present.
+ if (checkReadLogsDisabledMarker(mountTarget)) {
+ ifs->disableReadLogs();
+ }
+
// DataLoader params
DataLoaderParamsParcel dataLoaderParams;
{
diff --git a/services/incremental/IncrementalService.h b/services/incremental/IncrementalService.h
index 918531b7921c..a6cc94639c8a 100644
--- a/services/incremental/IncrementalService.h
+++ b/services/incremental/IncrementalService.h
@@ -94,6 +94,10 @@ public:
Permanent = 1,
};
+ enum StorageFlags {
+ ReadLogsEnabled = 1,
+ };
+
static FileId idFromMetadata(std::span<const uint8_t> metadata);
static inline FileId idFromMetadata(std::span<const char> metadata) {
return idFromMetadata({(const uint8_t*)metadata.data(), metadata.size()});
@@ -116,6 +120,7 @@ public:
int unbind(StorageId storage, std::string_view target);
void deleteStorage(StorageId storage);
+ void disableReadLogs(StorageId storage);
int setStorageParams(StorageId storage, bool enableReadLogs);
int makeFile(StorageId storage, std::string_view path, int mode, FileId id,
@@ -264,6 +269,7 @@ private:
const std::string root;
Control control;
/*const*/ MountId mountId;
+ int32_t flags = StorageFlags::ReadLogsEnabled;
StorageMap storages;
BindMap bindPoints;
DataLoaderStubPtr dataLoaderStub;
@@ -282,6 +288,9 @@ private:
StorageMap::iterator makeStorage(StorageId id);
+ void disableReadLogs() { flags &= ~StorageFlags::ReadLogsEnabled; }
+ int32_t readLogsEnabled() const { return (flags & StorageFlags::ReadLogsEnabled); }
+
static void cleanupFilesystem(std::string_view root);
};
diff --git a/services/incremental/test/IncrementalServiceTest.cpp b/services/incremental/test/IncrementalServiceTest.cpp
index 26b5094a795a..1ae9e256c9f4 100644
--- a/services/incremental/test/IncrementalServiceTest.cpp
+++ b/services/incremental/test/IncrementalServiceTest.cpp
@@ -929,6 +929,34 @@ TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccess) {
ASSERT_GE(mDataLoader->setStorageParams(true), 0);
}
+TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndDisabled) {
+ mVold->mountIncFsSuccess();
+ mIncFs->makeFileSuccess();
+ mVold->bindMountSuccess();
+ mVold->setIncFsMountOptionsSuccess();
+ mDataLoaderManager->bindToDataLoaderSuccess();
+ mDataLoaderManager->getDataLoaderSuccess();
+ mAppOpsManager->checkPermissionSuccess();
+ EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
+ EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
+ // Enabling and then disabling readlogs.
+ EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(1);
+ EXPECT_CALL(*mVold, setIncFsMountOptions(_, false)).Times(1);
+ // After setIncFsMountOptions succeeded expecting to start watching.
+ EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(1);
+ // Not expecting callback removal.
+ EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
+ TemporaryDir tempDir;
+ int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
+ IncrementalService::CreateOptions::CreateNew,
+ {}, {}, {});
+ ASSERT_GE(storageId, 0);
+ ASSERT_GE(mDataLoader->setStorageParams(true), 0);
+ // Now disable.
+ mIncrementalService->disableReadLogs(storageId);
+ ASSERT_EQ(mDataLoader->setStorageParams(true), -EPERM);
+}
+
TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndPermissionChanged) {
mVold->mountIncFsSuccess();
mIncFs->makeFileSuccess();
diff --git a/services/java/com/android/server/SystemConfigService.java b/services/java/com/android/server/SystemConfigService.java
index e8ab10124ef8..1801f3bca30e 100644
--- a/services/java/com/android/server/SystemConfigService.java
+++ b/services/java/com/android/server/SystemConfigService.java
@@ -15,6 +15,9 @@
*/
package com.android.server;
+import static java.util.stream.Collectors.toList;
+import static java.util.stream.Collectors.toMap;
+
import android.Manifest;
import android.content.Context;
import android.os.ISystemConfig;
@@ -46,6 +49,19 @@ public class SystemConfigService extends SystemService {
"getDisabledUntilUsedPreInstalledCarrierAssociatedApps requires"
+ " READ_CARRIER_APP_INFO");
return SystemConfig.getInstance()
+ .getDisabledUntilUsedPreinstalledCarrierAssociatedApps().entrySet().stream()
+ .collect(toMap(
+ Map.Entry::getKey,
+ e -> e.getValue().stream().map(app -> app.packageName)
+ .collect(toList())));
+ }
+
+ @Override
+ public Map getDisabledUntilUsedPreinstalledCarrierAssociatedAppEntries() {
+ mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_CARRIER_APP_INFO,
+ "getDisabledUntilUsedPreInstalledCarrierAssociatedAppEntries requires"
+ + " READ_CARRIER_APP_INFO");
+ return SystemConfig.getInstance()
.getDisabledUntilUsedPreinstalledCarrierAssociatedApps();
}
};
diff --git a/services/net/java/android/net/ip/IpClientCallbacks.java b/services/net/java/android/net/ip/IpClientCallbacks.java
index b172c4be7b0d..b17fcaa132a1 100644
--- a/services/net/java/android/net/ip/IpClientCallbacks.java
+++ b/services/net/java/android/net/ip/IpClientCallbacks.java
@@ -68,12 +68,13 @@ public class IpClientCallbacks {
*/
public void onNewDhcpResults(DhcpResultsParcelable dhcpResults) {
// In general callbacks would not use a parcelable directly (DhcpResultsParcelable), and
- // would use a wrapper instead. But there are already two classes in the tree for DHCP
- // information: DhcpInfo and DhcpResults, and each of them do not expose an appropriate API
- // (they are bags of mutable fields and can't be changed because they are public API and
- // @UnsupportedAppUsage). Adding a third class would cost more than the gain considering
- // that the only client of this callback is WiFi, which will end up converting the results
- // to DhcpInfo anyway.
+ // would use a wrapper instead, because of the lack of safety of stable parcelables. But
+ // there are already two classes in the tree for DHCP information: DhcpInfo and DhcpResults,
+ // and neither of them exposes an appropriate API (they are bags of mutable fields and can't
+ // be changed because they are public API and @UnsupportedAppUsage, being no better than the
+ // stable parcelable). Adding a third class would cost more than the gain considering that
+ // the only client of this callback is WiFi, which will end up converting the results to
+ // DhcpInfo anyway.
}
/**
diff --git a/services/tests/PackageManagerServiceTests/host/Android.bp b/services/tests/PackageManagerServiceTests/host/Android.bp
index dad001b52b15..41dfade1a09a 100644
--- a/services/tests/PackageManagerServiceTests/host/Android.bp
+++ b/services/tests/PackageManagerServiceTests/host/Android.bp
@@ -28,6 +28,14 @@ java_test_host {
":PackageManagerDummyAppVersion1",
":PackageManagerDummyAppVersion2",
":PackageManagerDummyAppVersion3",
+ ":PackageManagerDummyAppVersion4",
":PackageManagerDummyAppOriginalOverride",
+ ":PackageManagerServiceHostTestsResources",
]
}
+
+filegroup {
+ name: "PackageManagerServiceHostTestsResources",
+ srcs: [ "resources/*" ],
+ path: "resources/"
+}
diff --git a/services/tests/PackageManagerServiceTests/host/resources/PackageManagerDummyAppVersion3Invalid.apk b/services/tests/PackageManagerServiceTests/host/resources/PackageManagerDummyAppVersion3Invalid.apk
new file mode 100644
index 000000000000..127886cf8e9e
--- /dev/null
+++ b/services/tests/PackageManagerServiceTests/host/resources/PackageManagerDummyAppVersion3Invalid.apk
Binary files differ
diff --git a/services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/HostUtils.kt b/services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/HostUtils.kt
index 4927c45550b5..490f96d8f426 100644
--- a/services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/HostUtils.kt
+++ b/services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/HostUtils.kt
@@ -19,6 +19,7 @@ package com.android.server.pm.test
import com.android.internal.util.test.SystemPreparer
import com.android.tradefed.device.ITestDevice
import java.io.File
+import java.io.FileOutputStream
internal fun SystemPreparer.pushApk(file: String, partition: Partition) =
pushResourceFile(file, HostUtils.makePathForApk(file, partition))
@@ -43,4 +44,13 @@ internal object HostUtils {
.resolve(file.nameWithoutExtension)
.resolve(file.name)
.toString()
+
+ fun copyResourceToHostFile(javaResourceName: String, file: File): File {
+ javaClass.classLoader!!.getResource(javaResourceName).openStream().use { input ->
+ FileOutputStream(file).use { output ->
+ input.copyTo(output)
+ }
+ }
+ return file
+ }
}
diff --git a/services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/InvalidNewSystemAppTest.kt b/services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/InvalidNewSystemAppTest.kt
new file mode 100644
index 000000000000..98e045d0a203
--- /dev/null
+++ b/services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/InvalidNewSystemAppTest.kt
@@ -0,0 +1,83 @@
+/*
+ * 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
+
+import com.android.internal.util.test.SystemPreparer
+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
+
+@RunWith(DeviceJUnit4ClassRunner::class)
+class InvalidNewSystemAppTest : BaseHostJUnit4Test() {
+
+ companion object {
+ private const val TEST_PKG_NAME = "com.android.server.pm.test.dummy_app"
+ private const val VERSION_ONE = "PackageManagerDummyAppVersion1.apk"
+ private const val VERSION_TWO = "PackageManagerDummyAppVersion2.apk"
+ private const val VERSION_THREE_INVALID = "PackageManagerDummyAppVersion3Invalid.apk"
+ private const val VERSION_FOUR = "PackageManagerDummyAppVersion4.apk"
+
+ @get:ClassRule
+ val deviceRebootRule = SystemPreparer.TestRuleDelegate(true)
+ }
+
+ private val tempFolder = TemporaryFolder()
+ private val preparer: SystemPreparer = SystemPreparer(tempFolder,
+ SystemPreparer.RebootStrategy.START_STOP, deviceRebootRule) { this.device }
+
+ @get:Rule
+ val rules = RuleChain.outerRule(tempFolder).around(preparer)!!
+
+ @Before
+ @After
+ fun uninstallDataPackage() {
+ device.uninstallPackage(TEST_PKG_NAME)
+ }
+
+ @Test
+ fun verify() {
+ // First, push a system app to the device and then update it so there's a data variant
+ val filePath = HostUtils.makePathForApk("PackageManagerDummyApp.apk", Partition.PRODUCT)
+
+ preparer.pushResourceFile(VERSION_ONE, filePath)
+ .reboot()
+
+ val versionTwoFile = HostUtils.copyResourceToHostFile(VERSION_TWO, tempFolder.newFile())
+
+ assertThat(device.installPackage(versionTwoFile, true)).isNull()
+
+ // Then push a bad update to the system, overwriting the existing file as if an OTA occurred
+ preparer.deleteFile(filePath)
+ .pushResourceFile(VERSION_THREE_INVALID, filePath)
+ .reboot()
+
+ // This will remove the package from the device, which is expected
+ assertThat(device.getAppPackageInfo(TEST_PKG_NAME)).isNull()
+
+ // Then check that a user would still be able to install the application manually
+ val versionFourFile = HostUtils.copyResourceToHostFile(VERSION_FOUR, tempFolder.newFile())
+ assertThat(device.installPackage(versionFourFile, true)).isNull()
+ }
+}
diff --git a/services/tests/PackageManagerServiceTests/host/test-apps/Android.bp b/services/tests/PackageManagerServiceTests/host/test-apps/Android.bp
index 9568faa7dfd0..c9b29275a731 100644
--- a/services/tests/PackageManagerServiceTests/host/test-apps/Android.bp
+++ b/services/tests/PackageManagerServiceTests/host/test-apps/Android.bp
@@ -28,6 +28,11 @@ android_test_helper_app {
}
android_test_helper_app {
+ name: "PackageManagerDummyAppVersion4",
+ manifest: "AndroidManifestVersion4.xml"
+}
+
+android_test_helper_app {
name: "PackageManagerDummyAppOriginalOverride",
manifest: "AndroidManifestOriginalOverride.xml"
}
diff --git a/services/tests/PackageManagerServiceTests/host/test-apps/AndroidManifestVersion1.xml b/services/tests/PackageManagerServiceTests/host/test-apps/AndroidManifestVersion1.xml
index d772050d7fd0..b492a31349fc 100644
--- a/services/tests/PackageManagerServiceTests/host/test-apps/AndroidManifestVersion1.xml
+++ b/services/tests/PackageManagerServiceTests/host/test-apps/AndroidManifestVersion1.xml
@@ -18,4 +18,11 @@
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.server.pm.test.dummy_app"
android:versionCode="1"
- />
+ >
+
+ <permission
+ android:name="com.android.server.pm.test.dummy_app.TEST_PERMISSION"
+ android:protectionLevel="normal"
+ />
+
+</manifest>
diff --git a/services/tests/PackageManagerServiceTests/host/test-apps/AndroidManifestVersion2.xml b/services/tests/PackageManagerServiceTests/host/test-apps/AndroidManifestVersion2.xml
index 53f836b222e6..25e9f8eb2a67 100644
--- a/services/tests/PackageManagerServiceTests/host/test-apps/AndroidManifestVersion2.xml
+++ b/services/tests/PackageManagerServiceTests/host/test-apps/AndroidManifestVersion2.xml
@@ -18,4 +18,11 @@
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.server.pm.test.dummy_app"
android:versionCode="2"
- />
+ >
+
+ <permission
+ android:name="com.android.server.pm.test.dummy_app.TEST_PERMISSION"
+ android:protectionLevel="normal"
+ />
+
+</manifest>
diff --git a/services/tests/PackageManagerServiceTests/host/test-apps/AndroidManifestVersion3.xml b/services/tests/PackageManagerServiceTests/host/test-apps/AndroidManifestVersion3.xml
index 90ca9d0ac02c..935f5e62f508 100644
--- a/services/tests/PackageManagerServiceTests/host/test-apps/AndroidManifestVersion3.xml
+++ b/services/tests/PackageManagerServiceTests/host/test-apps/AndroidManifestVersion3.xml
@@ -18,4 +18,11 @@
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.server.pm.test.dummy_app"
android:versionCode="3"
- />
+ >
+
+ <permission
+ android:name="com.android.server.pm.test.dummy_app.TEST_PERMISSION"
+ android:protectionLevel="normal"
+ />
+
+</manifest>
diff --git a/services/tests/PackageManagerServiceTests/host/test-apps/AndroidManifestVersion4.xml b/services/tests/PackageManagerServiceTests/host/test-apps/AndroidManifestVersion4.xml
new file mode 100644
index 000000000000..d0643cbb2aeb
--- /dev/null
+++ b/services/tests/PackageManagerServiceTests/host/test-apps/AndroidManifestVersion4.xml
@@ -0,0 +1,28 @@
+<?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.dummy_app"
+ android:versionCode="4"
+ >
+
+ <permission
+ android:name="com.android.server.pm.test.dummy_app.TEST_PERMISSION"
+ android:protectionLevel="normal"
+ />
+
+</manifest>
diff --git a/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsServiceTest.java
index de6f55ba1053..0a61c443e0bd 100644
--- a/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsServiceTest.java
@@ -169,12 +169,13 @@ public class AppOpsServiceTest {
mAppOpsService.setMode(OP_WRITE_SMS, mMyUid, sMyPackageName, MODE_ERRORED);
// Note an op that's allowed.
- mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, sMyPackageName, null, false, null);
+ mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, sMyPackageName, null, false, null, false);
List<PackageOps> loggedOps = getLoggedOps();
assertContainsOp(loggedOps, OP_READ_SMS, mTestStartMillis, -1, MODE_ALLOWED);
// Note another op that's not allowed.
- mAppOpsService.noteOperation(OP_WRITE_SMS, mMyUid, sMyPackageName, null, false, null);
+ mAppOpsService.noteOperation(OP_WRITE_SMS, mMyUid, sMyPackageName, null, false, null,
+ false);
loggedOps = getLoggedOps();
assertContainsOp(loggedOps, OP_READ_SMS, mTestStartMillis, -1, MODE_ALLOWED);
assertContainsOp(loggedOps, OP_WRITE_SMS, -1, mTestStartMillis, MODE_ERRORED);
@@ -191,7 +192,7 @@ public class AppOpsServiceTest {
mAppOpsService.setMode(OP_COARSE_LOCATION, mMyUid, sMyPackageName, MODE_ALLOWED);
assertThat(mAppOpsService.noteOperation(OP_WIFI_SCAN, mMyUid, sMyPackageName, null, false,
- null)).isEqualTo(MODE_ALLOWED);
+ null, false)).isEqualTo(MODE_ALLOWED);
assertContainsOp(getLoggedOps(), OP_WIFI_SCAN, mTestStartMillis, -1,
MODE_ALLOWED /* default for WIFI_SCAN; this is not changed or used in this test */);
@@ -199,7 +200,7 @@ public class AppOpsServiceTest {
// Now set COARSE_LOCATION to ERRORED -> this will make WIFI_SCAN disabled as well.
mAppOpsService.setMode(OP_COARSE_LOCATION, mMyUid, sMyPackageName, MODE_ERRORED);
assertThat(mAppOpsService.noteOperation(OP_WIFI_SCAN, mMyUid, sMyPackageName, null, false,
- null)).isEqualTo(MODE_ERRORED);
+ null, false)).isEqualTo(MODE_ERRORED);
assertContainsOp(getLoggedOps(), OP_WIFI_SCAN, mTestStartMillis, mTestStartMillis,
MODE_ALLOWED /* default for WIFI_SCAN; this is not changed or used in this test */);
@@ -210,8 +211,9 @@ public class AppOpsServiceTest {
public void testStatePersistence() {
mAppOpsService.setMode(OP_READ_SMS, mMyUid, sMyPackageName, MODE_ALLOWED);
mAppOpsService.setMode(OP_WRITE_SMS, mMyUid, sMyPackageName, MODE_ERRORED);
- mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, sMyPackageName, null, false, null);
- mAppOpsService.noteOperation(OP_WRITE_SMS, mMyUid, sMyPackageName, null, false, null);
+ mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, sMyPackageName, null, false, null, false);
+ mAppOpsService.noteOperation(OP_WRITE_SMS, mMyUid, sMyPackageName, null, false, null,
+ false);
mAppOpsService.writeState();
// Create a new app ops service, and initialize its state from XML.
@@ -228,7 +230,7 @@ public class AppOpsServiceTest {
@Test
public void testShutdown() {
mAppOpsService.setMode(OP_READ_SMS, mMyUid, sMyPackageName, MODE_ALLOWED);
- mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, sMyPackageName, null, false, null);
+ mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, sMyPackageName, null, false, null, false);
mAppOpsService.shutdown();
// Create a new app ops service, and initialize its state from XML.
@@ -243,7 +245,7 @@ public class AppOpsServiceTest {
@Test
public void testGetOpsForPackage() {
mAppOpsService.setMode(OP_READ_SMS, mMyUid, sMyPackageName, MODE_ALLOWED);
- mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, sMyPackageName, null, false, null);
+ mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, sMyPackageName, null, false, null, false);
// Query all ops
List<PackageOps> loggedOps = mAppOpsService.getOpsForPackage(
@@ -272,7 +274,7 @@ public class AppOpsServiceTest {
@Test
public void testPackageRemoved() {
mAppOpsService.setMode(OP_READ_SMS, mMyUid, sMyPackageName, MODE_ALLOWED);
- mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, sMyPackageName, null, false, null);
+ mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, sMyPackageName, null, false, null, false);
List<PackageOps> loggedOps = getLoggedOps();
assertContainsOp(loggedOps, OP_READ_SMS, mTestStartMillis, -1, MODE_ALLOWED);
@@ -287,7 +289,7 @@ public class AppOpsServiceTest {
@Test
public void testPackageRemovedHistoricalOps() throws InterruptedException {
mAppOpsService.setMode(OP_READ_SMS, mMyUid, sMyPackageName, MODE_ALLOWED);
- mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, sMyPackageName, null, false, null);
+ mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, sMyPackageName, null, false, null, false);
AppOpsManager.HistoricalOps historicalOps = new AppOpsManager.HistoricalOps(0, 15000);
historicalOps.increaseAccessCount(OP_READ_SMS, mMyUid, sMyPackageName, null,
@@ -327,7 +329,7 @@ public class AppOpsServiceTest {
@Test
public void testUidRemoved() {
mAppOpsService.setMode(OP_READ_SMS, mMyUid, sMyPackageName, MODE_ALLOWED);
- mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, sMyPackageName, null, false, null);
+ mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, sMyPackageName, null, false, null, false);
List<PackageOps> loggedOps = getLoggedOps();
assertContainsOp(loggedOps, OP_READ_SMS, mTestStartMillis, -1, MODE_ALLOWED);
@@ -351,12 +353,12 @@ public class AppOpsServiceTest {
mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY,
ActivityManager.PROCESS_CAPABILITY_NONE);
assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName, null,
- false, null)).isNotEqualTo(MODE_ALLOWED);
+ false, null, false)).isNotEqualTo(MODE_ALLOWED);
mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_TOP,
ActivityManager.PROCESS_CAPABILITY_FOREGROUND_LOCATION);
assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName, null,
- false, null)).isEqualTo(MODE_ALLOWED);
+ false, null, false)).isEqualTo(MODE_ALLOWED);
mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY,
ActivityManager.PROCESS_CAPABILITY_NONE);
@@ -365,7 +367,7 @@ public class AppOpsServiceTest {
mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY,
ActivityManager.PROCESS_CAPABILITY_NONE);
assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName, null,
- false, null)).isNotEqualTo(MODE_ALLOWED);
+ false, null, false)).isNotEqualTo(MODE_ALLOWED);
}
@Test
@@ -374,12 +376,12 @@ public class AppOpsServiceTest {
mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY,
ActivityManager.PROCESS_CAPABILITY_NONE);
assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName, null,
- false, null)).isNotEqualTo(MODE_ALLOWED);
+ false, null, false)).isNotEqualTo(MODE_ALLOWED);
mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE,
ActivityManager.PROCESS_CAPABILITY_NONE);
assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName, null,
- false, null)).isNotEqualTo(MODE_ALLOWED);
+ false, null, false)).isNotEqualTo(MODE_ALLOWED);
}
@Test
@@ -389,12 +391,12 @@ public class AppOpsServiceTest {
mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY,
ActivityManager.PROCESS_CAPABILITY_NONE);
assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName, null,
- false, null)).isNotEqualTo(MODE_ALLOWED);
+ false, null, false)).isNotEqualTo(MODE_ALLOWED);
mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE,
ActivityManager.PROCESS_CAPABILITY_FOREGROUND_LOCATION);
assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName, null,
- false, null)).isEqualTo(MODE_ALLOWED);
+ false, null, false)).isEqualTo(MODE_ALLOWED);
}
@Test
@@ -404,12 +406,12 @@ public class AppOpsServiceTest {
mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY,
ActivityManager.PROCESS_CAPABILITY_NONE);
assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName, null,
- false, null)).isNotEqualTo(MODE_ALLOWED);
+ false, null, false)).isNotEqualTo(MODE_ALLOWED);
mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_TOP,
ActivityManager.PROCESS_CAPABILITY_FOREGROUND_LOCATION);
assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName, null,
- false, null)).isEqualTo(MODE_ALLOWED);
+ false, null, false)).isEqualTo(MODE_ALLOWED);
mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE,
ActivityManager.PROCESS_CAPABILITY_NONE);
@@ -418,7 +420,7 @@ public class AppOpsServiceTest {
mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE,
ActivityManager.PROCESS_CAPABILITY_NONE);
assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName, null,
- false, null)).isNotEqualTo(MODE_ALLOWED);
+ false, null, false)).isNotEqualTo(MODE_ALLOWED);
}
@Test
@@ -428,12 +430,12 @@ public class AppOpsServiceTest {
mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY,
ActivityManager.PROCESS_CAPABILITY_NONE);
assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName, null,
- false, null)).isNotEqualTo(MODE_ALLOWED);
+ false, null, false)).isNotEqualTo(MODE_ALLOWED);
mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_TOP,
ActivityManager.PROCESS_CAPABILITY_FOREGROUND_LOCATION);
assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName, null,
- false, null)).isEqualTo(MODE_ALLOWED);
+ false, null, false)).isEqualTo(MODE_ALLOWED);
mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE,
ActivityManager.PROCESS_CAPABILITY_FOREGROUND_LOCATION);
@@ -442,7 +444,7 @@ public class AppOpsServiceTest {
mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE,
ActivityManager.PROCESS_CAPABILITY_FOREGROUND_LOCATION);
assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName, null,
- false, null)).isEqualTo(MODE_ALLOWED);
+ false, null, false)).isEqualTo(MODE_ALLOWED);
mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE,
ActivityManager.PROCESS_CAPABILITY_NONE);
@@ -451,7 +453,7 @@ public class AppOpsServiceTest {
mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE,
ActivityManager.PROCESS_CAPABILITY_NONE);
assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName, null,
- false, null)).isNotEqualTo(MODE_ALLOWED);
+ false, null, false)).isNotEqualTo(MODE_ALLOWED);
}
private List<PackageOps> getLoggedOps() {
diff --git a/services/tests/servicestests/AndroidManifest.xml b/services/tests/servicestests/AndroidManifest.xml
index 3b38d948b121..6db3233b0266 100644
--- a/services/tests/servicestests/AndroidManifest.xml
+++ b/services/tests/servicestests/AndroidManifest.xml
@@ -80,6 +80,7 @@
<uses-permission android:name="android.permission.WRITE_DREAM_STATE"/>
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
<uses-permission android:name="android.permission.MODIFY_DAY_NIGHT_MODE"/>
+ <uses-permission android:name="android.permission.MEDIA_RESOURCE_OVERRIDE_PID"/>
<!-- Uses API introduced in O (26) -->
<uses-sdk android:minSdkVersion="1"
diff --git a/services/tests/servicestests/assets/AppIntegrityManagerServiceImplTest/SourceStampTestApk.apk b/services/tests/servicestests/assets/AppIntegrityManagerServiceImplTest/SourceStampTestApk.apk
index 211e064399a8..bd871ae7488c 100644
--- a/services/tests/servicestests/assets/AppIntegrityManagerServiceImplTest/SourceStampTestApk.apk
+++ b/services/tests/servicestests/assets/AppIntegrityManagerServiceImplTest/SourceStampTestApk.apk
Binary files differ
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java
index 6fe259e7fc85..6a797f31fa55 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java
@@ -506,7 +506,7 @@ public class ActivityManagerServiceTest {
@Test
public void testDispatchUids_dispatchNeededChanges() throws RemoteException {
when(mAppOpsService.noteOperation(AppOpsManager.OP_GET_USAGE_STATS, Process.myUid(), null,
- null, false, null)).thenReturn(AppOpsManager.MODE_ALLOWED);
+ null, false, null, false)).thenReturn(AppOpsManager.MODE_ALLOWED);
final int[] changesToObserve = {
ActivityManager.UID_OBSERVER_PROCSTATE,
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java
new file mode 100644
index 000000000000..b88573ae168a
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java
@@ -0,0 +1,133 @@
+/*
+ * 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.hdmi;
+
+import static com.android.server.hdmi.Constants.ADDR_PLAYBACK_1;
+import static com.android.server.hdmi.Constants.ADDR_TV;
+import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_ENABLE_CEC;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.hardware.hdmi.HdmiControlManager;
+import android.hardware.tv.cec.V1_0.SendMessageResult;
+import android.os.Handler;
+import android.os.IPowerManager;
+import android.os.IThermalService;
+import android.os.Looper;
+import android.os.PowerManager;
+import android.os.test.TestLooper;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.ArrayList;
+
+@SmallTest
+@RunWith(JUnit4.class)
+/** Tests for {@link HdmiCecLocalDeviceTv} class. */
+public class HdmiCecLocalDeviceTvTest {
+
+ private HdmiControlService mHdmiControlService;
+ private HdmiCecController mHdmiCecController;
+ private HdmiCecLocalDeviceTv mHdmiCecLocalDeviceTv;
+ private FakeNativeWrapper mNativeWrapper;
+ private Looper mMyLooper;
+ private TestLooper mTestLooper = new TestLooper();
+ private ArrayList<HdmiCecLocalDevice> mLocalDevices = new ArrayList<>();
+ private int mTvPhysicalAddress;
+
+ @Mock
+ private IPowerManager mIPowerManagerMock;
+ @Mock
+ private IThermalService mIThermalServiceMock;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+
+ Context context = InstrumentationRegistry.getTargetContext();
+ mMyLooper = mTestLooper.getLooper();
+ PowerManager powerManager = new PowerManager(context, mIPowerManagerMock,
+ mIThermalServiceMock, new Handler(mMyLooper));
+ mHdmiControlService =
+ new HdmiControlService(InstrumentationRegistry.getTargetContext()) {
+ @Override
+ boolean isControlEnabled() {
+ return true;
+ }
+
+ @Override
+ boolean isTvDevice() {
+ return true;
+ }
+
+ @Override
+ void writeStringSystemProperty(String key, String value) {
+ // do nothing
+ }
+
+ @Override
+ PowerManager getPowerManager() {
+ return powerManager;
+ }
+ };
+
+ mHdmiCecLocalDeviceTv = new HdmiCecLocalDeviceTv(mHdmiControlService);
+ mHdmiCecLocalDeviceTv.init();
+ mHdmiControlService.setIoLooper(mMyLooper);
+ mNativeWrapper = new FakeNativeWrapper();
+ mHdmiCecController =
+ HdmiCecController.createWithNativeWrapper(mHdmiControlService, mNativeWrapper);
+ mHdmiControlService.setCecController(mHdmiCecController);
+ mHdmiControlService.setHdmiMhlController(HdmiMhlControllerStub.create(mHdmiControlService));
+ mHdmiControlService.setMessageValidator(new HdmiCecMessageValidator(mHdmiControlService));
+ mLocalDevices.add(mHdmiCecLocalDeviceTv);
+ mHdmiControlService.initPortInfo();
+ mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
+ mTvPhysicalAddress = 0x0000;
+ mNativeWrapper.setPhysicalAddress(mTvPhysicalAddress);
+ mTestLooper.dispatchAll();
+ mNativeWrapper.clearResultMessages();
+ }
+
+ @Test
+ public void initialPowerStateIsStandby() {
+ assertThat(mHdmiCecLocalDeviceTv.getPowerStatus()).isEqualTo(
+ HdmiControlManager.POWER_STATUS_STANDBY);
+ }
+
+ @Test
+ public void onAddressAllocated_invokesDeviceDiscovery() {
+ mNativeWrapper.setPollAddressResponse(ADDR_PLAYBACK_1, SendMessageResult.SUCCESS);
+ mHdmiCecLocalDeviceTv.onAddressAllocated(0, HdmiControlService.INITIATED_BY_BOOT_UP);
+
+ mTestLooper.dispatchAll();
+
+ // Check for for <Give Physical Address> being sent to available device (ADDR_PLAYBACK_1).
+ // This message is sent as part of the DeviceDiscoveryAction to available devices.
+ HdmiCecMessage givePhysicalAddress = HdmiCecMessageBuilder.buildGivePhysicalAddress(ADDR_TV,
+ ADDR_PLAYBACK_1);
+ assertThat(mNativeWrapper.getResultMessages()).contains(givePhysicalAddress);
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java
index c34b8e19a41d..ac44ccea2106 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java
@@ -264,6 +264,19 @@ public class HdmiControlServiceTest {
}
@Test
+ public void disableAndReenableCec_volumeControlReturnsToOriginalValue() {
+ boolean volumeControlEnabled = true;
+ mHdmiControlService.setHdmiCecVolumeControlEnabled(volumeControlEnabled);
+
+ mHdmiControlService.setControlEnabled(false);
+ assertThat(mHdmiControlService.isHdmiCecVolumeControlEnabled()).isFalse();
+
+ mHdmiControlService.setControlEnabled(true);
+ assertThat(mHdmiControlService.isHdmiCecVolumeControlEnabled()).isEqualTo(
+ volumeControlEnabled);
+ }
+
+ @Test
public void addHdmiCecVolumeControlFeatureListener_emitsCurrentState_enabled() {
mHdmiControlService.setHdmiCecVolumeControlEnabled(true);
VolumeControlFeatureCallback callback = new VolumeControlFeatureCallback();
diff --git a/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java b/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java
index f205fde88c0d..26230949cda6 100644
--- a/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java
@@ -23,6 +23,7 @@ import static org.hamcrest.Matchers.empty;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -32,6 +33,7 @@ import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageParser;
import android.content.pm.Signature;
+import android.content.pm.UserInfo;
import android.content.pm.parsing.ParsingPackage;
import android.content.pm.parsing.component.ParsedActivity;
import android.content.pm.parsing.component.ParsedInstrumentation;
@@ -39,9 +41,11 @@ import android.content.pm.parsing.component.ParsedIntentInfo;
import android.content.pm.parsing.component.ParsedProvider;
import android.os.Build;
import android.os.Process;
+import android.os.UserHandle;
import android.platform.test.annotations.Presubmit;
import android.util.ArrayMap;
import android.util.ArraySet;
+import android.util.SparseArray;
import androidx.annotation.NonNull;
@@ -57,26 +61,36 @@ import org.junit.runners.JUnit4;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
+import org.mockito.stubbing.Answer;
import java.security.cert.CertificateException;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.function.IntFunction;
+import java.util.stream.Collectors;
@Presubmit
@RunWith(JUnit4.class)
public class AppsFilterTest {
- private static final int DUMMY_CALLING_UID = 10345;
- private static final int DUMMY_TARGET_UID = 10556;
- private static final int DUMMY_ACTOR_UID = 10656;
- private static final int DUMMY_OVERLAY_UID = 10756;
- private static final int DUMMY_ACTOR_TWO_UID = 10856;
+ private static final int DUMMY_CALLING_APPID = 10345;
+ private static final int DUMMY_TARGET_APPID = 10556;
+ private static final int DUMMY_ACTOR_APPID = 10656;
+ private static final int DUMMY_OVERLAY_APPID = 10756;
+ private static final int SYSTEM_USER = 0;
+ private static final int SECONDARY_USER = 10;
+ private static final int[] USER_ARRAY = {SYSTEM_USER, SECONDARY_USER};
+ private static final UserInfo[] USER_INFO_LIST = Arrays.stream(USER_ARRAY).mapToObj(
+ id -> new UserInfo(id, Integer.toString(id), 0)).toArray(UserInfo[]::new);
@Mock
AppsFilter.FeatureConfig mFeatureConfigMock;
+ @Mock
+ AppsFilter.StateProvider mStateProvider;
private ArrayMap<String, PackageSetting> mExisting = new ArrayMap<>();
@@ -170,15 +184,24 @@ public class AppsFilterTest {
mExisting = new ArrayMap<>();
MockitoAnnotations.initMocks(this);
+ doAnswer(invocation -> {
+ ((AppsFilter.StateProvider.CurrentStateCallback) invocation.getArgument(0))
+ .currentState(mExisting, USER_INFO_LIST);
+ return null;
+ }).when(mStateProvider)
+ .runWithState(any(AppsFilter.StateProvider.CurrentStateCallback.class));
+
when(mFeatureConfigMock.isGloballyEnabled()).thenReturn(true);
- when(mFeatureConfigMock.packageIsEnabled(any(AndroidPackage.class)))
- .thenReturn(true);
+ when(mFeatureConfigMock.packageIsEnabled(any(AndroidPackage.class))).thenAnswer(
+ (Answer<Boolean>) invocation ->
+ ((AndroidPackage)invocation.getArgument(SYSTEM_USER)).getTargetSdkVersion()
+ >= Build.VERSION_CODES.R);
}
@Test
public void testSystemReadyPropogates() throws Exception {
final AppsFilter appsFilter =
- new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
+ new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
appsFilter.onSystemReady();
verify(mFeatureConfigMock).onSystemReady();
}
@@ -186,22 +209,23 @@ public class AppsFilterTest {
@Test
public void testQueriesAction_FilterMatches() throws Exception {
final AppsFilter appsFilter =
- new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
+ new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
PackageSetting target = simulateAddPackage(appsFilter,
- pkg("com.some.package", new IntentFilter("TEST_ACTION")), DUMMY_TARGET_UID);
+ pkg("com.some.package", new IntentFilter("TEST_ACTION")), DUMMY_TARGET_APPID);
PackageSetting calling = simulateAddPackage(appsFilter,
- pkg("com.some.other.package", new Intent("TEST_ACTION")), DUMMY_CALLING_UID);
+ pkg("com.some.other.package", new Intent("TEST_ACTION")), DUMMY_CALLING_APPID);
- assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
+ assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
+ SYSTEM_USER));
}
@Test
public void testQueriesProtectedAction_FilterDoesNotMatch() throws Exception {
final AppsFilter appsFilter =
- new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
+ new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
final Signature frameworkSignature = Mockito.mock(Signature.class);
final PackageParser.SigningDetails frameworkSigningDetails =
new PackageParser.SigningDetails(new Signature[]{frameworkSignature}, 1);
@@ -211,164 +235,174 @@ public class AppsFilterTest {
b -> b.setSigningDetails(frameworkSigningDetails));
appsFilter.onSystemReady();
- final int activityUid = DUMMY_TARGET_UID;
+ final int activityUid = DUMMY_TARGET_APPID;
PackageSetting targetActivity = simulateAddPackage(appsFilter,
pkg("com.target.activity", new IntentFilter("TEST_ACTION")), activityUid);
- final int receiverUid = DUMMY_TARGET_UID + 1;
+ final int receiverUid = DUMMY_TARGET_APPID + 1;
PackageSetting targetReceiver = simulateAddPackage(appsFilter,
pkgWithReceiver("com.target.receiver", new IntentFilter("TEST_ACTION")),
receiverUid);
- final int callingUid = DUMMY_CALLING_UID;
+ final int callingUid = DUMMY_CALLING_APPID;
PackageSetting calling = simulateAddPackage(appsFilter,
pkg("com.calling.action", new Intent("TEST_ACTION")), callingUid);
- final int wildcardUid = DUMMY_CALLING_UID + 1;
+ final int wildcardUid = DUMMY_CALLING_APPID + 1;
PackageSetting callingWildCard = simulateAddPackage(appsFilter,
pkg("com.calling.wildcard", new Intent("*")), wildcardUid);
- assertFalse(appsFilter.shouldFilterApplication(callingUid, calling, targetActivity, 0));
- assertTrue(appsFilter.shouldFilterApplication(callingUid, calling, targetReceiver, 0));
+ assertFalse(appsFilter.shouldFilterApplication(callingUid, calling, targetActivity,
+ SYSTEM_USER));
+ assertTrue(appsFilter.shouldFilterApplication(callingUid, calling, targetReceiver,
+ SYSTEM_USER));
assertFalse(appsFilter.shouldFilterApplication(
- wildcardUid, callingWildCard, targetActivity, 0));
+ wildcardUid, callingWildCard, targetActivity, SYSTEM_USER));
assertTrue(appsFilter.shouldFilterApplication(
- wildcardUid, callingWildCard, targetReceiver, 0));
+ wildcardUid, callingWildCard, targetReceiver, SYSTEM_USER));
}
@Test
public void testQueriesProvider_FilterMatches() throws Exception {
final AppsFilter appsFilter =
- new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
+ new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
PackageSetting target = simulateAddPackage(appsFilter,
- pkgWithProvider("com.some.package", "com.some.authority"), DUMMY_TARGET_UID);
+ pkgWithProvider("com.some.package", "com.some.authority"), DUMMY_TARGET_APPID);
PackageSetting calling = simulateAddPackage(appsFilter,
pkgQueriesProvider("com.some.other.package", "com.some.authority"),
- DUMMY_CALLING_UID);
+ DUMMY_CALLING_APPID);
- assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
+ assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
+ SYSTEM_USER));
}
@Test
public void testQueriesDifferentProvider_Filters() throws Exception {
final AppsFilter appsFilter =
- new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
+ new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
PackageSetting target = simulateAddPackage(appsFilter,
- pkgWithProvider("com.some.package", "com.some.authority"), DUMMY_TARGET_UID);
+ pkgWithProvider("com.some.package", "com.some.authority"), DUMMY_TARGET_APPID);
PackageSetting calling = simulateAddPackage(appsFilter,
pkgQueriesProvider("com.some.other.package", "com.some.other.authority"),
- DUMMY_CALLING_UID);
+ DUMMY_CALLING_APPID);
- assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
+ assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
+ SYSTEM_USER));
}
@Test
public void testQueriesProviderWithSemiColon_FilterMatches() throws Exception {
final AppsFilter appsFilter =
- new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
+ new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
PackageSetting target = simulateAddPackage(appsFilter,
pkgWithProvider("com.some.package", "com.some.authority;com.some.other.authority"),
- DUMMY_TARGET_UID);
+ DUMMY_TARGET_APPID);
PackageSetting calling = simulateAddPackage(appsFilter,
pkgQueriesProvider("com.some.other.package", "com.some.authority"),
- DUMMY_CALLING_UID);
+ DUMMY_CALLING_APPID);
- assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
+ assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
+ SYSTEM_USER));
}
@Test
public void testQueriesAction_NoMatchingAction_Filters() throws Exception {
final AppsFilter appsFilter =
- new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
+ new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
PackageSetting target = simulateAddPackage(appsFilter,
- pkg("com.some.package"), DUMMY_TARGET_UID);
+ pkg("com.some.package"), DUMMY_TARGET_APPID);
PackageSetting calling = simulateAddPackage(appsFilter,
- pkg("com.some.other.package", new Intent("TEST_ACTION")), DUMMY_CALLING_UID);
+ pkg("com.some.other.package", new Intent("TEST_ACTION")), DUMMY_CALLING_APPID);
- assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
+ assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
+ SYSTEM_USER));
}
@Test
public void testQueriesAction_NoMatchingActionFilterLowSdk_DoesntFilter() throws Exception {
final AppsFilter appsFilter =
- new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
+ new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
PackageSetting target = simulateAddPackage(appsFilter,
- pkg("com.some.package"), DUMMY_TARGET_UID);
- PackageSetting calling = simulateAddPackage(appsFilter,
- pkg("com.some.other.package",
- new Intent("TEST_ACTION"))
- .setTargetSdkVersion(Build.VERSION_CODES.P),
- DUMMY_CALLING_UID);
+ pkg("com.some.package"), DUMMY_TARGET_APPID);
+ ParsingPackage callingPkg = pkg("com.some.other.package",
+ new Intent("TEST_ACTION"))
+ .setTargetSdkVersion(Build.VERSION_CODES.P);
+ PackageSetting calling = simulateAddPackage(appsFilter, callingPkg,
+ DUMMY_CALLING_APPID);
- when(mFeatureConfigMock.packageIsEnabled(calling.pkg)).thenReturn(false);
- assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
+ assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
+ SYSTEM_USER));
}
@Test
public void testNoQueries_Filters() throws Exception {
final AppsFilter appsFilter =
- new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
+ new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
PackageSetting target = simulateAddPackage(appsFilter,
- pkg("com.some.package"), DUMMY_TARGET_UID);
+ pkg("com.some.package"), DUMMY_TARGET_APPID);
PackageSetting calling = simulateAddPackage(appsFilter,
- pkg("com.some.other.package"), DUMMY_CALLING_UID);
+ pkg("com.some.other.package"), DUMMY_CALLING_APPID);
- assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
+ assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
+ SYSTEM_USER));
}
@Test
public void testForceQueryable_DoesntFilter() throws Exception {
final AppsFilter appsFilter =
- new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
+ new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
PackageSetting target = simulateAddPackage(appsFilter,
- pkg("com.some.package").setForceQueryable(true), DUMMY_TARGET_UID);
+ pkg("com.some.package").setForceQueryable(true), DUMMY_TARGET_APPID);
PackageSetting calling = simulateAddPackage(appsFilter,
- pkg("com.some.other.package"), DUMMY_CALLING_UID);
+ pkg("com.some.other.package"), DUMMY_CALLING_APPID);
- assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
+ assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
+ SYSTEM_USER));
}
@Test
public void testForceQueryableByDevice_SystemCaller_DoesntFilter() throws Exception {
final AppsFilter appsFilter =
- new AppsFilter(mFeatureConfigMock, new String[]{"com.some.package"}, false, null);
+ new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{"com.some.package"},
+ false, null);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
PackageSetting target = simulateAddPackage(appsFilter,
- pkg("com.some.package"), DUMMY_TARGET_UID,
+ pkg("com.some.package"), DUMMY_TARGET_APPID,
setting -> setting.setPkgFlags(ApplicationInfo.FLAG_SYSTEM));
PackageSetting calling = simulateAddPackage(appsFilter,
- pkg("com.some.other.package"), DUMMY_CALLING_UID);
+ pkg("com.some.other.package"), DUMMY_CALLING_APPID);
- assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
+ assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
+ SYSTEM_USER));
}
@Test
public void testSystemSignedTarget_DoesntFilter() throws CertificateException {
final AppsFilter appsFilter =
- new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
+ new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
appsFilter.onSystemReady();
final Signature frameworkSignature = Mockito.mock(Signature.class);
@@ -382,62 +416,67 @@ public class AppsFilterTest {
simulateAddPackage(appsFilter, pkg("android"), 1000,
b -> b.setSigningDetails(frameworkSigningDetails));
PackageSetting target = simulateAddPackage(appsFilter, pkg("com.some.package"),
- DUMMY_TARGET_UID,
+ DUMMY_TARGET_APPID,
b -> b.setSigningDetails(frameworkSigningDetails)
.setPkgFlags(ApplicationInfo.FLAG_SYSTEM));
PackageSetting calling = simulateAddPackage(appsFilter,
- pkg("com.some.other.package"), DUMMY_CALLING_UID,
+ pkg("com.some.other.package"), DUMMY_CALLING_APPID,
b -> b.setSigningDetails(otherSigningDetails));
- assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
+ assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
+ SYSTEM_USER));
}
@Test
public void testForceQueryableByDevice_NonSystemCaller_Filters() throws Exception {
final AppsFilter appsFilter =
- new AppsFilter(mFeatureConfigMock, new String[]{"com.some.package"}, false, null);
+ new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{"com.some.package"},
+ false, null);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
PackageSetting target = simulateAddPackage(appsFilter,
- pkg("com.some.package"), DUMMY_TARGET_UID);
+ pkg("com.some.package"), DUMMY_TARGET_APPID);
PackageSetting calling = simulateAddPackage(appsFilter,
- pkg("com.some.other.package"), DUMMY_CALLING_UID);
+ pkg("com.some.other.package"), DUMMY_CALLING_APPID);
- assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
+ assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
+ SYSTEM_USER));
}
@Test
public void testSystemQueryable_DoesntFilter() throws Exception {
final AppsFilter appsFilter =
- new AppsFilter(mFeatureConfigMock, new String[]{},
+ new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{},
true /* system force queryable */, null);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
PackageSetting target = simulateAddPackage(appsFilter,
- pkg("com.some.package"), DUMMY_TARGET_UID,
+ pkg("com.some.package"), DUMMY_TARGET_APPID,
setting -> setting.setPkgFlags(ApplicationInfo.FLAG_SYSTEM));
PackageSetting calling = simulateAddPackage(appsFilter,
- pkg("com.some.other.package"), DUMMY_CALLING_UID);
+ pkg("com.some.other.package"), DUMMY_CALLING_APPID);
- assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
+ assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
+ SYSTEM_USER));
}
@Test
public void testQueriesPackage_DoesntFilter() throws Exception {
final AppsFilter appsFilter =
- new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
+ new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
PackageSetting target = simulateAddPackage(appsFilter,
- pkg("com.some.package"), DUMMY_TARGET_UID);
+ pkg("com.some.package"), DUMMY_TARGET_APPID);
PackageSetting calling = simulateAddPackage(appsFilter,
- pkg("com.some.other.package", "com.some.package"), DUMMY_CALLING_UID);
+ pkg("com.some.other.package", "com.some.package"), DUMMY_CALLING_APPID);
- assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
+ assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
+ SYSTEM_USER));
}
@Test
@@ -445,63 +484,83 @@ public class AppsFilterTest {
when(mFeatureConfigMock.packageIsEnabled(any(AndroidPackage.class)))
.thenReturn(false);
final AppsFilter appsFilter =
- new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
+ new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
PackageSetting target = simulateAddPackage(
- appsFilter, pkg("com.some.package"), DUMMY_TARGET_UID);
+ appsFilter, pkg("com.some.package"), DUMMY_TARGET_APPID);
PackageSetting calling = simulateAddPackage(
- appsFilter, pkg("com.some.other.package"), DUMMY_CALLING_UID);
+ appsFilter, pkg("com.some.other.package"), DUMMY_CALLING_APPID);
- assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
+ assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
+ SYSTEM_USER));
}
@Test
public void testSystemUid_DoesntFilter() throws Exception {
final AppsFilter appsFilter =
- new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
+ new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
PackageSetting target = simulateAddPackage(appsFilter,
- pkg("com.some.package"), DUMMY_TARGET_UID);
+ pkg("com.some.package"), DUMMY_TARGET_APPID);
- assertFalse(appsFilter.shouldFilterApplication(0, null, target, 0));
+ assertFalse(appsFilter.shouldFilterApplication(SYSTEM_USER, null, target, SYSTEM_USER));
assertFalse(appsFilter.shouldFilterApplication(Process.FIRST_APPLICATION_UID - 1,
- null, target, 0));
+ null, target, SYSTEM_USER));
+ }
+
+ @Test
+ public void testSystemUidSecondaryUser_DoesntFilter() throws Exception {
+ final AppsFilter appsFilter =
+ new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
+ simulateAddBasicAndroid(appsFilter);
+ appsFilter.onSystemReady();
+
+ PackageSetting target = simulateAddPackage(appsFilter,
+ pkg("com.some.package"), DUMMY_TARGET_APPID);
+
+ assertFalse(appsFilter.shouldFilterApplication(0, null, target, SECONDARY_USER));
+ assertFalse(appsFilter.shouldFilterApplication(
+ UserHandle.getUid(SECONDARY_USER, Process.FIRST_APPLICATION_UID - 1),
+ null, target, SECONDARY_USER));
}
@Test
public void testNonSystemUid_NoCallingSetting_Filters() throws Exception {
final AppsFilter appsFilter =
- new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
+ new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
PackageSetting target = simulateAddPackage(appsFilter,
- pkg("com.some.package"), DUMMY_TARGET_UID);
+ pkg("com.some.package"), DUMMY_TARGET_APPID);
- assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, null, target, 0));
+ assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, null, target,
+ SYSTEM_USER));
}
@Test
public void testNoTargetPackage_filters() throws Exception {
final AppsFilter appsFilter =
- new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
+ new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
PackageSetting target = new PackageSettingBuilder()
+ .setAppId(DUMMY_TARGET_APPID)
.setName("com.some.package")
.setCodePath("/")
.setResourcePath("/")
.setPVersionCode(1L)
.build();
PackageSetting calling = simulateAddPackage(appsFilter,
- pkg("com.some.other.package", new Intent("TEST_ACTION")), DUMMY_CALLING_UID);
+ pkg("com.some.other.package", new Intent("TEST_ACTION")), DUMMY_CALLING_APPID);
- assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
+ assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
+ SYSTEM_USER));
}
@Test
@@ -516,7 +575,11 @@ public class AppsFilterTest {
.setOverlayTargetName("overlayableName");
ParsingPackage actor = pkg("com.some.package.actor");
- final AppsFilter appsFilter = new AppsFilter(mFeatureConfigMock, new String[]{}, false,
+ final AppsFilter appsFilter = new AppsFilter(
+ mStateProvider,
+ mFeatureConfigMock,
+ new String[]{},
+ false,
new OverlayReferenceMapper.Provider() {
@Nullable
@Override
@@ -544,31 +607,34 @@ public class AppsFilterTest {
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
- PackageSetting targetSetting = simulateAddPackage(appsFilter, target, DUMMY_TARGET_UID);
- PackageSetting overlaySetting = simulateAddPackage(appsFilter, overlay, DUMMY_OVERLAY_UID);
- PackageSetting actorSetting = simulateAddPackage(appsFilter, actor, DUMMY_ACTOR_UID);
+ PackageSetting targetSetting = simulateAddPackage(appsFilter, target, DUMMY_TARGET_APPID);
+ PackageSetting overlaySetting =
+ simulateAddPackage(appsFilter, overlay, DUMMY_OVERLAY_APPID);
+ PackageSetting actorSetting = simulateAddPackage(appsFilter, actor, DUMMY_ACTOR_APPID);
// Actor can see both target and overlay
- assertFalse(appsFilter.shouldFilterApplication(DUMMY_ACTOR_UID, actorSetting,
- targetSetting, 0));
- assertFalse(appsFilter.shouldFilterApplication(DUMMY_ACTOR_UID, actorSetting,
- overlaySetting, 0));
+ assertFalse(appsFilter.shouldFilterApplication(DUMMY_ACTOR_APPID, actorSetting,
+ targetSetting, SYSTEM_USER));
+ assertFalse(appsFilter.shouldFilterApplication(DUMMY_ACTOR_APPID, actorSetting,
+ overlaySetting, SYSTEM_USER));
// But target/overlay can't see each other
- assertTrue(appsFilter.shouldFilterApplication(DUMMY_TARGET_UID, targetSetting,
- overlaySetting, 0));
- assertTrue(appsFilter.shouldFilterApplication(DUMMY_OVERLAY_UID, overlaySetting,
- targetSetting, 0));
+ assertTrue(appsFilter.shouldFilterApplication(DUMMY_TARGET_APPID, targetSetting,
+ overlaySetting, SYSTEM_USER));
+ assertTrue(appsFilter.shouldFilterApplication(DUMMY_OVERLAY_APPID, overlaySetting,
+ targetSetting, SYSTEM_USER));
// And can't see the actor
- assertTrue(appsFilter.shouldFilterApplication(DUMMY_TARGET_UID, targetSetting,
- actorSetting, 0));
- assertTrue(appsFilter.shouldFilterApplication(DUMMY_OVERLAY_UID, overlaySetting,
- actorSetting, 0));
+ assertTrue(appsFilter.shouldFilterApplication(DUMMY_TARGET_APPID, targetSetting,
+ actorSetting, SYSTEM_USER));
+ assertTrue(appsFilter.shouldFilterApplication(DUMMY_OVERLAY_APPID, overlaySetting,
+ actorSetting, SYSTEM_USER));
}
@Test
public void testActsOnTargetOfOverlayThroughSharedUser() throws Exception {
+// Debug.waitForDebugger();
+
final String actorName = "overlay://test/actorName";
ParsingPackage target = pkg("com.some.package.target")
@@ -580,7 +646,11 @@ public class AppsFilterTest {
ParsingPackage actorOne = pkg("com.some.package.actor.one");
ParsingPackage actorTwo = pkg("com.some.package.actor.two");
- final AppsFilter appsFilter = new AppsFilter(mFeatureConfigMock, new String[]{}, false,
+ final AppsFilter appsFilter = new AppsFilter(
+ mStateProvider,
+ mFeatureConfigMock,
+ new String[]{},
+ false,
new OverlayReferenceMapper.Provider() {
@Nullable
@Override
@@ -609,108 +679,114 @@ public class AppsFilterTest {
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
- PackageSetting targetSetting = simulateAddPackage(appsFilter, target, DUMMY_TARGET_UID);
- PackageSetting overlaySetting = simulateAddPackage(appsFilter, overlay, DUMMY_OVERLAY_UID);
- PackageSetting actorOneSetting = simulateAddPackage(appsFilter, actorOne, DUMMY_ACTOR_UID);
- PackageSetting actorTwoSetting = simulateAddPackage(appsFilter, actorTwo,
- DUMMY_ACTOR_TWO_UID);
-
+ PackageSetting targetSetting = simulateAddPackage(appsFilter, target, DUMMY_TARGET_APPID);
SharedUserSetting actorSharedSetting = new SharedUserSetting("actorSharedUser",
- actorOneSetting.pkgFlags, actorOneSetting.pkgPrivateFlags);
- actorSharedSetting.addPackage(actorOneSetting);
- actorSharedSetting.addPackage(actorTwoSetting);
+ targetSetting.pkgFlags, targetSetting.pkgPrivateFlags);
+ PackageSetting overlaySetting =
+ simulateAddPackage(appsFilter, overlay, DUMMY_OVERLAY_APPID);
+ simulateAddPackage(appsFilter, actorOne, DUMMY_ACTOR_APPID,
+ null /*settingBuilder*/, actorSharedSetting);
+ simulateAddPackage(appsFilter, actorTwo, DUMMY_ACTOR_APPID,
+ null /*settingBuilder*/, actorSharedSetting);
+
// actorTwo can see both target and overlay
- assertFalse(appsFilter.shouldFilterApplication(DUMMY_ACTOR_TWO_UID, actorSharedSetting,
- targetSetting, 0));
- assertFalse(appsFilter.shouldFilterApplication(DUMMY_ACTOR_TWO_UID, actorSharedSetting,
- overlaySetting, 0));
+ assertFalse(appsFilter.shouldFilterApplication(DUMMY_ACTOR_APPID, actorSharedSetting,
+ targetSetting, SYSTEM_USER));
+ assertFalse(appsFilter.shouldFilterApplication(DUMMY_ACTOR_APPID, actorSharedSetting,
+ overlaySetting, SYSTEM_USER));
}
@Test
public void testInitiatingApp_DoesntFilter() throws Exception {
final AppsFilter appsFilter =
- new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
+ new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
PackageSetting target = simulateAddPackage(appsFilter, pkg("com.some.package"),
- DUMMY_TARGET_UID);
+ DUMMY_TARGET_APPID);
PackageSetting calling = simulateAddPackage(appsFilter, pkg("com.some.other.package"),
- DUMMY_CALLING_UID, withInstallSource(target.name, null, null, false));
+ DUMMY_CALLING_APPID, withInstallSource(target.name, null, null, false));
- assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
+ assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
+ SYSTEM_USER));
}
@Test
public void testUninstalledInitiatingApp_Filters() throws Exception {
final AppsFilter appsFilter =
- new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
+ new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
PackageSetting target = simulateAddPackage(appsFilter, pkg("com.some.package"),
- DUMMY_TARGET_UID);
+ DUMMY_TARGET_APPID);
PackageSetting calling = simulateAddPackage(appsFilter, pkg("com.some.other.package"),
- DUMMY_CALLING_UID, withInstallSource(target.name, null, null, true));
+ DUMMY_CALLING_APPID, withInstallSource(target.name, null, null, true));
- assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
+ assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
+ SYSTEM_USER));
}
@Test
public void testOriginatingApp_Filters() throws Exception {
final AppsFilter appsFilter =
- new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
+ new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
PackageSetting target = simulateAddPackage(appsFilter, pkg("com.some.package"),
- DUMMY_TARGET_UID);
+ DUMMY_TARGET_APPID);
PackageSetting calling = simulateAddPackage(appsFilter, pkg("com.some.other.package"),
- DUMMY_CALLING_UID, withInstallSource(null, target.name, null, false));
+ DUMMY_CALLING_APPID, withInstallSource(null, target.name, null, false));
- assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
+ assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
+ SYSTEM_USER));
}
@Test
public void testInstallingApp_DoesntFilter() throws Exception {
final AppsFilter appsFilter =
- new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
+ new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
PackageSetting target = simulateAddPackage(appsFilter, pkg("com.some.package"),
- DUMMY_TARGET_UID);
+ DUMMY_TARGET_APPID);
PackageSetting calling = simulateAddPackage(appsFilter, pkg("com.some.other.package"),
- DUMMY_CALLING_UID, withInstallSource(null, null, target.name, false));
+ DUMMY_CALLING_APPID, withInstallSource(null, null, target.name, false));
- assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
+ assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
+ SYSTEM_USER));
}
@Test
public void testInstrumentation_DoesntFilter() throws Exception {
final AppsFilter appsFilter =
- new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
+ new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
PackageSetting target = simulateAddPackage(appsFilter, pkg("com.some.package"),
- DUMMY_TARGET_UID);
+ DUMMY_TARGET_APPID);
PackageSetting instrumentation = simulateAddPackage(appsFilter,
pkgWithInstrumentation("com.some.other.package", "com.some.package"),
- DUMMY_CALLING_UID);
+ DUMMY_CALLING_APPID);
assertFalse(
- appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, instrumentation, target, 0));
+ appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, instrumentation, target,
+ SYSTEM_USER));
assertFalse(
- appsFilter.shouldFilterApplication(DUMMY_TARGET_UID, target, instrumentation, 0));
+ appsFilter.shouldFilterApplication(DUMMY_TARGET_APPID, target, instrumentation,
+ SYSTEM_USER));
}
@Test
public void testWhoCanSee() throws Exception {
final AppsFilter appsFilter =
- new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
+ new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
@@ -718,6 +794,7 @@ public class AppsFilterTest {
final int seesNothingAppId = Process.FIRST_APPLICATION_UID;
final int hasProviderAppId = Process.FIRST_APPLICATION_UID + 1;
final int queriesProviderAppId = Process.FIRST_APPLICATION_UID + 2;
+
PackageSetting system = simulateAddPackage(appsFilter, pkg("some.system.pkg"), systemAppId);
PackageSetting seesNothing = simulateAddPackage(appsFilter, pkg("com.some.package"),
seesNothingAppId);
@@ -727,23 +804,26 @@ public class AppsFilterTest {
pkgQueriesProvider("com.yet.some.other.package", "com.some.authority"),
queriesProviderAppId);
- final int[] systemFilter =
- appsFilter.getVisibilityWhitelist(system, new int[]{0}, mExisting).get(0);
- assertThat(toList(systemFilter), empty());
+ final SparseArray<int[]> systemFilter =
+ appsFilter.getVisibilityWhitelist(system, USER_ARRAY, mExisting);
+ assertThat(toList(systemFilter.get(SYSTEM_USER)),
+ contains(seesNothingAppId, hasProviderAppId, queriesProviderAppId));
- final int[] seesNothingFilter =
- appsFilter.getVisibilityWhitelist(seesNothing, new int[]{0}, mExisting).get(0);
- assertThat(toList(seesNothingFilter),
+ final SparseArray<int[]> seesNothingFilter =
+ appsFilter.getVisibilityWhitelist(seesNothing, USER_ARRAY, mExisting);
+ assertThat(toList(seesNothingFilter.get(SYSTEM_USER)),
+ contains(seesNothingAppId));
+ assertThat(toList(seesNothingFilter.get(SECONDARY_USER)),
contains(seesNothingAppId));
- final int[] hasProviderFilter =
- appsFilter.getVisibilityWhitelist(hasProvider, new int[]{0}, mExisting).get(0);
- assertThat(toList(hasProviderFilter),
+ final SparseArray<int[]> hasProviderFilter =
+ appsFilter.getVisibilityWhitelist(hasProvider, USER_ARRAY, mExisting);
+ assertThat(toList(hasProviderFilter.get(SYSTEM_USER)),
contains(hasProviderAppId, queriesProviderAppId));
- int[] queriesProviderFilter =
- appsFilter.getVisibilityWhitelist(queriesProvider, new int[]{0}, mExisting).get(0);
- assertThat(toList(queriesProviderFilter),
+ SparseArray<int[]> queriesProviderFilter =
+ appsFilter.getVisibilityWhitelist(queriesProvider, USER_ARRAY, mExisting);
+ assertThat(toList(queriesProviderFilter.get(SYSTEM_USER)),
contains(queriesProviderAppId));
// provider read
@@ -751,8 +831,8 @@ public class AppsFilterTest {
// ensure implicit access is included in the filter
queriesProviderFilter =
- appsFilter.getVisibilityWhitelist(queriesProvider, new int[]{0}, mExisting).get(0);
- assertThat(toList(queriesProviderFilter),
+ appsFilter.getVisibilityWhitelist(queriesProvider, USER_ARRAY, mExisting);
+ assertThat(toList(queriesProviderFilter.get(SYSTEM_USER)),
contains(hasProviderAppId, queriesProviderAppId));
}
@@ -779,11 +859,17 @@ public class AppsFilterTest {
private PackageSetting simulateAddPackage(AppsFilter filter,
ParsingPackage newPkgBuilder, int appId) {
- return simulateAddPackage(filter, newPkgBuilder, appId, null);
+ return simulateAddPackage(filter, newPkgBuilder, appId, null /*settingBuilder*/);
}
private PackageSetting simulateAddPackage(AppsFilter filter,
ParsingPackage newPkgBuilder, int appId, @Nullable WithSettingBuilder action) {
+ return simulateAddPackage(filter, newPkgBuilder, appId, action, null /*sharedUserSetting*/);
+ }
+
+ private PackageSetting simulateAddPackage(AppsFilter filter,
+ ParsingPackage newPkgBuilder, int appId, @Nullable WithSettingBuilder action,
+ @Nullable SharedUserSetting sharedUserSetting) {
AndroidPackage newPkg = ((ParsedPackage) newPkgBuilder.hideAsParsed()).hideAsFinal();
final PackageSettingBuilder settingBuilder = new PackageSettingBuilder()
@@ -795,8 +881,12 @@ public class AppsFilterTest {
.setPVersionCode(1L);
final PackageSetting setting =
(action == null ? settingBuilder : action.withBuilder(settingBuilder)).build();
- filter.addPackage(setting, mExisting);
mExisting.put(newPkg.getPackageName(), setting);
+ if (sharedUserSetting != null) {
+ sharedUserSetting.addPackage(setting);
+ setting.sharedUser = sharedUserSetting;
+ }
+ filter.addPackage(setting);
return setting;
}
@@ -809,4 +899,3 @@ public class AppsFilterTest {
return setting -> setting.setInstallSource(installSource);
}
}
-
diff --git a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
index 2d45f9ea40c7..1a04d2ff8c29 100644
--- a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
@@ -213,7 +213,7 @@ public class AppStandbyControllerTests {
}
@Override
- boolean isNonIdleWhitelisted(String packageName) throws RemoteException {
+ boolean isNonIdleWhitelisted(String packageName) {
return mNonIdleWhitelistApps.contains(packageName);
}
@@ -516,7 +516,7 @@ public class AppStandbyControllerTests {
UsageEvents.Event ev = new UsageEvents.Event();
ev.mPackage = packageName;
ev.mEventType = eventType;
- controller.reportEvent(ev, elapsedTime, USER_ID);
+ controller.reportEvent(ev, USER_ID);
}
private int getStandbyBucket(AppStandbyController controller, String packageName) {
diff --git a/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java
index 3062584aee20..b100c8482bf8 100644
--- a/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java
@@ -31,9 +31,10 @@ import android.os.PowerManager;
import android.os.PowerManagerInternal;
import android.os.PowerSaveState;
import android.os.RemoteException;
-import android.provider.Settings;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
+
+import com.android.server.twilight.TwilightListener;
import com.android.server.twilight.TwilightManager;
import com.android.server.twilight.TwilightState;
import com.android.server.wm.WindowManagerInternal;
@@ -55,7 +56,6 @@ import static junit.framework.TestCase.assertFalse;
import static junit.framework.TestCase.assertTrue;
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
@@ -65,6 +65,7 @@ import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -100,6 +101,7 @@ public class UiModeManagerServiceTest extends UiServiceTestCase {
private BroadcastReceiver mTimeChangedCallback;
private AlarmManager.OnAlarmListener mCustomListener;
private Consumer<PowerSaveState> mPowerSaveConsumer;
+ private TwilightListener mTwilightListener;
@Before
public void setUp() {
@@ -107,6 +109,10 @@ public class UiModeManagerServiceTest extends UiServiceTestCase {
when(mContext.checkCallingOrSelfPermission(anyString()))
.thenReturn(PackageManager.PERMISSION_GRANTED);
doAnswer(inv -> {
+ mTwilightListener = (TwilightListener) inv.getArgument(0);
+ return null;
+ }).when(mTwilightManager).registerListener(any(), any());
+ doAnswer(inv -> {
mPowerSaveConsumer = (Consumer<PowerSaveState>) inv.getArgument(1);
return null;
}).when(mLocalPowerManager).registerLowPowerModeObserver(anyInt(), any());
@@ -160,6 +166,37 @@ public class UiModeManagerServiceTest extends UiServiceTestCase {
}
@Test
+ public void setNightMoveActivated_overridesFunctionCorrectly() throws RemoteException {
+ // set up
+ when(mPowerManager.isInteractive()).thenReturn(false);
+ mService.setNightMode(MODE_NIGHT_NO);
+ assertFalse(mUiManagerService.getConfiguration().isNightModeActive());
+
+ // assume it is day time
+ doReturn(false).when(mTwilightState).isNight();
+
+ // set mode to auto
+ mService.setNightMode(MODE_NIGHT_AUTO);
+
+ // set night mode on overriding current config
+ mService.setNightModeActivated(true);
+
+ assertTrue(mUiManagerService.getConfiguration().isNightModeActive());
+
+ // now it is night time
+ doReturn(true).when(mTwilightState).isNight();
+ mTwilightListener.onTwilightStateChanged(mTwilightState);
+
+ assertTrue(mUiManagerService.getConfiguration().isNightModeActive());
+
+ // now it is next day mid day
+ doReturn(false).when(mTwilightState).isNight();
+ mTwilightListener.onTwilightStateChanged(mTwilightState);
+
+ assertFalse(mUiManagerService.getConfiguration().isNightModeActive());
+ }
+
+ @Test
public void setAutoMode_screenOffRegistered() throws RemoteException {
try {
mService.setNightMode(MODE_NIGHT_NO);
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/BadgeExtractorTest.java b/services/tests/uiservicestests/src/com/android/server/notification/BadgeExtractorTest.java
index c9c31bfcde08..36ac5d5a111d 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/BadgeExtractorTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/BadgeExtractorTest.java
@@ -32,7 +32,7 @@ import android.app.NotificationChannel;
import android.app.PendingIntent;
import android.content.Intent;
import android.graphics.drawable.Icon;
-
+import android.media.session.MediaSession;
import android.os.UserHandle;
import android.service.notification.StatusBarNotification;
import android.test.suitebuilder.annotation.SmallTest;
@@ -114,6 +114,31 @@ public class BadgeExtractorTest extends UiServiceTestCase {
return r;
}
+ private NotificationRecord getNotificationRecordWithMedia(boolean excludeSession) {
+ NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_UNSPECIFIED);
+ channel.setShowBadge(/* showBadge */ true);
+ when(mConfig.getNotificationChannel(mPkg, mUid, "a", false)).thenReturn(channel);
+
+ Notification.MediaStyle style = new Notification.MediaStyle();
+ if (!excludeSession) {
+ MediaSession session = new MediaSession(getContext(), "BadgeExtractorTestSession");
+ style.setMediaSession(session.getSessionToken());
+ }
+
+ final Builder builder = new Builder(getContext())
+ .setContentTitle("foo")
+ .setSmallIcon(android.R.drawable.sym_def_app_icon)
+ .setPriority(Notification.PRIORITY_HIGH)
+ .setDefaults(Notification.DEFAULT_SOUND)
+ .setStyle(style);
+
+ Notification n = builder.build();
+ StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, mId, mTag, mUid,
+ mPid, n, mUser, null, System.currentTimeMillis());
+ NotificationRecord r = new NotificationRecord(getContext(), sbn, channel);
+ return r;
+ }
+
//
// Tests
//
@@ -203,6 +228,66 @@ public class BadgeExtractorTest extends UiServiceTestCase {
}
@Test
+ public void testHideMediaNotifOverridesYes() throws Exception {
+ BadgeExtractor extractor = new BadgeExtractor();
+ extractor.setConfig(mConfig);
+ when(mConfig.badgingEnabled(mUser)).thenReturn(true);
+ when(mConfig.canShowBadge(mPkg, mUid)).thenReturn(true);
+
+ when(mConfig.isMediaNotificationFilteringEnabled()).thenReturn(true);
+ NotificationRecord r = getNotificationRecordWithMedia(/* excludeSession */ false);
+
+ extractor.process(r);
+
+ assertFalse(r.canShowBadge());
+ }
+
+ @Test
+ public void testHideMediaNotifDisabledOverridesNo() throws Exception {
+ BadgeExtractor extractor = new BadgeExtractor();
+ extractor.setConfig(mConfig);
+ when(mConfig.badgingEnabled(mUser)).thenReturn(true);
+ when(mConfig.canShowBadge(mPkg, mUid)).thenReturn(true);
+
+ when(mConfig.isMediaNotificationFilteringEnabled()).thenReturn(false);
+ NotificationRecord r = getNotificationRecordWithMedia(/* excludeSession */ false);
+
+ extractor.process(r);
+
+ assertTrue(r.canShowBadge());
+ }
+
+ @Test
+ public void testHideMediaNotifNoSessionOverridesNo() throws Exception {
+ BadgeExtractor extractor = new BadgeExtractor();
+ extractor.setConfig(mConfig);
+ when(mConfig.badgingEnabled(mUser)).thenReturn(true);
+ when(mConfig.canShowBadge(mPkg, mUid)).thenReturn(true);
+
+ when(mConfig.isMediaNotificationFilteringEnabled()).thenReturn(true);
+ NotificationRecord r = getNotificationRecordWithMedia(/* excludeSession */ true);
+
+ extractor.process(r);
+
+ assertTrue(r.canShowBadge());
+ }
+
+ @Test
+ public void testHideMediaNotifNotMediaStyleOverridesNo() throws Exception {
+ BadgeExtractor extractor = new BadgeExtractor();
+ extractor.setConfig(mConfig);
+ when(mConfig.badgingEnabled(mUser)).thenReturn(true);
+ when(mConfig.canShowBadge(mPkg, mUid)).thenReturn(true);
+
+ when(mConfig.isMediaNotificationFilteringEnabled()).thenReturn(true);
+ NotificationRecord r = getNotificationRecord(true, IMPORTANCE_UNSPECIFIED);
+
+ extractor.process(r);
+
+ assertTrue(r.canShowBadge());
+ }
+
+ @Test
public void testDndOverridesYes() {
BadgeExtractor extractor = new BadgeExtractor();
extractor.setConfig(mConfig);
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationChannelLoggerFake.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationChannelLoggerFake.java
index b6ea063ccc14..f609306e44b0 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationChannelLoggerFake.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationChannelLoggerFake.java
@@ -51,4 +51,9 @@ public class NotificationChannelLoggerFake implements NotificationChannelLogger
NotificationChannelGroup channelGroup, int uid, String pkg, boolean wasBlocked) {
mCalls.add(new CallRecord(event));
}
+
+ @Override
+ public void logAppEvent(NotificationChannelEvent event, int uid, String pkg) {
+ mCalls.add(new CallRecord(event));
+ }
}
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 6991c18ceb82..a2d987fb0a8d 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryDatabaseTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryDatabaseTest.java
@@ -149,7 +149,7 @@ public class NotificationHistoryDatabaseTest extends UiServiceTestCase {
}
@Test
- public void testPrune_badFileName() {
+ public void testPrune_badFileName_noCrash() {
GregorianCalendar cal = new GregorianCalendar();
cal.setTimeInMillis(10);
int retainDays = 1;
@@ -159,7 +159,7 @@ public class NotificationHistoryDatabaseTest extends UiServiceTestCase {
// add 5 files with a creation date of "today", but the file names are bad
for (long i = cal.getTimeInMillis(); i >= 5; i--) {
File file = mock(File.class);
- when(file.getName()).thenReturn(i + ".txt");
+ when(file.getName()).thenReturn(i + ".bak");
AtomicFile af = new AtomicFile(file);
mDataBase.mHistoryFiles.addLast(af);
}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
index 622a203c5242..5b0a7fb9d413 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
@@ -2088,6 +2088,22 @@ public class PreferencesHelperTest extends UiServiceTestCase {
}
@Test
+ public void testShowQSMediaOverrideTrue() {
+ Global.putInt(getContext().getContentResolver(),
+ Global.SHOW_MEDIA_ON_QUICK_SETTINGS, 1);
+ mHelper.updateMediaNotificationFilteringEnabled(); // would be called by settings observer
+ assertTrue(mHelper.isMediaNotificationFilteringEnabled());
+ }
+
+ @Test
+ public void testShowQSMediaOverrideFalse() {
+ Global.putInt(getContext().getContentResolver(),
+ Global.SHOW_MEDIA_ON_QUICK_SETTINGS, 0);
+ mHelper.updateMediaNotificationFilteringEnabled(); // would be called by settings observer
+ assertFalse(mHelper.isMediaNotificationFilteringEnabled());
+ }
+
+ @Test
public void testOnLocaleChanged_updatesDefaultChannels() throws Exception {
String newLabel = "bananas!";
final NotificationChannel defaultChannel = mHelper.getNotificationChannel(PKG_N_MR1,
@@ -2266,6 +2282,14 @@ public class PreferencesHelperTest extends UiServiceTestCase {
}
@Test
+ public void testAppBlockedLogging() {
+ mHelper.setEnabled(PKG_N_MR1, 1020, false);
+ assertEquals(1, mLogger.getCalls().size());
+ assertEquals(
+ NotificationChannelLogger.NotificationChannelEvent.APP_NOTIFICATIONS_BLOCKED,
+ mLogger.get(0).event);
+ }
+ @Test
public void testXml_statusBarIcons_default() throws Exception {
String preQXml = "<ranking version=\"1\">\n"
+ "<package name=\"" + PKG_N_MR1 + "\" show_badge=\"true\">\n"
diff --git a/services/tests/uiservicestests/src/com/android/server/slice/SliceClientPermissionsTest.java b/services/tests/uiservicestests/src/com/android/server/slice/SliceClientPermissionsTest.java
index ff2236d25e28..4f092b91220f 100644
--- a/services/tests/uiservicestests/src/com/android/server/slice/SliceClientPermissionsTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/slice/SliceClientPermissionsTest.java
@@ -227,6 +227,23 @@ public class SliceClientPermissionsTest extends UiServiceTestCase {
assertEquivalent(client, deser);
}
+ @Test(expected = XmlPullParserException.class)
+ public void testReadEmptyFile_ThrowException() throws XmlPullParserException, IOException {
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
+ XmlSerializer serializer = XmlPullParserFactory.newInstance().newSerializer();
+ serializer.setOutput(output, Encoding.UTF_8.name());
+ // create empty xml document
+ serializer.startDocument(null, true);
+ serializer.endDocument();
+ serializer.flush();
+
+ ByteArrayInputStream input = new ByteArrayInputStream(output.toByteArray());
+ XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser();
+ parser.setInput(input, Encoding.UTF_8.name());
+ SliceClientPermissions.createFrom(parser, mock(DirtyTracker.class));
+ // Should throw exception since the xml is empty
+ }
+
private void assertEquivalent(SliceClientPermissions o1, SliceClientPermissions o2) {
assertEquals(o1.getPkg(), o2.getPkg());
ArrayList<SliceAuthority> a1 = new ArrayList<>(o1.getAuthorities());
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index 4ee933a0a5a5..2171d75256f2 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -794,6 +794,39 @@ public class ActivityRecordTests extends ActivityTestsBase {
}
/**
+ * Verify that when top focused activity is on secondary display, when finishing the top focused
+ * activity on default display, the preferred top stack on default display should be changed by
+ * adjusting focus.
+ */
+ @Test
+ public void testFinishActivityIfPossible_PreferredTopStackChanged() {
+ final ActivityRecord topActivityOnNonTopDisplay =
+ createActivityOnDisplay(true /* defaultDisplay */, null /* process */);
+ ActivityStack topRootableTask = topActivityOnNonTopDisplay.getRootTask();
+ topRootableTask.moveToFront("test");
+ assertTrue(topRootableTask.isTopStackInDisplayArea());
+ assertEquals(topRootableTask, topActivityOnNonTopDisplay.getDisplayArea()
+ .mPreferredTopFocusableStack);
+
+ final ActivityRecord secondaryDisplayActivity =
+ createActivityOnDisplay(false /* defaultDisplay */, null /* process */);
+ topRootableTask = secondaryDisplayActivity.getRootTask();
+ topRootableTask.moveToFront("test");
+ assertTrue(topRootableTask.isTopStackInDisplayArea());
+ assertEquals(topRootableTask,
+ secondaryDisplayActivity.getDisplayArea().mPreferredTopFocusableStack);
+
+ // The global top focus activity is on secondary display now.
+ // Finish top activity on default display and verify the next preferred top focusable stack
+ // on default display has changed.
+ topActivityOnNonTopDisplay.setState(RESUMED, "test");
+ topActivityOnNonTopDisplay.finishIfPossible(0 /* resultCode */, null /* resultData */,
+ null /* resultGrants */, "test", false /* oomAdj */);
+ assertEquals(mTask, mStack.getTopMostTask());
+ assertEquals(mStack, mActivity.getDisplayArea().mPreferredTopFocusableStack);
+ }
+
+ /**
* Verify that resumed activity is paused due to finish request.
*/
@Test
@@ -1390,7 +1423,6 @@ public class ActivityRecordTests extends ActivityTestsBase {
@Test
public void testActivityOnCancelFixedRotationTransform() {
- mService.mWindowManager.mIsFixedRotationTransformEnabled = true;
final DisplayRotation displayRotation = mActivity.mDisplayContent.getDisplayRotation();
spyOn(displayRotation);
@@ -1447,7 +1479,6 @@ public class ActivityRecordTests extends ActivityTestsBase {
@Test
public void testIsSnapshotCompatible() {
- mService.mWindowManager.mIsFixedRotationTransformEnabled = true;
final TaskSnapshot snapshot = new TaskSnapshotPersisterTestBase.TaskSnapshotBuilder()
.setRotation(mActivity.getWindowConfiguration().getRotation())
.build();
@@ -1461,7 +1492,6 @@ public class ActivityRecordTests extends ActivityTestsBase {
@Test
public void testFixedRotationSnapshotStartingWindow() {
- mService.mWindowManager.mIsFixedRotationTransformEnabled = true;
// TaskSnapshotSurface requires a fullscreen opaque window.
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.TYPE_APPLICATION_STARTING);
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java
index ef28a450695b..4dbf79a4a5a6 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java
@@ -38,6 +38,7 @@ import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentat
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doCallRealMethod;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
+import static com.android.server.wm.WindowContainer.POSITION_TOP;
import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_AFTER_ANIM;
import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_BEFORE_ANIM;
import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_NONE;
@@ -452,6 +453,31 @@ public class AppWindowTokenTests extends WindowTestsBase {
assertFalse(middle.isVisible());
}
+ @Test
+ public void testTransferStartingWindowSetFixedRotation() {
+ final ActivityRecord topActivity = createTestActivityRecordForGivenTask(mTask);
+ mTask.positionChildAt(topActivity, POSITION_TOP);
+ mActivity.addStartingWindow(mPackageName,
+ android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
+ false);
+ waitUntilHandlersIdle();
+
+ // Make activities to have different rotation from it display and set fixed rotation
+ // transform to activity1.
+ int rotation = (mDisplayContent.getRotation() + 1) % 4;
+ mDisplayContent.setFixedRotationLaunchingApp(mActivity, rotation);
+ doReturn(rotation).when(mDisplayContent)
+ .rotationForActivityInDifferentOrientation(topActivity);
+
+ // Make sure the fixed rotation transform linked to activity2 when adding starting window
+ // on activity2.
+ topActivity.addStartingWindow(mPackageName,
+ android.R.style.Theme, null, "Test", 0, 0, 0, 0, mActivity.appToken.asBinder(),
+ false, false, false, true, false);
+ waitUntilHandlersIdle();
+ assertTrue(topActivity.hasFixedRotationTransform());
+ }
+
private ActivityRecord createIsolatedTestActivityRecord() {
final ActivityStack taskStack = createTaskStackOnDisplay(mDisplayContent);
final Task task = createTaskInStack(taskStack, 0 /* userId */);
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
index 4ad7dff87072..689674011d30 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -16,6 +16,7 @@
package com.android.server.wm;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
@@ -79,6 +80,7 @@ import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doCallRealMethod;
import android.annotation.SuppressLint;
import android.app.ActivityTaskManager;
@@ -1065,7 +1067,6 @@ public class DisplayContentTests extends WindowTestsBase {
@Test
public void testApplyTopFixedRotationTransform() {
- mWm.mIsFixedRotationTransformEnabled = true;
final DisplayPolicy displayPolicy = mDisplayContent.getDisplayPolicy();
// Only non-movable (gesture) navigation bar will be animated by fixed rotation animation.
doReturn(false).when(displayPolicy).navigationBarCanMove();
@@ -1134,8 +1135,6 @@ public class DisplayContentTests extends WindowTestsBase {
// Launch another activity before the transition is finished.
final ActivityRecord app2 = new ActivityTestsBase.StackBuilder(mWm.mRoot)
.setDisplay(mDisplayContent).build().getTopMostActivity();
- mDisplayContent.prepareAppTransition(WindowManager.TRANSIT_ACTIVITY_OPEN,
- false /* alwaysKeepCurrent */);
mDisplayContent.mOpeningApps.add(app2);
app2.setRequestedOrientation(newOrientation);
@@ -1144,7 +1143,14 @@ public class DisplayContentTests extends WindowTestsBase {
assertTrue(app.hasFixedRotationTransform(app2));
assertTrue(mDisplayContent.isFixedRotationLaunchingApp(app2));
+ // The fixed rotation transform can only be finished when all animation finished.
+ doReturn(false).when(app2).isAnimating(anyInt(), anyInt());
+ mDisplayContent.mAppTransition.notifyAppTransitionFinishedLocked(app2.token);
+ assertTrue(app.hasFixedRotationTransform());
+ assertTrue(app2.hasFixedRotationTransform());
+
// The display should be rotated after the launch is finished.
+ doReturn(false).when(app).isAnimating(anyInt(), anyInt());
mDisplayContent.mAppTransition.notifyAppTransitionFinishedLocked(app.token);
// The fixed rotation should be cleared and the new rotation is applied to display.
@@ -1155,6 +1161,29 @@ public class DisplayContentTests extends WindowTestsBase {
}
@Test
+ public void testFinishFixedRotationNoAppTransitioningTask() {
+ final ActivityRecord app = mAppWindow.mActivityRecord;
+ final Task task = app.getTask();
+ final ActivityRecord app2 = new ActivityTestsBase.ActivityBuilder(mWm.mAtmService)
+ .setTask(task).build();
+ mDisplayContent.setFixedRotationLaunchingApp(app2, (mDisplayContent.getRotation() + 1) % 4);
+ doReturn(true).when(task).isAppTransitioning();
+ // If the task is animating transition, this should be no-op.
+ mDisplayContent.mFixedRotationTransitionListener.onAppTransitionFinishedLocked(app.token);
+
+ assertTrue(app2.hasFixedRotationTransform());
+ assertTrue(mDisplayContent.hasTopFixedRotationLaunchingApp());
+
+ doReturn(false).when(task).isAppTransitioning();
+ // Although this notifies app instead of app2 that uses the fixed rotation, app2 should
+ // still finish the transform because there is no more transition event.
+ mDisplayContent.mFixedRotationTransitionListener.onAppTransitionFinishedLocked(app.token);
+
+ assertFalse(app2.hasFixedRotationTransform());
+ assertFalse(mDisplayContent.hasTopFixedRotationLaunchingApp());
+ }
+
+ @Test
public void testRotateSeamlesslyWithFixedRotation() {
final DisplayRotation displayRotation = mDisplayContent.getDisplayRotation();
final ActivityRecord app = mAppWindow.mActivityRecord;
@@ -1174,7 +1203,6 @@ public class DisplayContentTests extends WindowTestsBase {
@Test
public void testNoFixedRotationWithPip() {
- mWm.mIsFixedRotationTransformEnabled = true;
// Make resume-top really update the activity state.
doReturn(false).when(mWm.mAtmService).isBooting();
doReturn(true).when(mWm.mAtmService).isBooted();
@@ -1224,11 +1252,39 @@ public class DisplayContentTests extends WindowTestsBase {
}
@Test
+ public void testRecentsNotRotatingWithFixedRotation() {
+ final DisplayRotation displayRotation = mDisplayContent.getDisplayRotation();
+ doCallRealMethod().when(displayRotation).updateRotationUnchecked(anyBoolean());
+ // Skip freezing so the unrelated conditions in updateRotationUnchecked won't disturb.
+ doNothing().when(mWm).startFreezingDisplay(anyInt(), anyInt(), any(), anyInt());
+
+ final ActivityRecord recentsActivity = createActivityRecord(mDisplayContent,
+ WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_RECENTS);
+ recentsActivity.setRequestedOrientation(SCREEN_ORIENTATION_PORTRAIT);
+
+ // Do not rotate if the recents animation is animating on top.
+ mDisplayContent.mFixedRotationTransitionListener.onStartRecentsAnimation(recentsActivity);
+ displayRotation.setRotation((displayRotation.getRotation() + 1) % 4);
+ assertFalse(displayRotation.updateRotationUnchecked(false));
+
+ // Rotation can be updated if the recents animation is finished.
+ mDisplayContent.mFixedRotationTransitionListener.onFinishRecentsAnimation(false);
+ assertTrue(displayRotation.updateRotationUnchecked(false));
+
+ // Rotation can be updated if the recents animation is animating but it is not on top, e.g.
+ // switching activities in different orientations by quickstep gesture.
+ mDisplayContent.mFixedRotationTransitionListener.onStartRecentsAnimation(recentsActivity);
+ mDisplayContent.setFixedRotationLaunchingAppUnchecked(mAppWindow.mActivityRecord);
+ displayRotation.setRotation((displayRotation.getRotation() + 1) % 4);
+ assertTrue(displayRotation.updateRotationUnchecked(false));
+ }
+
+ @Test
public void testRemoteRotation() {
DisplayContent dc = createNewDisplay();
final DisplayRotation dr = dc.getDisplayRotation();
- Mockito.doCallRealMethod().when(dr).updateRotationUnchecked(anyBoolean());
+ doCallRealMethod().when(dr).updateRotationUnchecked(anyBoolean());
Mockito.doReturn(ROTATION_90).when(dr).rotationForOrientation(anyInt(), anyInt());
final boolean[] continued = new boolean[1];
// TODO(display-merge): Remove cast
@@ -1280,7 +1336,6 @@ public class DisplayContentTests extends WindowTestsBase {
public void testGetOrCreateRootHomeTask_supportedSecondaryDisplay() {
DisplayContent display = createNewDisplay();
doReturn(true).when(display).supportsSystemDecorations();
- doReturn(false).when(display).isUntrustedVirtualDisplay();
// Remove the current home stack if it exists so a new one can be created below.
TaskDisplayArea taskDisplayArea = display.getDefaultTaskDisplayArea();
@@ -1304,10 +1359,10 @@ public class DisplayContentTests extends WindowTestsBase {
}
@Test
- public void testGetOrCreateRootHomeTask_untrustedVirtualDisplay() {
+ public void testGetOrCreateRootHomeTask_untrustedDisplay() {
DisplayContent display = createNewDisplay();
TaskDisplayArea taskDisplayArea = display.getDefaultTaskDisplayArea();
- doReturn(true).when(display).isUntrustedVirtualDisplay();
+ doReturn(false).when(display).isTrusted();
assertNull(taskDisplayArea.getRootHomeTask());
assertNull(taskDisplayArea.getOrCreateRootHomeTask());
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
index 27c4e9ba8641..1922351ac1eb 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
@@ -57,6 +57,7 @@ import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.platform.test.annotations.Presubmit;
import android.util.Pair;
+import android.util.SparseArray;
import android.view.DisplayCutout;
import android.view.DisplayInfo;
import android.view.InsetsState;
@@ -776,15 +777,15 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
}
private void assertSimulateLayoutSameDisplayFrames() {
- final int uiMode = 0;
final String prefix = "";
final InsetsState simulatedInsetsState = new InsetsState();
final DisplayFrames simulatedDisplayFrames = createDisplayFrames();
- mDisplayPolicy.beginLayoutLw(mFrames, uiMode);
+ mDisplayPolicy.beginLayoutLw(mFrames, mDisplayContent.getConfiguration().uiMode);
// Force the display bounds because it is not synced with display frames in policy test.
mDisplayContent.getWindowConfiguration().setBounds(mFrames.mUnrestricted);
mDisplayContent.getInsetsStateController().onPostLayout();
- mDisplayPolicy.simulateLayoutDisplay(simulatedDisplayFrames, simulatedInsetsState, uiMode);
+ mDisplayPolicy.simulateLayoutDisplay(simulatedDisplayFrames, simulatedInsetsState,
+ new SparseArray<>() /* barContentFrames */);
final StringWriter realFramesDump = new StringWriter();
mFrames.dump(prefix, new PrintWriter(realFramesDump));
diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
index 2af98d85b1ca..0a27e1a1da68 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
@@ -30,7 +30,6 @@ import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
@@ -41,7 +40,6 @@ import static org.mockito.Mockito.verify;
import android.graphics.Rect;
import android.platform.test.annotations.Presubmit;
-import android.view.InsetsSource;
import android.view.InsetsSourceControl;
import android.view.InsetsState;
import android.view.test.InsetsModeSession;
@@ -87,10 +85,7 @@ public class InsetsStateControllerTest extends WindowTestsBase {
.setWindow(statusBar, null, null);
statusBar.setControllableInsetProvider(getController().getSourceProvider(ITYPE_STATUS_BAR));
final InsetsState state = getController().getInsetsForDispatch(statusBar);
- for (int i = state.getSourcesCount() - 1; i >= 0; i--) {
- final InsetsSource source = state.sourceAt(i);
- assertNotEquals(ITYPE_STATUS_BAR, source.getType());
- }
+ assertNull(state.peekSource(ITYPE_STATUS_BAR));
}
@Test
@@ -191,13 +186,23 @@ public class InsetsStateControllerTest extends WindowTestsBase {
@Test
public void testStripForDispatch_imeOrderChanged() {
- getController().getSourceProvider(ITYPE_IME).setWindow(mImeWindow, null, null);
+ // This can be the IME z-order target while app cannot be the IME z-order target.
+ // This is also the only IME control target in this test, so IME won't be invisible caused
+ // by the control-target change.
+ mDisplayContent.mInputMethodInputTarget = createWindow(null, TYPE_APPLICATION, "base");
- // This window can be the IME target while app cannot be the IME target.
- createWindow(null, TYPE_APPLICATION, "base");
+ // Make IME and stay visible during the test.
+ mImeWindow.setHasSurface(true);
+ getController().getSourceProvider(ITYPE_IME).setWindow(mImeWindow, null, null);
+ getController().onImeControlTargetChanged(mDisplayContent.mInputMethodInputTarget);
+ final InsetsState requestedState = new InsetsState();
+ requestedState.getSource(ITYPE_IME).setVisible(true);
+ mDisplayContent.mInputMethodInputTarget.updateRequestedInsetsState(requestedState);
+ getController().onInsetsModified(mDisplayContent.mInputMethodInputTarget, requestedState);
// Send our spy window (app) into the system so that we can detect the invocation.
final WindowState win = createWindow(null, TYPE_APPLICATION, "app");
+ win.setHasSurface(true);
final WindowToken parent = win.mToken;
parent.removeChild(win);
final WindowState app = spy(win);
@@ -209,7 +214,7 @@ public class InsetsStateControllerTest extends WindowTestsBase {
mDisplayContent.applySurfaceChangesTransaction();
// app won't get visible IME insets while above IME even when IME is visible.
- getController().getRawInsetsState().setSourceVisible(ITYPE_IME, true);
+ assertTrue(getController().getRawInsetsState().getSourceOrDefaultVisibility(ITYPE_IME));
assertFalse(getController().getInsetsForDispatch(app).getSource(ITYPE_IME).isVisible());
// Reset invocation counter.
@@ -223,8 +228,7 @@ public class InsetsStateControllerTest extends WindowTestsBase {
// Make sure app got notified.
verify(app, atLeast(1)).notifyInsetsChanged();
- // app will get visible IME insets while below IME when IME is visible.
- getController().getRawInsetsState().setSourceVisible(ITYPE_IME, true);
+ // app will get visible IME insets while below IME.
assertTrue(getController().getInsetsForDispatch(app).getSource(ITYPE_IME).isVisible());
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
index ca6679d1eece..8e85e7b96d1f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
@@ -321,7 +321,6 @@ public class RecentsAnimationControllerTest extends WindowTestsBase {
@Test
public void testRecentViewInFixedPortraitWhenTopAppInLandscape() {
- mWm.mIsFixedRotationTransformEnabled = true;
mWm.setRecentsAnimationController(mController);
final ActivityRecord homeActivity = createHomeActivity();
@@ -349,11 +348,19 @@ public class RecentsAnimationControllerTest extends WindowTestsBase {
assertEquals(Configuration.ORIENTATION_PORTRAIT,
homeActivity.getConfiguration().orientation);
- // Home activity won't become top (return to landActivity), so its fixed rotation and the
- // top rotated record should be cleared.
+ // Home activity won't become top (return to landActivity), so the top rotated record should
+ // be cleared.
mController.cleanupAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION);
- assertFalse(homeActivity.hasFixedRotationTransform());
+ assertFalse(mDefaultDisplay.isFixedRotationLaunchingApp(homeActivity));
assertFalse(mDefaultDisplay.hasTopFixedRotationLaunchingApp());
+ // The transform should keep until the transition is done, so the restored configuration
+ // won't be sent to activity and cause unnecessary configuration change.
+ assertTrue(homeActivity.hasFixedRotationTransform());
+
+ // In real case the transition will be executed from RecentsAnimation#finishAnimation.
+ mDefaultDisplay.mFixedRotationTransitionListener.onAppTransitionFinishedLocked(
+ homeActivity.token);
+ assertFalse(homeActivity.hasFixedRotationTransform());
}
@Test
@@ -382,7 +389,6 @@ public class RecentsAnimationControllerTest extends WindowTestsBase {
@Test
public void testWallpaperHasFixedRotationApplied() {
- mWm.mIsFixedRotationTransformEnabled = true;
mWm.setRecentsAnimationController(mController);
// Create a portrait home activity, a wallpaper and a landscape activity displayed on top.
diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
index 665cf83cd33c..130e5550b2a2 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -24,6 +24,7 @@ import static android.view.Surface.ROTATION_270;
import static android.view.Surface.ROTATION_90;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.eq;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.never;
@@ -250,6 +251,13 @@ public class SizeCompatTests extends ActivityTestsBase {
mActivity.mDisplayContent.mInputMethodTarget = addWindowToActivity(mActivity);
// Make sure IME cannot attach to the app, otherwise IME window will also be shifted.
assertFalse(mActivity.mDisplayContent.isImeAttachedToApp());
+
+ // Recompute the natural configuration without resolving size compat configuration.
+ mActivity.clearSizeCompatMode();
+ mActivity.onConfigurationChanged(mTask.getConfiguration());
+ // It should keep non-attachable because the resolved bounds will be computed according to
+ // the aspect ratio that won't match its parent bounds.
+ assertFalse(mActivity.mDisplayContent.isImeAttachedToApp());
}
@Test
@@ -288,14 +296,29 @@ public class SizeCompatTests extends ActivityTestsBase {
// Move the non-resizable activity to the new display.
mStack.reparent(newDisplay.getDefaultTaskDisplayArea(), true /* onTop */);
- // The configuration bounds should keep the same.
+ // The configuration bounds [820, 0 - 1820, 2500] should keep the same.
assertEquals(origWidth, configBounds.width());
assertEquals(origHeight, configBounds.height());
assertScaled();
+ final Rect newDisplayBounds = newDisplay.getWindowConfiguration().getBounds();
// The scaled bounds should exclude notch area (1000 - 100 == 360 * 2500 / 1000 = 900).
- assertEquals(newDisplay.getBounds().height() - notchHeight,
+ assertEquals(newDisplayBounds.height() - notchHeight,
(int) ((float) mActivity.getBounds().width() * origHeight / origWidth));
+
+ // Recompute the natural configuration in the new display.
+ mActivity.clearSizeCompatMode();
+ mActivity.ensureActivityConfiguration(0 /* globalChanges */, false /* preserveWindow */);
+ // Because the display cannot rotate, the portrait activity will fit the short side of
+ // display with keeping portrait bounds [200, 0 - 700, 1000] in center.
+ assertEquals(newDisplayBounds.height(), configBounds.height());
+ assertEquals(configBounds.height() * newDisplayBounds.height() / newDisplayBounds.width(),
+ configBounds.width());
+ assertFitted();
+ // The appBounds should be [200, 100 - 700, 1000].
+ final Rect appBounds = mActivity.getWindowConfiguration().getAppBounds();
+ assertEquals(configBounds.width(), appBounds.width());
+ assertEquals(configBounds.height() - notchHeight, appBounds.height());
}
@Test
@@ -488,10 +511,12 @@ public class SizeCompatTests extends ActivityTestsBase {
@Test
public void testLaunchWithFixedRotationTransform() {
- mService.mWindowManager.mIsFixedRotationTransformEnabled = true;
final int dw = 1000;
final int dh = 2500;
- setUpDisplaySizeWithApp(dw, dh);
+ final int notchHeight = 200;
+ setUpApp(new TestDisplayContent.Builder(mService, dw, dh).setNotch(notchHeight).build());
+ addStatusBar(mActivity.mDisplayContent);
+
mActivity.mDisplayContent.prepareAppTransition(WindowManager.TRANSIT_ACTIVITY_OPEN,
false /* alwaysKeepCurrent */);
mActivity.mDisplayContent.mOpeningApps.add(mActivity);
@@ -503,31 +528,76 @@ public class SizeCompatTests extends ActivityTestsBase {
// Display keeps in original orientation.
assertEquals(Configuration.ORIENTATION_PORTRAIT,
mActivity.mDisplayContent.getConfiguration().orientation);
- // Activity bounds should be [350, 0 - 2150, 1000] in landscape. Its width=1000*1.8=1800.
+ // The width should be restricted by the max aspect ratio = 1000 * 1.8 = 1800.
assertEquals((int) (dw * maxAspect), mActivity.getBounds().width());
- // The bounds should be horizontal centered: (2500-1900)/2=350.
- assertEquals((dh - mActivity.getBounds().width()) / 2, mActivity.getBounds().left);
+ // The notch is at the left side of the landscape activity. The bounds should be horizontal
+ // centered in the remaining area [200, 0 - 2500, 1000], so its left should be
+ // 200 + (2300 - 1800) / 2 = 450. The bounds should be [450, 0 - 2250, 1000].
+ assertEquals(notchHeight + (dh - notchHeight - mActivity.getBounds().width()) / 2,
+ mActivity.getBounds().left);
// The letterbox needs a main window to layout.
- addWindowToActivity(mActivity);
+ final WindowState w = addWindowToActivity(mActivity);
// Compute the frames of the window and invoke {@link ActivityRecord#layoutLetterbox}.
mActivity.mRootWindowContainer.performSurfacePlacement();
- // The letterbox insets should be [350, 0 - 350, 0].
+ // The letterbox insets should be [450, 0 - 250, 0].
assertEquals(new Rect(mActivity.getBounds().left, 0, dh - mActivity.getBounds().right, 0),
mActivity.getLetterboxInsets());
+
+ final StatusBarController statusBarController =
+ mActivity.mDisplayContent.getDisplayPolicy().getStatusBarController();
+ // The activity doesn't fill the display, so the letterbox of the rotated activity is
+ // overlapped with the rotated content frame of status bar. Hence the status bar shouldn't
+ // be transparent.
+ assertFalse(statusBarController.isTransparentAllowed(w));
+
+ // Make the activity fill the display.
+ prepareUnresizable(10 /* maxAspect */, SCREEN_ORIENTATION_LANDSCAPE);
+ w.mWinAnimator.mDrawState = WindowStateAnimator.HAS_DRAWN;
+ // Refresh the letterbox.
+ mActivity.mRootWindowContainer.performSurfacePlacement();
+
+ // The letterbox should only cover the notch area, so status bar can be transparent.
+ assertEquals(new Rect(notchHeight, 0, 0, 0), mActivity.getLetterboxInsets());
+ assertTrue(statusBarController.isTransparentAllowed(w));
}
- private WindowState addWindowToActivity(ActivityRecord activity) {
+ private static WindowState addWindowToActivity(ActivityRecord activity) {
final WindowManager.LayoutParams params = new WindowManager.LayoutParams();
params.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
final WindowTestUtils.TestWindowState w = new WindowTestUtils.TestWindowState(
- mService.mWindowManager, mock(Session.class), new TestIWindow(), params, mActivity);
+ activity.mWmService, mock(Session.class), new TestIWindow(), params, activity);
WindowTestsBase.makeWindowVisible(w);
w.mWinAnimator.mDrawState = WindowStateAnimator.HAS_DRAWN;
- mActivity.addWindow(w);
+ activity.addWindow(w);
return w;
}
+ private static void addStatusBar(DisplayContent displayContent) {
+ final DisplayPolicy displayPolicy = displayContent.getDisplayPolicy();
+ doReturn(true).when(displayPolicy).hasStatusBar();
+ displayPolicy.onConfigurationChanged();
+
+ final WindowTestUtils.TestWindowToken token = WindowTestUtils.createTestWindowToken(
+ WindowManager.LayoutParams.TYPE_STATUS_BAR, displayContent);
+ final WindowManager.LayoutParams attrs =
+ new WindowManager.LayoutParams(WindowManager.LayoutParams.TYPE_STATUS_BAR);
+ attrs.gravity = android.view.Gravity.TOP;
+ attrs.layoutInDisplayCutoutMode =
+ WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+ attrs.setFitInsetsTypes(0 /* types */);
+ final WindowTestUtils.TestWindowState statusBar = new WindowTestUtils.TestWindowState(
+ displayContent.mWmService, mock(Session.class), new TestIWindow(), attrs, token);
+ token.addWindow(statusBar);
+ statusBar.setRequestedSize(displayContent.mBaseDisplayWidth,
+ displayContent.getDisplayUiContext().getResources().getDimensionPixelSize(
+ com.android.internal.R.dimen.status_bar_height));
+
+ displayPolicy.addWindowLw(statusBar, attrs);
+ displayPolicy.beginLayoutLw(displayContent.mDisplayFrames,
+ displayContent.getConfiguration().uiMode);
+ }
+
/**
* Setup {@link #mActivity} as a size-compat-mode-able activity with fixed aspect and/or
* orientation.
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java
index 512042cdf7b9..786f8d8af024 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java
@@ -150,9 +150,9 @@ public class TaskDisplayAreaTests extends WindowTestsBase {
@Test
public void testDisplayPositionWithPinnedStack() {
- // Make sure the display is system owned display which capable to move the stack to top.
+ // Make sure the display is trusted display which capable to move the stack to top.
spyOn(mDisplayContent);
- doReturn(false).when(mDisplayContent).isUntrustedVirtualDisplay();
+ doReturn(true).when(mDisplayContent).isTrusted();
// The display contains pinned stack that was added in {@link #setUp}.
final ActivityStack stack = createTaskStackOnDisplay(mDisplayContent);
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java
index 4907bdc5e1f0..d6ec78837f7d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java
@@ -190,7 +190,7 @@ public class TaskSnapshotSurfaceTest extends WindowTestsBase {
public void testCalculateSnapshotFrame() {
setupSurface(100, 100);
final Rect insets = new Rect(0, 10, 0, 10);
- mSurface.setFrames(new Rect(0, 0, 100, 100), insets, insets);
+ mSurface.setFrames(new Rect(0, 0, 100, 100), insets);
assertEquals(new Rect(0, 0, 100, 80),
mSurface.calculateSnapshotFrame(new Rect(0, 10, 100, 90)));
}
@@ -199,7 +199,7 @@ public class TaskSnapshotSurfaceTest extends WindowTestsBase {
public void testCalculateSnapshotFrame_navBarLeft() {
setupSurface(100, 100);
final Rect insets = new Rect(10, 10, 0, 0);
- mSurface.setFrames(new Rect(0, 0, 100, 100), insets, insets);
+ mSurface.setFrames(new Rect(0, 0, 100, 100), insets);
assertEquals(new Rect(10, 0, 100, 90),
mSurface.calculateSnapshotFrame(new Rect(10, 10, 100, 100)));
}
@@ -208,7 +208,7 @@ public class TaskSnapshotSurfaceTest extends WindowTestsBase {
public void testCalculateSnapshotFrame_waterfall() {
setupSurface(100, 100, new Rect(5, 10, 5, 10), 0, 0, new Rect(0, 0, 100, 100));
final Rect insets = new Rect(0, 10, 0, 10);
- mSurface.setFrames(new Rect(5, 0, 95, 100), insets, insets);
+ mSurface.setFrames(new Rect(5, 0, 95, 100), insets);
assertEquals(new Rect(0, 0, 90, 90),
mSurface.calculateSnapshotFrame(new Rect(5, 0, 95, 90)));
}
@@ -217,7 +217,7 @@ public class TaskSnapshotSurfaceTest extends WindowTestsBase {
public void testDrawStatusBarBackground() {
setupSurface(100, 100);
final Rect insets = new Rect(0, 10, 10, 0);
- mSurface.setFrames(new Rect(0, 0, 100, 100), insets, insets);
+ mSurface.setFrames(new Rect(0, 0, 100, 100), insets);
final Canvas mockCanvas = mock(Canvas.class);
when(mockCanvas.getWidth()).thenReturn(100);
when(mockCanvas.getHeight()).thenReturn(100);
@@ -230,7 +230,7 @@ public class TaskSnapshotSurfaceTest extends WindowTestsBase {
public void testDrawStatusBarBackground_nullFrame() {
setupSurface(100, 100);
final Rect insets = new Rect(0, 10, 10, 0);
- mSurface.setFrames(new Rect(0, 0, 100, 100), insets, insets);
+ mSurface.setFrames(new Rect(0, 0, 100, 100), insets);
final Canvas mockCanvas = mock(Canvas.class);
when(mockCanvas.getWidth()).thenReturn(100);
when(mockCanvas.getHeight()).thenReturn(100);
@@ -243,7 +243,7 @@ public class TaskSnapshotSurfaceTest extends WindowTestsBase {
public void testDrawStatusBarBackground_nope() {
setupSurface(100, 100);
final Rect insets = new Rect(0, 10, 10, 0);
- mSurface.setFrames(new Rect(0, 0, 100, 100), insets, insets);
+ mSurface.setFrames(new Rect(0, 0, 100, 100), insets);
final Canvas mockCanvas = mock(Canvas.class);
when(mockCanvas.getWidth()).thenReturn(100);
when(mockCanvas.getHeight()).thenReturn(100);
@@ -257,7 +257,7 @@ public class TaskSnapshotSurfaceTest extends WindowTestsBase {
final Rect insets = new Rect(0, 10, 0, 10);
setupSurface(100, 100, insets, 0, FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS,
new Rect(0, 0, 100, 100));
- mSurface.setFrames(new Rect(0, 0, 100, 100), insets, insets);
+ mSurface.setFrames(new Rect(0, 0, 100, 100), insets);
final Canvas mockCanvas = mock(Canvas.class);
when(mockCanvas.getWidth()).thenReturn(100);
when(mockCanvas.getHeight()).thenReturn(100);
@@ -270,7 +270,7 @@ public class TaskSnapshotSurfaceTest extends WindowTestsBase {
final Rect insets = new Rect(10, 10, 0, 0);
setupSurface(100, 100, insets, 0, FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS,
new Rect(0, 0, 100, 100));
- mSurface.setFrames(new Rect(0, 0, 100, 100), insets, insets);
+ mSurface.setFrames(new Rect(0, 0, 100, 100), insets);
final Canvas mockCanvas = mock(Canvas.class);
when(mockCanvas.getWidth()).thenReturn(100);
when(mockCanvas.getHeight()).thenReturn(100);
@@ -283,7 +283,7 @@ public class TaskSnapshotSurfaceTest extends WindowTestsBase {
final Rect insets = new Rect(0, 10, 10, 0);
setupSurface(100, 100, insets, 0, FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS,
new Rect(0, 0, 100, 100));
- mSurface.setFrames(new Rect(0, 0, 100, 100), insets, insets);
+ mSurface.setFrames(new Rect(0, 0, 100, 100), insets);
final Canvas mockCanvas = mock(Canvas.class);
when(mockCanvas.getWidth()).thenReturn(100);
when(mockCanvas.getHeight()).thenReturn(100);
diff --git a/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java
index 373f363e31ff..53ede60e9ac7 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java
@@ -101,7 +101,6 @@ public class WallpaperControllerTests extends WindowTestsBase {
public void testWallpaperSizeWithFixedTransform() {
// No wallpaper
final DisplayContent dc = createNewDisplay();
- dc.mWmService.mIsFixedRotationTransformEnabled = true;
// No wallpaper WSA Surface
WindowToken wallpaperWindowToken = new WallpaperWindowToken(mWm, mock(IBinder.class),
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
index 71dabc56719b..7ce0c1edfb4c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
@@ -67,6 +67,7 @@ import android.util.Rational;
import android.view.Display;
import android.view.SurfaceControl;
import android.window.ITaskOrganizer;
+import android.window.IWindowContainerTransactionCallback;
import android.window.WindowContainerTransaction;
import androidx.test.filters.SmallTest;
@@ -728,7 +729,7 @@ public class WindowOrganizerTests extends WindowTestsBase {
// We should be rejected from the second sync since we are already
// in one.
assertEquals(false, bse.addToSyncSet(id2, task));
- w.finishDrawing(null);
+ finishAndNotifyDrawing(w);
assertEquals(true, bse.addToSyncSet(id2, task));
bse.setReady(id2);
}
@@ -752,7 +753,7 @@ public class WindowOrganizerTests extends WindowTestsBase {
// Since we have a window we have to wait for it to draw to finish sync.
verify(transactionListener, never())
.onTransactionReady(anyInt(), any());
- w.finishDrawing(null);
+ finishAndNotifyDrawing(w);
verify(transactionListener)
.onTransactionReady(anyInt(), any());
}
@@ -820,14 +821,14 @@ public class WindowOrganizerTests extends WindowTestsBase {
int id = bse.startSyncSet(transactionListener);
assertEquals(true, bse.addToSyncSet(id, task));
bse.setReady(id);
- w.finishDrawing(null);
+ finishAndNotifyDrawing(w);
// Since we have a child window we still shouldn't be done.
verify(transactionListener, never())
.onTransactionReady(anyInt(), any());
reset(transactionListener);
- child.finishDrawing(null);
+ finishAndNotifyDrawing(child);
// Ah finally! Done
verify(transactionListener)
.onTransactionReady(anyInt(), any());
@@ -979,4 +980,42 @@ public class WindowOrganizerTests extends WindowTestsBase {
new IRequestFinishCallback.Default());
verify(organizer, times(1)).onBackPressedOnTaskRoot(any());
}
+
+ @Test
+ public void testBLASTCallbackWithMultipleWindows() throws Exception {
+ final ActivityStack stackController = createStack();
+ final Task task = createTask(stackController);
+ final ITaskOrganizer organizer = registerMockOrganizer();
+ final WindowState w1 = createAppWindow(task, TYPE_APPLICATION, "Enlightened Window 1");
+ final WindowState w2 = createAppWindow(task, TYPE_APPLICATION, "Enlightened Window 2");
+ makeWindowVisible(w1);
+ makeWindowVisible(w2);
+
+ IWindowContainerTransactionCallback mockCallback =
+ mock(IWindowContainerTransactionCallback.class);
+ int id = mWm.mAtmService.mWindowOrganizerController.startSyncWithOrganizer(mockCallback);
+
+ mWm.mAtmService.mWindowOrganizerController.addToSyncSet(id, task);
+ mWm.mAtmService.mWindowOrganizerController.setSyncReady(id);
+
+ // Since we have a window we have to wait for it to draw to finish sync.
+ verify(mockCallback, never()).onTransactionReady(anyInt(), any());
+ assertTrue(w1.useBLASTSync());
+ assertTrue(w2.useBLASTSync());
+ finishAndNotifyDrawing(w1);
+
+ // Even though one Window finished drawing, both windows should still be using blast sync
+ assertTrue(w1.useBLASTSync());
+ assertTrue(w2.useBLASTSync());
+
+ finishAndNotifyDrawing(w2);
+ verify(mockCallback).onTransactionReady(anyInt(), any());
+ assertFalse(w1.useBLASTSync());
+ assertFalse(w2.useBLASTSync());
+ }
+
+ private void finishAndNotifyDrawing(WindowState ws) {
+ ws.finishDrawing(null);
+ ws.notifyBlastSyncTransaction();
+ }
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
index e9ed20bd9683..4a0f48cf2ccb 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
@@ -18,6 +18,7 @@ package com.android.server.wm;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
import static android.hardware.camera2.params.OutputConfiguration.ROTATION_90;
import static android.view.InsetsState.ITYPE_STATUS_BAR;
@@ -244,6 +245,12 @@ public class WindowStateTests extends WindowTestsBase {
appWindow.mAttrs.flags &= ~FLAG_NOT_FOCUSABLE;
assertTrue(appWindow.canBeImeTarget());
+ // Verify PINNED windows can't be IME target.
+ int initialMode = appWindow.mActivityRecord.getWindowingMode();
+ appWindow.mActivityRecord.setWindowingMode(WINDOWING_MODE_PINNED);
+ assertFalse(appWindow.canBeImeTarget());
+ appWindow.mActivityRecord.setWindowingMode(initialMode);
+
// Make windows invisible
appWindow.hideLw(false /* doAnimation */);
imeWindow.hideLw(false /* doAnimation */);
@@ -646,6 +653,7 @@ public class WindowStateTests extends WindowTestsBase {
final WindowState win1 = createWindow(null, TYPE_APPLICATION, dc, "win1");
win1.mHasSurface = true;
win1.mSurfaceControl = mock(SurfaceControl.class);
+ win1.mAttrs.surfaceInsets.set(1, 2, 3, 4);
win1.getFrameLw().offsetTo(WINDOW_OFFSET, 0);
win1.updateSurfacePosition(t);
win1.getTransformationMatrix(values, matrix);
@@ -692,4 +700,14 @@ public class WindowStateTests extends WindowTestsBase {
sameTokenWindow.removeImmediately();
assertFalse(sameTokenWindow.needsRelativeLayeringToIme());
}
+
+ @Test
+ public void testNeedsRelativeLayeringToIme_startingWindow() {
+ WindowState sameTokenWindow = createWindow(null, TYPE_APPLICATION_STARTING,
+ mAppWindow.mToken, "SameTokenWindow");
+ mDisplayContent.mInputMethodTarget = mAppWindow;
+ sameTokenWindow.mActivityRecord.getStack().setWindowingMode(
+ WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
+ assertFalse(sameTokenWindow.needsRelativeLayeringToIme());
+ }
}
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 060ed51951e4..321657d5d626 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -681,6 +681,8 @@ public class UsageStatsService extends SystemService implements
reportEventToAllUserId(event);
flushToDiskLocked();
}
+
+ mAppStandby.flushToDisk();
}
/**
@@ -780,6 +782,22 @@ public class UsageStatsService extends SystemService implements
* Called by the Binder stub.
*/
void reportEvent(Event event, int userId) {
+ final int uid;
+ // Acquire uid outside of mLock for events that need it
+ switch (event.mEventType) {
+ case Event.ACTIVITY_RESUMED:
+ case Event.ACTIVITY_PAUSED:
+ uid = mPackageManagerInternal.getPackageUid(event.mPackage, 0, userId);
+ break;
+ default:
+ uid = 0;
+ }
+
+ if (event.mPackage != null
+ && mPackageManagerInternal.isPackageEphemeral(userId, event.mPackage)) {
+ event.mFlags |= Event.FLAG_IS_PACKAGE_INSTANT_APP;
+ }
+
synchronized (mLock) {
// This should never be called directly when the user is locked
if (!mUserUnlockedStates.get(userId)) {
@@ -790,15 +808,15 @@ public class UsageStatsService extends SystemService implements
return;
}
- final long elapsedRealtime = SystemClock.elapsedRealtime();
-
- if (event.mPackage != null
- && mPackageManagerInternal.isPackageEphemeral(userId, event.mPackage)) {
- event.mFlags |= Event.FLAG_IS_PACKAGE_INSTANT_APP;
- }
-
switch (event.mEventType) {
case Event.ACTIVITY_RESUMED:
+ FrameworkStatsLog.write(
+ FrameworkStatsLog.APP_USAGE_EVENT_OCCURRED,
+ uid,
+ event.mPackage,
+ event.mClass,
+ FrameworkStatsLog
+ .APP_USAGE_EVENT_OCCURRED__EVENT_TYPE__MOVE_TO_FOREGROUND);
// check if this activity has already been resumed
if (mVisibleActivities.get(event.mInstanceId) != null) break;
mVisibleActivities.put(event.mInstanceId,
@@ -816,13 +834,6 @@ public class UsageStatsService extends SystemService implements
} catch (IllegalArgumentException iae) {
Slog.e(TAG, "Failed to note usage start", iae);
}
- FrameworkStatsLog.write(
- FrameworkStatsLog.APP_USAGE_EVENT_OCCURRED,
- mPackageManagerInternal.getPackageUid(event.mPackage, 0, userId),
- event.mPackage,
- event.mClass,
- FrameworkStatsLog
- .APP_USAGE_EVENT_OCCURRED__EVENT_TYPE__MOVE_TO_FOREGROUND);
break;
case Event.ACTIVITY_PAUSED:
if (event.mTaskRootPackage == null) {
@@ -839,7 +850,7 @@ public class UsageStatsService extends SystemService implements
}
FrameworkStatsLog.write(
FrameworkStatsLog.APP_USAGE_EVENT_OCCURRED,
- mPackageManagerInternal.getPackageUid(event.mPackage, 0, userId),
+ uid,
event.mPackage,
event.mClass,
FrameworkStatsLog
@@ -903,9 +914,9 @@ public class UsageStatsService extends SystemService implements
return; // user was stopped or removed
}
service.reportEvent(event);
-
- mAppStandby.reportEvent(event, elapsedRealtime, userId);
}
+
+ mAppStandby.reportEvent(event, userId);
}
/**
@@ -937,6 +948,7 @@ public class UsageStatsService extends SystemService implements
reportEventToAllUserId(event);
flushToDiskLocked();
}
+ mAppStandby.flushToDisk();
}
/**
@@ -946,9 +958,9 @@ public class UsageStatsService extends SystemService implements
synchronized (mLock) {
Slog.i(TAG, "Removing user " + userId + " and all data.");
mUserState.remove(userId);
- mAppStandby.onUserRemoved(userId);
mAppTimeLimit.onUserRemoved(userId);
}
+ mAppStandby.onUserRemoved(userId);
// Cancel any scheduled jobs for this user since the user is being removed.
UsageStatsIdleService.cancelJob(getContext(), userId);
UsageStatsIdleService.cancelUpdateMappingsJob(getContext());
@@ -1147,10 +1159,7 @@ public class UsageStatsService extends SystemService implements
if (service != null) {
service.persistActiveStats();
}
- mAppStandby.flushToDisk(userId);
}
- mAppStandby.flushDurationsToDisk();
-
mHandler.removeMessages(MSG_FLUSH_TO_DISK);
}
@@ -1158,28 +1167,31 @@ public class UsageStatsService extends SystemService implements
* Called by the Binder stub.
*/
void dump(String[] args, PrintWriter pw) {
- synchronized (mLock) {
- IndentingPrintWriter idpw = new IndentingPrintWriter(pw, " ");
-
- boolean checkin = false;
- boolean compact = false;
- final ArrayList<String> pkgs = new ArrayList<>();
-
- if (args != null) {
- for (int i = 0; i < args.length; i++) {
- String arg = args[i];
- if ("--checkin".equals(arg)) {
- checkin = true;
- } else if ("-c".equals(arg)) {
- compact = true;
- } else if ("flush".equals(arg)) {
+ IndentingPrintWriter idpw = new IndentingPrintWriter(pw, " ");
+
+ boolean checkin = false;
+ boolean compact = false;
+ final ArrayList<String> pkgs = new ArrayList<>();
+
+ if (args != null) {
+ for (int i = 0; i < args.length; i++) {
+ String arg = args[i];
+ if ("--checkin".equals(arg)) {
+ checkin = true;
+ } else if ("-c".equals(arg)) {
+ compact = true;
+ } else if ("flush".equals(arg)) {
+ synchronized (mLock) {
flushToDiskLocked();
- pw.println("Flushed stats to disk");
- return;
- } else if ("is-app-standby-enabled".equals(arg)) {
- pw.println(mAppStandby.isAppIdleEnabled());
- return;
- } else if ("apptimelimit".equals(arg)) {
+ }
+ mAppStandby.flushToDisk();
+ pw.println("Flushed stats to disk");
+ return;
+ } else if ("is-app-standby-enabled".equals(arg)) {
+ pw.println(mAppStandby.isAppIdleEnabled());
+ return;
+ } else if ("apptimelimit".equals(arg)) {
+ synchronized (mLock) {
if (i + 1 >= args.length) {
mAppTimeLimit.dump(null, pw);
} else {
@@ -1188,8 +1200,10 @@ public class UsageStatsService extends SystemService implements
mAppTimeLimit.dump(remainingArgs, pw);
}
return;
- } else if ("file".equals(arg)) {
- final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
+ }
+ } else if ("file".equals(arg)) {
+ final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
+ synchronized (mLock) {
if (i + 1 >= args.length) {
// dump everything for all users
final int numUsers = mUserState.size();
@@ -1213,8 +1227,10 @@ public class UsageStatsService extends SystemService implements
}
}
return;
- } else if ("database-info".equals(arg)) {
- final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
+ }
+ } else if ("database-info".equals(arg)) {
+ final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
+ synchronized (mLock) {
if (i + 1 >= args.length) {
// dump info for all users
final int numUsers = mUserState.size();
@@ -1236,34 +1252,43 @@ public class UsageStatsService extends SystemService implements
}
}
return;
- } else if ("appstandby".equals(arg)) {
- mAppStandby.dumpState(args, pw);
- return;
- } else if ("stats-directory".equals(arg)) {
- final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
+ }
+ } else if ("appstandby".equals(arg)) {
+ mAppStandby.dumpState(args, pw);
+ return;
+ } else if ("stats-directory".equals(arg)) {
+ final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
+ synchronized (mLock) {
final int userId = parseUserIdFromArgs(args, i, ipw);
if (userId != UserHandle.USER_NULL) {
ipw.println(new File(Environment.getDataSystemCeDirectory(userId),
"usagestats").getAbsolutePath());
}
return;
- } else if ("mappings".equals(arg)) {
- final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
- final int userId = parseUserIdFromArgs(args, i, ipw);
+ }
+ } else if ("mappings".equals(arg)) {
+ final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
+ final int userId = parseUserIdFromArgs(args, i, ipw);
+ synchronized (mLock) {
if (userId != UserHandle.USER_NULL) {
mUserState.get(userId).dumpMappings(ipw);
}
return;
- } else if (arg != null && !arg.startsWith("-")) {
- // Anything else that doesn't start with '-' is a pkg to filter
- pkgs.add(arg);
}
+ } else if (arg != null && !arg.startsWith("-")) {
+ // Anything else that doesn't start with '-' is a pkg to filter
+ pkgs.add(arg);
}
}
+ }
+ final int[] userIds;
+ synchronized (mLock) {
final int userCount = mUserState.size();
+ userIds = new int[userCount];
for (int i = 0; i < userCount; i++) {
- int userId = mUserState.keyAt(i);
+ final int userId = mUserState.keyAt(i);
+ userIds[i] = userId;
idpw.printPair("user", userId);
idpw.println();
idpw.increaseIndent();
@@ -1275,21 +1300,22 @@ public class UsageStatsService extends SystemService implements
idpw.println();
}
}
- mAppStandby.dumpUser(idpw, userId, pkgs);
idpw.decreaseIndent();
}
- if (CollectionUtils.isEmpty(pkgs)) {
- pw.println();
- mAppStandby.dumpState(args, pw);
- }
-
idpw.println();
idpw.printPair("Usage Source", UsageStatsManager.usageSourceToString(mUsageSource));
idpw.println();
mAppTimeLimit.dump(null, pw);
}
+
+ mAppStandby.dumpUsers(idpw, userIds, pkgs);
+
+ if (CollectionUtils.isEmpty(pkgs)) {
+ pw.println();
+ mAppStandby.dumpState(args, pw);
+ }
}
private int parseUserIdFromArgs(String[] args, int index, IndentingPrintWriter ipw) {
diff --git a/telephony/common/com/android/internal/telephony/CarrierAppUtils.java b/telephony/common/com/android/internal/telephony/CarrierAppUtils.java
index 4606fb4b631c..e57b03098758 100644
--- a/telephony/common/com/android/internal/telephony/CarrierAppUtils.java
+++ b/telephony/common/com/android/internal/telephony/CarrierAppUtils.java
@@ -21,6 +21,8 @@ import android.content.ContentResolver;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
+import android.os.Build;
+import android.os.CarrierAssociatedAppEntry;
import android.os.SystemConfigManager;
import android.os.UserHandle;
import android.permission.PermissionManager;
@@ -79,8 +81,8 @@ public final class CarrierAppUtils {
SystemConfigManager config = context.getSystemService(SystemConfigManager.class);
Set<String> systemCarrierAppsDisabledUntilUsed =
config.getDisabledUntilUsedPreinstalledCarrierApps();
- Map<String, List<String>> systemCarrierAssociatedAppsDisabledUntilUsed =
- config.getDisabledUntilUsedPreinstalledCarrierAssociatedApps();
+ Map<String, List<CarrierAssociatedAppEntry>> systemCarrierAssociatedAppsDisabledUntilUsed =
+ config.getDisabledUntilUsedPreinstalledCarrierAssociatedAppEntries();
ContentResolver contentResolver = getContentResolverForUser(context, userId);
disableCarrierAppsUntilPrivileged(callingPackage, telephonyManager, contentResolver,
userId, systemCarrierAppsDisabledUntilUsed,
@@ -107,8 +109,8 @@ public final class CarrierAppUtils {
Set<String> systemCarrierAppsDisabledUntilUsed =
config.getDisabledUntilUsedPreinstalledCarrierApps();
- Map<String, List<String>> systemCarrierAssociatedAppsDisabledUntilUsed =
- config.getDisabledUntilUsedPreinstalledCarrierAssociatedApps();
+ Map<String, List<CarrierAssociatedAppEntry>> systemCarrierAssociatedAppsDisabledUntilUsed =
+ config.getDisabledUntilUsedPreinstalledCarrierAssociatedAppEntries();
ContentResolver contentResolver = getContentResolverForUser(context, userId);
disableCarrierAppsUntilPrivileged(callingPackage, null /* telephonyManager */,
contentResolver, userId, systemCarrierAppsDisabledUntilUsed,
@@ -138,8 +140,8 @@ public final class CarrierAppUtils {
public static void disableCarrierAppsUntilPrivileged(String callingPackage,
@Nullable TelephonyManager telephonyManager, ContentResolver contentResolver,
int userId, Set<String> systemCarrierAppsDisabledUntilUsed,
- Map<String, List<String>> systemCarrierAssociatedAppsDisabledUntilUsed,
- Context context) {
+ Map<String, List<CarrierAssociatedAppEntry>>
+ systemCarrierAssociatedAppsDisabledUntilUsed, Context context) {
PackageManager packageManager = context.getPackageManager();
PermissionManager permissionManager =
(PermissionManager) context.getSystemService(Context.PERMISSION_SERVICE);
@@ -149,12 +151,17 @@ public final class CarrierAppUtils {
return;
}
- Map<String, List<ApplicationInfo>> associatedApps = getDefaultCarrierAssociatedAppsHelper(
+ Map<String, List<AssociatedAppInfo>> associatedApps = getDefaultCarrierAssociatedAppsHelper(
userId, systemCarrierAssociatedAppsDisabledUntilUsed, context);
List<String> enabledCarrierPackages = new ArrayList<>();
- boolean hasRunOnce = Settings.Secure.getInt(contentResolver,
- Settings.Secure.CARRIER_APPS_HANDLED, 0) == 1;
+ int carrierAppsHandledSdk =
+ Settings.Secure.getInt(contentResolver, Settings.Secure.CARRIER_APPS_HANDLED, 0);
+ if (DEBUG) {
+ Log.i(TAG, "Last execution SDK: " + carrierAppsHandledSdk);
+ }
+ boolean hasRunEver = carrierAppsHandledSdk != 0; // SDKs < R used to just set 1 here
+ boolean hasRunForSdk = carrierAppsHandledSdk == Build.VERSION.SDK_INT;
try {
for (ApplicationInfo ai : candidates) {
@@ -166,10 +173,10 @@ public final class CarrierAppUtils {
// add hiddenUntilInstalled flag for carrier apps and associated apps
packageManager.setSystemAppState(
packageName, PackageManager.SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_HIDDEN);
- List<ApplicationInfo> associatedAppList = associatedApps.get(packageName);
+ List<AssociatedAppInfo> associatedAppList = associatedApps.get(packageName);
if (associatedAppList != null) {
- for (ApplicationInfo associatedApp : associatedAppList) {
- packageManager.setSystemAppState(associatedApp.packageName,
+ for (AssociatedAppInfo associatedApp : associatedAppList) {
+ packageManager.setSystemAppState(associatedApp.appInfo.packageName,
PackageManager.SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_HIDDEN);
}
}
@@ -184,7 +191,7 @@ public final class CarrierAppUtils {
|| enabledSetting
== PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED
|| (ai.flags & ApplicationInfo.FLAG_INSTALLED) == 0) {
- Log.i(TAG, "Update state(" + packageName + "): ENABLED for user "
+ Log.i(TAG, "Update state (" + packageName + "): ENABLED for user "
+ userId);
context.createContextAsUser(UserHandle.of(userId), 0)
.getPackageManager()
@@ -200,28 +207,37 @@ public final class CarrierAppUtils {
// Also enable any associated apps for this carrier app.
if (associatedAppList != null) {
- for (ApplicationInfo associatedApp : associatedAppList) {
+ for (AssociatedAppInfo associatedApp : associatedAppList) {
int associatedAppEnabledSetting = context
.createContextAsUser(UserHandle.of(userId), 0)
.getPackageManager()
- .getApplicationEnabledSetting(associatedApp.packageName);
+ .getApplicationEnabledSetting(
+ associatedApp.appInfo.packageName);
+ boolean associatedAppInstalled = (associatedApp.appInfo.flags
+ & ApplicationInfo.FLAG_INSTALLED) != 0;
+ if (DEBUG) {
+ Log.i(TAG, "(hasPrivileges) associated app "
+ + associatedApp.appInfo.packageName + ", enabled = "
+ + associatedAppEnabledSetting + ", installed = "
+ + associatedAppInstalled);
+ }
if (associatedAppEnabledSetting
== PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
|| associatedAppEnabledSetting
== PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED
- || (associatedApp.flags
- & ApplicationInfo.FLAG_INSTALLED) == 0) {
- Log.i(TAG, "Update associated state(" + associatedApp.packageName
- + "): ENABLED for user " + userId);
+ || !associatedAppInstalled) {
+ Log.i(TAG, "Update associated state ("
+ + associatedApp.appInfo.packageName + "): ENABLED for user "
+ + userId);
context.createContextAsUser(UserHandle.of(userId), 0)
.getPackageManager()
- .setSystemAppState(associatedApp.packageName,
+ .setSystemAppState(associatedApp.appInfo.packageName,
PackageManager.SYSTEM_APP_STATE_INSTALLED);
context.createPackageContextAsUser(
callingPackage, 0, UserHandle.of(userId))
.getPackageManager()
.setApplicationEnabledSetting(
- associatedApp.packageName,
+ associatedApp.appInfo.packageName,
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP);
}
@@ -236,7 +252,7 @@ public final class CarrierAppUtils {
if (!isUpdatedSystemApp(ai) && enabledSetting
== PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
&& (ai.flags & ApplicationInfo.FLAG_INSTALLED) != 0) {
- Log.i(TAG, "Update state(" + packageName
+ Log.i(TAG, "Update state (" + packageName
+ "): DISABLED_UNTIL_USED for user " + userId);
context.createContextAsUser(UserHandle.of(userId), 0)
.getPackageManager()
@@ -244,37 +260,56 @@ public final class CarrierAppUtils {
packageName, PackageManager.SYSTEM_APP_STATE_UNINSTALLED);
}
- // Also disable any associated apps for this carrier app if this is the first
- // run. We avoid doing this a second time because it is brittle to rely on the
- // distinction between "default" and "enabled".
- if (!hasRunOnce) {
- if (associatedAppList != null) {
- for (ApplicationInfo associatedApp : associatedAppList) {
- int associatedAppEnabledSetting = context
- .createContextAsUser(UserHandle.of(userId), 0)
+ // Associated apps are more brittle, because we can't rely on the distinction
+ // between "default" and "enabled". To account for this, we have two cases:
+ // 1. We've never run before, so we're fine to disable all associated apps.
+ // 2. We've run before, but not on this SDK version, so we will only operate on
+ // apps with addedInSdk in the range (lastHandledSdk, currentSdk].
+ // Otherwise, don't touch the associated apps.
+ if (associatedAppList != null) {
+ for (AssociatedAppInfo associatedApp : associatedAppList) {
+ boolean allowDisable = !hasRunEver || (!hasRunForSdk
+ && associatedApp.addedInSdk
+ != CarrierAssociatedAppEntry.SDK_UNSPECIFIED
+ && associatedApp.addedInSdk > carrierAppsHandledSdk
+ && associatedApp.addedInSdk <= Build.VERSION.SDK_INT);
+ int associatedAppEnabledSetting = context
+ .createContextAsUser(UserHandle.of(userId), 0)
+ .getPackageManager()
+ .getApplicationEnabledSetting(
+ associatedApp.appInfo.packageName);
+ boolean associatedAppInstalled = (associatedApp.appInfo.flags
+ & ApplicationInfo.FLAG_INSTALLED) != 0;
+ if (DEBUG) {
+ Log.i(TAG, "(!hasPrivileges) associated app "
+ + associatedApp.appInfo.packageName + ", allowDisable = "
+ + allowDisable + ", addedInSdk = "
+ + associatedApp.addedInSdk + ", enabled = "
+ + associatedAppEnabledSetting + ", installed = "
+ + associatedAppInstalled);
+ }
+ if (allowDisable
+ && associatedAppEnabledSetting
+ == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
+ && associatedAppInstalled) {
+ Log.i(TAG,
+ "Update associated state ("
+ + associatedApp.appInfo.packageName
+ + "): DISABLED_UNTIL_USED for user " + userId);
+ context.createContextAsUser(UserHandle.of(userId), 0)
.getPackageManager()
- .getApplicationEnabledSetting(associatedApp.packageName);
- if (associatedAppEnabledSetting
- == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
- && (associatedApp.flags
- & ApplicationInfo.FLAG_INSTALLED) != 0) {
- Log.i(TAG,
- "Update associated state(" + associatedApp.packageName
- + "): DISABLED_UNTIL_USED for user " + userId);
- context.createContextAsUser(UserHandle.of(userId), 0)
- .getPackageManager()
- .setSystemAppState(associatedApp.packageName,
- PackageManager.SYSTEM_APP_STATE_UNINSTALLED);
- }
+ .setSystemAppState(associatedApp.appInfo.packageName,
+ PackageManager.SYSTEM_APP_STATE_UNINSTALLED);
}
}
}
}
}
- // Mark the execution so we do not disable apps again.
- if (!hasRunOnce) {
- Settings.Secure.putInt(contentResolver, Settings.Secure.CARRIER_APPS_HANDLED, 1);
+ // Mark the execution so we do not disable apps again on this SDK version.
+ if (!hasRunEver || !hasRunForSdk) {
+ Settings.Secure.putInt(contentResolver, Settings.Secure.CARRIER_APPS_HANDLED,
+ Build.VERSION.SDK_INT);
}
if (!enabledCarrierPackages.isEmpty()) {
@@ -360,28 +395,28 @@ public final class CarrierAppUtils {
return apps;
}
- private static Map<String, List<ApplicationInfo>> getDefaultCarrierAssociatedAppsHelper(
- int userId, Map<String, List<String>> systemCarrierAssociatedAppsDisabledUntilUsed,
- Context context) {
+ private static Map<String, List<AssociatedAppInfo>> getDefaultCarrierAssociatedAppsHelper(
+ int userId, Map<String, List<CarrierAssociatedAppEntry>>
+ systemCarrierAssociatedAppsDisabledUntilUsed, Context context) {
int size = systemCarrierAssociatedAppsDisabledUntilUsed.size();
- Map<String, List<ApplicationInfo>> associatedApps = new ArrayMap<>(size);
- for (Map.Entry<String, List<String>> entry
+ Map<String, List<AssociatedAppInfo>> associatedApps = new ArrayMap<>(size);
+ for (Map.Entry<String, List<CarrierAssociatedAppEntry>> entry
: systemCarrierAssociatedAppsDisabledUntilUsed.entrySet()) {
String carrierAppPackage = entry.getKey();
- List<String> associatedAppPackages = entry.getValue();
+ List<CarrierAssociatedAppEntry> associatedAppPackages = entry.getValue();
for (int j = 0; j < associatedAppPackages.size(); j++) {
+ CarrierAssociatedAppEntry associatedApp = associatedAppPackages.get(j);
ApplicationInfo ai =
- getApplicationInfoIfSystemApp(
- userId, associatedAppPackages.get(j), context);
+ getApplicationInfoIfSystemApp(userId, associatedApp.packageName, context);
// Only update enabled state for the app on /system. Once it has been updated we
// shouldn't touch it.
if (ai != null && !isUpdatedSystemApp(ai)) {
- List<ApplicationInfo> appList = associatedApps.get(carrierAppPackage);
+ List<AssociatedAppInfo> appList = associatedApps.get(carrierAppPackage);
if (appList == null) {
appList = new ArrayList<>();
associatedApps.put(carrierAppPackage, appList);
}
- appList.add(ai);
+ appList.add(new AssociatedAppInfo(ai, associatedApp.addedInSdk));
}
}
}
@@ -406,4 +441,15 @@ public final class CarrierAppUtils {
}
return null;
}
+
+ private static final class AssociatedAppInfo {
+ public final ApplicationInfo appInfo;
+ // Might be CarrierAssociatedAppEntry.SDK_UNSPECIFIED.
+ public final int addedInSdk;
+
+ AssociatedAppInfo(ApplicationInfo appInfo, int addedInSdk) {
+ this.appInfo = appInfo;
+ this.addedInSdk = addedInSdk;
+ }
+ }
}
diff --git a/telephony/common/com/android/internal/telephony/TelephonyPermissions.java b/telephony/common/com/android/internal/telephony/TelephonyPermissions.java
index 1a38a42873b7..bc987a6282c7 100644
--- a/telephony/common/com/android/internal/telephony/TelephonyPermissions.java
+++ b/telephony/common/com/android/internal/telephony/TelephonyPermissions.java
@@ -303,12 +303,6 @@ public final class TelephonyPermissions {
String message, boolean allowCarrierPrivilegeOnAnySub) {
int uid = Binder.getCallingUid();
int pid = Binder.getCallingPid();
- PermissionManager permissionManager = (PermissionManager) context.getSystemService(
- Context.PERMISSION_SERVICE);
- if (permissionManager.checkDeviceIdentifierAccess(callingPackage, message, callingFeatureId,
- pid, uid) == PackageManager.PERMISSION_GRANTED) {
- return true;
- }
// If the calling package has carrier privileges for specified sub, then allow access.
if (checkCarrierPrivilegeForSubId(context, subId)) return true;
@@ -319,6 +313,13 @@ public final class TelephonyPermissions {
return true;
}
+ PermissionManager permissionManager = (PermissionManager) context.getSystemService(
+ Context.PERMISSION_SERVICE);
+ if (permissionManager.checkDeviceIdentifierAccess(callingPackage, message, callingFeatureId,
+ pid, uid) == PackageManager.PERMISSION_GRANTED) {
+ return true;
+ }
+
return reportAccessDeniedToReadIdentifiers(context, subId, pid, uid, callingPackage,
message);
}
@@ -433,16 +434,6 @@ public final class TelephonyPermissions {
public static boolean checkReadPhoneNumber(
Context context, int subId, int pid, int uid,
String callingPackage, @Nullable String callingFeatureId, String message) {
- // Default SMS app can always read it.
- AppOpsManager appOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
- if (appOps.noteOp(AppOpsManager.OPSTR_WRITE_SMS, uid, callingPackage, callingFeatureId,
- null) == AppOpsManager.MODE_ALLOWED) {
- return true;
- }
-
- // NOTE(b/73308711): If an app has one of the following AppOps bits explicitly revoked, they
- // will be denied access, even if they have another permission and AppOps bit if needed.
-
// First, check if the SDK version is below R
boolean preR = false;
try {
@@ -477,21 +468,29 @@ public final class TelephonyPermissions {
}
}
+ // Default SMS app can always read it.
+ AppOpsManager appOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
+ if (appOps.noteOp(AppOpsManager.OPSTR_WRITE_SMS, uid, callingPackage, callingFeatureId,
+ null) == AppOpsManager.MODE_ALLOWED) {
+ return true;
+ }
// Can be read with READ_SMS too.
try {
context.enforcePermission(android.Manifest.permission.READ_SMS, pid, uid, message);
- return appOps.noteOp(AppOpsManager.OPSTR_READ_SMS, uid, callingPackage,
- callingFeatureId, null) == AppOpsManager.MODE_ALLOWED;
-
+ if (appOps.noteOp(AppOpsManager.OPSTR_READ_SMS, uid, callingPackage,
+ callingFeatureId, null) == AppOpsManager.MODE_ALLOWED) {
+ return true;
+ }
} catch (SecurityException readSmsSecurityException) {
}
// Can be read with READ_PHONE_NUMBERS too.
try {
context.enforcePermission(android.Manifest.permission.READ_PHONE_NUMBERS, pid, uid,
message);
- return appOps.noteOp(AppOpsManager.OPSTR_READ_PHONE_NUMBERS, uid, callingPackage,
- callingFeatureId, null) == AppOpsManager.MODE_ALLOWED;
-
+ if (appOps.noteOp(AppOpsManager.OPSTR_READ_PHONE_NUMBERS, uid, callingPackage,
+ callingFeatureId, null) == AppOpsManager.MODE_ALLOWED) {
+ return true;
+ }
} catch (SecurityException readPhoneNumberSecurityException) {
}
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 53aad2351a32..3d455d51dd7f 100755
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -1385,6 +1385,14 @@ public class CarrierConfigManager {
public static final String KEY_CARRIER_NAME_STRING = "carrier_name_string";
/**
+ * To override wifi calling's carrier name string using ef_pnn from sim card when SPN in empty.
+ *
+ * @hide
+ */
+ public static final String KEY_WFC_CARRIER_NAME_OVERRIDE_BY_PNN_BOOL =
+ "wfc_carrier_name_override_by_pnn_bool";
+
+ /**
* Override the SPN Display Condition 2 integer bits (lsb). B2, B1 is the last two bits of the
* spn display condition coding.
*
@@ -4008,6 +4016,7 @@ public class CarrierConfigManager {
sDefaults.putBoolean(KEY_CONFIG_WIFI_DISABLE_IN_ECBM, false);
sDefaults.putBoolean(KEY_CARRIER_NAME_OVERRIDE_BOOL, false);
sDefaults.putString(KEY_CARRIER_NAME_STRING, "");
+ sDefaults.putBoolean(KEY_WFC_CARRIER_NAME_OVERRIDE_BY_PNN_BOOL, false);
sDefaults.putInt(KEY_SPN_DISPLAY_CONDITION_OVERRIDE_INT, -1);
sDefaults.putStringArray(KEY_SPDI_OVERRIDE_STRING_ARRAY, null);
sDefaults.putStringArray(KEY_PNN_OVERRIDE_STRING_ARRAY, null);
diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java
index 991375c5bc73..b376660f839e 100644
--- a/telephony/java/android/telephony/SmsManager.java
+++ b/telephony/java/android/telephony/SmsManager.java
@@ -2978,4 +2978,29 @@ public final class SmsManager {
Log.e(TAG, "setPremiumSmsPermission() RemoteException", e);
}
}
+
+ /**
+ * Reset all cell broadcast ranges. Previously enabled ranges will become invalid after this.
+ *
+ * @return {@code true} if succeeded, otherwise {@code false}.
+ *
+ * // TODO: Unhide the API in S.
+ * @hide
+ */
+ public boolean resetAllCellBroadcastRanges() {
+ boolean success = false;
+
+ try {
+ ISms iSms = getISmsService();
+ if (iSms != null) {
+ // If getSubscriptionId() returns INVALID or an inactive subscription, we will use
+ // the default phone internally.
+ success = iSms.resetAllCellBroadcastRanges(getSubscriptionId());
+ }
+ } catch (RemoteException ex) {
+ // ignore it
+ }
+
+ return success;
+ }
}
diff --git a/telephony/java/android/telephony/SubscriptionInfo.java b/telephony/java/android/telephony/SubscriptionInfo.java
index d62cd0a63b44..11667c83bc6a 100644
--- a/telephony/java/android/telephony/SubscriptionInfo.java
+++ b/telephony/java/android/telephony/SubscriptionInfo.java
@@ -305,11 +305,14 @@ public class SubscriptionInfo implements Parcelable {
}
/**
- * Returns the ICC ID if the calling app has been granted the READ_PRIVILEGED_PHONE_STATE
- * permission, has carrier privileges (see {@link TelephonyManager#hasCarrierPrivileges}), or
- * is a device owner or profile owner that has been granted the READ_PHONE_STATE permission.
- * The profile owner is an app that owns a managed profile on the device; for more details see
- * <a href="https://developer.android.com/work/managed-profiles">Work profiles</a>. Profile
+ * Returns the ICC ID.
+ *
+ * Starting with API level 30, returns the ICC ID if the calling app has been granted the
+ * READ_PRIVILEGED_PHONE_STATE permission, has carrier privileges (see
+ * {@link TelephonyManager#hasCarrierPrivileges}), or is a device owner or profile owner that
+ * has been granted the READ_PHONE_STATE permission. The profile owner is an app that owns a
+ * managed profile on the device; for more details see <a
+ * href="https://developer.android.com/work/managed-profiles">Work profiles</a>. Profile
* owner access is deprecated and will be removed in a future release.
*
* @return the ICC ID, or an empty string if one of these requirements is not met
@@ -449,8 +452,22 @@ public class SubscriptionInfo implements Parcelable {
}
/**
- * @return the number of this subscription if the calling app has been granted the
- * READ_PHONE_NUMBERS permission, or an empty string otherwise
+ * Returns the number of this subscription.
+ *
+ * Starting with API level 30, returns the number of this subscription if the calling app meets
+ * one of the following requirements:
+ * <ul>
+ * <li>If the calling app's target SDK is API level 29 or lower and the app has been granted
+ * the READ_PHONE_STATE permission.
+ * <li>If the calling app has been granted any of READ_PRIVILEGED_PHONE_STATE,
+ * READ_PHONE_NUMBERS, or READ_SMS.
+ * <li>If the calling app has carrier privileges (see {@link
+ * TelephonyManager#hasCarrierPrivileges}).
+ * <li>If the calling app is the default SMS role holder.
+ * </ul>
+ *
+ * @return the number of this subscription, or an empty string if one of these requirements is
+ * not met
*/
public String getNumber() {
return mNumber;
@@ -670,12 +687,15 @@ public class SubscriptionInfo implements Parcelable {
}
/**
- * Returns the card string if the calling app has been granted the READ_PRIVILEGED_PHONE_STATE
- * permission, has carrier privileges (see {@link TelephonyManager#hasCarrierPrivileges}), or
- * is a device owner or profile owner on an organization owned device that has been granted the
- * READ_PHONE_STATE permission. The profile owner is an app that owns a managed profile on the
- * device; for more details see <a href="https://developer.android.com/work/managed-profiles">
- * Work profiles</a>.
+ * Returns the card string of the SIM card which contains the subscription.
+ *
+ * Starting with API level 30, returns the card string if the calling app has been granted the
+ * READ_PRIVILEGED_PHONE_STATE permission, has carrier privileges (see
+ * {@link TelephonyManager#hasCarrierPrivileges}), or is a device owner or profile owner that
+ * has been granted the READ_PHONE_STATE permission. The profile owner is an app that owns a
+ * managed profile on the device; for more details see <a
+ * href="https://developer.android.com/work/managed-profiles">Work profiles</a>. Profile
+ * owner access is deprecated and will be removed in a future release.
*
* @return the card string of the SIM card which contains the subscription or an empty string
* if these requirements are not met. The card string is the ICCID for UICCs or the EID for
diff --git a/telephony/java/com/android/internal/telephony/ISms.aidl b/telephony/java/com/android/internal/telephony/ISms.aidl
index 89f811ebf7a1..9ec3c6716a29 100644
--- a/telephony/java/com/android/internal/telephony/ISms.aidl
+++ b/telephony/java/com/android/internal/telephony/ISms.aidl
@@ -563,4 +563,14 @@ interface ISms {
* @return capacity of ICC
*/
int getSmsCapacityOnIccForSubscriber(int subId);
+
+ /**
+ * Reset all cell broadcast ranges. Previously enabled ranges will become invalid after this.
+ *
+ * @param subId Subscription index
+ * @return {@code true} if succeeded, otherwise {@code false}.
+ *
+ * @hide
+ */
+ boolean resetAllCellBroadcastRanges(int subId);
}
diff --git a/telephony/java/com/android/internal/telephony/ISmsImplBase.java b/telephony/java/com/android/internal/telephony/ISmsImplBase.java
index f1182f75cc5e..c361d5bec097 100644
--- a/telephony/java/com/android/internal/telephony/ISmsImplBase.java
+++ b/telephony/java/com/android/internal/telephony/ISmsImplBase.java
@@ -212,4 +212,9 @@ public class ISmsImplBase extends ISms.Stub {
public int getSmsCapacityOnIccForSubscriber(int subId) {
throw new UnsupportedOperationException();
}
+
+ @Override
+ public boolean resetAllCellBroadcastRanges(int subId) {
+ throw new UnsupportedOperationException();
+ }
}
diff --git a/tests/BlobStoreTestUtils/src/com/android/utils/blob/DummyBlobData.java b/tests/BlobStoreTestUtils/src/com/android/utils/blob/DummyBlobData.java
index 4a0ca664049a..2df0024bdea9 100644
--- a/tests/BlobStoreTestUtils/src/com/android/utils/blob/DummyBlobData.java
+++ b/tests/BlobStoreTestUtils/src/com/android/utils/blob/DummyBlobData.java
@@ -153,7 +153,14 @@ public class DummyBlobData {
public void writeToSession(BlobStoreManager.Session session,
long offsetBytes, long lengthBytes) throws Exception {
try (FileInputStream in = new FileInputStream(mFile)) {
- Utils.writeToSession(session, in, offsetBytes, lengthBytes);
+ Utils.writeToSession(session, in, offsetBytes, lengthBytes, lengthBytes);
+ }
+ }
+
+ public void writeToSession(BlobStoreManager.Session session,
+ long offsetBytes, long lengthBytes, long allocateBytes) throws Exception {
+ try (FileInputStream in = new FileInputStream(mFile)) {
+ Utils.writeToSession(session, in, offsetBytes, lengthBytes, allocateBytes);
}
}
diff --git a/tests/BlobStoreTestUtils/src/com/android/utils/blob/Utils.java b/tests/BlobStoreTestUtils/src/com/android/utils/blob/Utils.java
index b9bd661dfd67..ec859955694c 100644
--- a/tests/BlobStoreTestUtils/src/com/android/utils/blob/Utils.java
+++ b/tests/BlobStoreTestUtils/src/com/android/utils/blob/Utils.java
@@ -59,15 +59,15 @@ public class Utils {
public static void writeToSession(BlobStoreManager.Session session, ParcelFileDescriptor input,
long lengthBytes) throws IOException {
try (FileInputStream in = new ParcelFileDescriptor.AutoCloseInputStream(input)) {
- writeToSession(session, in, 0, lengthBytes);
+ writeToSession(session, in, 0, lengthBytes, lengthBytes);
}
}
public static void writeToSession(BlobStoreManager.Session session, FileInputStream in,
- long offsetBytes, long lengthBytes) throws IOException {
+ long offsetBytes, long lengthBytes, long allocateBytes) throws IOException {
in.getChannel().position(offsetBytes);
try (FileOutputStream out = new ParcelFileDescriptor.AutoCloseOutputStream(
- session.openWrite(offsetBytes, lengthBytes))) {
+ session.openWrite(offsetBytes, allocateBytes))) {
copy(in, out, lengthBytes);
}
}
diff --git a/tests/StagedInstallTest/Android.bp b/tests/StagedInstallTest/Android.bp
new file mode 100644
index 000000000000..c3fdd695c2b7
--- /dev/null
+++ b/tests/StagedInstallTest/Android.bp
@@ -0,0 +1,31 @@
+// 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.
+
+android_test_helper_app {
+ name: "StagedInstallInternalTestApp",
+ manifest: "app/AndroidManifest.xml",
+ srcs: ["app/src/**/*.java"],
+ static_libs: ["androidx.test.rules", "cts-install-lib"],
+ test_suites: ["general-tests"],
+}
+
+java_test_host {
+ name: "StagedInstallInternalTest",
+ srcs: ["src/**/*.java"],
+ libs: ["tradefed"],
+ static_libs: ["testng", "compatibility-tradefed"],
+ test_suites: ["general-tests"],
+ test_config: "StagedInstallInternalTest.xml",
+}
+
diff --git a/tests/StagedInstallTest/StagedInstallInternalTest.xml b/tests/StagedInstallTest/StagedInstallInternalTest.xml
new file mode 100644
index 000000000000..1b8fa672fe38
--- /dev/null
+++ b/tests/StagedInstallTest/StagedInstallInternalTest.xml
@@ -0,0 +1,33 @@
+<?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.
+ -->
+<configuration description="Runs the internal staged install tests">
+ <option name="test-suite-tag" value="StagedInstallTest" />
+ <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+ <option name="cleanup-apks" value="true" />
+ <option name="test-file-name" value="StagedInstallInternalTestApp.apk" />
+ </target_preparer>
+ <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+ <option name="run-command" value="pm uninstall com.android.cts.install.lib.testapp.A" />
+ <option name="run-command" value="pm uninstall com.android.cts.install.lib.testapp.B" />
+ <option name="teardown-command" value="pm uninstall com.android.cts.install.lib.testapp.A" />
+ <option name="teardown-command" value="pm uninstall com.android.cts.install.lib.testapp.B" />
+ </target_preparer>
+ <test class="com.android.tradefed.testtype.HostTest" >
+ <option name="class"
+ value="com.android.tests.stagedinstallinternal.host.StagedInstallInternalTest" />
+ </test>
+</configuration>
diff --git a/tests/StagedInstallTest/TEST_MAPPING b/tests/StagedInstallTest/TEST_MAPPING
new file mode 100644
index 000000000000..5a7a5a766b88
--- /dev/null
+++ b/tests/StagedInstallTest/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+ "presubmit": [
+ {
+ "name": "StagedInstallInternalTest"
+ }
+ ]
+}
diff --git a/tests/StagedInstallTest/app/AndroidManifest.xml b/tests/StagedInstallTest/app/AndroidManifest.xml
new file mode 100644
index 000000000000..a678f1ec3691
--- /dev/null
+++ b/tests/StagedInstallTest/app/AndroidManifest.xml
@@ -0,0 +1,33 @@
+<?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.tests.stagedinstallinternal" >
+
+ <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
+ <application>
+ <receiver android:name="com.android.cts.install.lib.LocalIntentSender"
+ android:exported="true" />
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="com.android.tests.stagedinstallinternal"
+ android:label="StagedInstallInternal Test"/>
+
+</manifest>
diff --git a/tests/StagedInstallTest/app/src/com/android/tests/stagedinstallinternal/StagedInstallInternalTest.java b/tests/StagedInstallTest/app/src/com/android/tests/stagedinstallinternal/StagedInstallInternalTest.java
new file mode 100644
index 000000000000..02597d548361
--- /dev/null
+++ b/tests/StagedInstallTest/app/src/com/android/tests/stagedinstallinternal/StagedInstallInternalTest.java
@@ -0,0 +1,135 @@
+/*
+ * 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.tests.stagedinstallinternal;
+
+import static com.android.cts.install.lib.InstallUtils.getPackageInstaller;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import android.Manifest;
+import android.content.pm.PackageInstaller;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.cts.install.lib.Install;
+import com.android.cts.install.lib.InstallUtils;
+import com.android.cts.install.lib.TestApp;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.nio.file.Files;
+import java.util.List;
+import java.util.function.Consumer;
+
+@RunWith(JUnit4.class)
+public class StagedInstallInternalTest {
+
+ private static final String TAG = StagedInstallInternalTest.class.getSimpleName();
+
+ private File mTestStateFile = new File(
+ InstrumentationRegistry.getInstrumentation().getContext().getFilesDir(),
+ "stagedinstall_state");
+
+ /**
+ * Adopts common shell permissions needed for staged install tests.
+ */
+ @Before
+ public void adoptShellPermissions() {
+ InstallUtils.adoptShellPermissionIdentity(
+ Manifest.permission.INSTALL_PACKAGES,
+ Manifest.permission.DELETE_PACKAGES
+ );
+ }
+
+ /**
+ * Drops shell permissions needed for staged install tests.
+ */
+ @After
+ public void dropShellPermissions() {
+ InstallUtils.dropShellPermissionIdentity();
+ }
+
+ // This is marked as @Test to take advantage of @Before/@After methods of this class. Actual
+ // purpose of this method to be called before and after each test case of
+ // com.android.test.stagedinstall.host.StagedInstallTest to reduce tests flakiness.
+ @Test
+ public void cleanUp() throws Exception {
+ Files.deleteIfExists(mTestStateFile.toPath());
+ }
+
+ @Test
+ public void testSystemServerRestartDoesNotAffectStagedSessions_Commit() throws Exception {
+ int sessionId = Install.single(TestApp.A1).setStaged().commit();
+ assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(-1);
+ assertSessionReady(sessionId);
+ storeSessionId(sessionId);
+ }
+
+ @Test
+ public void testSystemServerRestartDoesNotAffectStagedSessions_Verify() throws Exception {
+ assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(-1);
+ int sessionId = retrieveLastSessionId();
+ assertSessionReady(sessionId);
+ }
+
+ private static void assertSessionReady(int sessionId) {
+ assertSessionState(sessionId,
+ (session) -> assertThat(session.isStagedSessionReady()).isTrue());
+ }
+
+ private static void assertSessionState(
+ int sessionId, Consumer<PackageInstaller.SessionInfo> assertion) {
+ PackageInstaller packageInstaller = getPackageInstaller();
+
+ List<PackageInstaller.SessionInfo> sessions = packageInstaller.getStagedSessions();
+ boolean found = false;
+ for (PackageInstaller.SessionInfo session : sessions) {
+ if (session.getSessionId() == sessionId) {
+ assertion.accept(session);
+ found = true;
+ }
+ }
+ assertWithMessage("Expecting to find session in getStagedSession()")
+ .that(found).isTrue();
+
+ // Test also that getSessionInfo correctly returns the session.
+ PackageInstaller.SessionInfo sessionInfo = packageInstaller.getSessionInfo(sessionId);
+ assertion.accept(sessionInfo);
+ }
+
+ private void storeSessionId(int sessionId) throws Exception {
+ try (BufferedWriter writer = new BufferedWriter(new FileWriter(mTestStateFile))) {
+ writer.write("" + sessionId);
+ }
+ }
+
+ private int retrieveLastSessionId() throws Exception {
+ try (BufferedReader reader = new BufferedReader(new FileReader(mTestStateFile))) {
+ return Integer.parseInt(reader.readLine());
+ }
+ }
+}
diff --git a/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java b/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java
new file mode 100644
index 000000000000..9b432f7d0ca5
--- /dev/null
+++ b/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java
@@ -0,0 +1,111 @@
+/*
+ * 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.tests.stagedinstallinternal.host;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertTrue;
+
+import com.android.ddmlib.Log;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
+import com.android.tradefed.util.ProcessInfo;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class StagedInstallInternalTest extends BaseHostJUnit4Test {
+
+ private static final String TAG = StagedInstallInternalTest.class.getSimpleName();
+ private static final long SYSTEM_SERVER_TIMEOUT_MS = 60 * 1000;
+ private boolean mWasRoot = false;
+
+ /**
+ * Runs the given phase of a test by calling into the device.
+ * Throws an exception if the test phase fails.
+ * <p>
+ * For example, <code>runPhase("testApkOnlyEnableRollback");</code>
+ */
+ private void runPhase(String phase) throws Exception {
+ assertTrue(runDeviceTests("com.android.tests.stagedinstallinternal",
+ "com.android.tests.stagedinstallinternal.StagedInstallInternalTest",
+ phase));
+ }
+
+ // We do not assert the success of cleanup phase since it might fail due to flaky reasons.
+ private void cleanUp() throws Exception {
+ try {
+ runDeviceTests("com.android.tests.stagedinstallinternal",
+ "com.android.tests.stagedinstallinternal.StagedInstallInternalTest",
+ "cleanUp");
+ } catch (AssertionError e) {
+ Log.e(TAG, e);
+ }
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ mWasRoot = getDevice().isAdbRoot();
+ if (!mWasRoot) {
+ getDevice().enableAdbRoot();
+ }
+ cleanUp();
+ // Abandon all staged sessions
+ getDevice().executeShellCommand("pm install-abandon $(pm get-stagedsessions --only-ready "
+ + "--only-parent --only-sessionid)");
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ if (!mWasRoot) {
+ getDevice().disableAdbRoot();
+ }
+ cleanUp();
+ }
+
+ @Test
+ public void testSystemServerRestartDoesNotAffectStagedSessions() throws Exception {
+ runPhase("testSystemServerRestartDoesNotAffectStagedSessions_Commit");
+ restartSystemServer();
+ runPhase("testSystemServerRestartDoesNotAffectStagedSessions_Verify");
+ }
+
+ private void restartSystemServer() throws Exception {
+ // Restart the system server
+ long oldStartTime = getDevice().getProcessByName("system_server").getStartTime();
+ assertThat(getDevice().executeShellCommand("am restart")).contains("Restart the system");
+
+ // Wait for new system server process to start
+ long start = System.currentTimeMillis();
+ long newStartTime = oldStartTime;
+ while (System.currentTimeMillis() < start + SYSTEM_SERVER_TIMEOUT_MS) {
+ ProcessInfo newPs = getDevice().getProcessByName("system_server");
+ if (newPs != null) {
+ newStartTime = newPs.getStartTime();
+ if (newStartTime != oldStartTime) {
+ break;
+ }
+ }
+ Thread.sleep(500);
+ }
+ assertThat(newStartTime).isNotEqualTo(oldStartTime);
+ getDevice().waitForDeviceAvailable();
+ }
+}
diff --git a/tests/net/common/java/android/net/DhcpInfoTest.java b/tests/net/common/java/android/net/DhcpInfoTest.java
index bd5533f33910..4d45ad72a9b8 100644
--- a/tests/net/common/java/android/net/DhcpInfoTest.java
+++ b/tests/net/common/java/android/net/DhcpInfoTest.java
@@ -16,8 +16,7 @@
package android.net;
-import static android.net.shared.Inet4AddressUtils.inet4AddressToIntHTL;
-
+import static com.android.net.module.util.Inet4AddressUtils.inet4AddressToIntHTL;
import static com.android.testutils.MiscAssertsKt.assertFieldCountEquals;
import static com.android.testutils.ParcelUtilsKt.parcelingRoundTrip;
diff --git a/tests/net/common/java/android/net/LinkPropertiesTest.java b/tests/net/common/java/android/net/LinkPropertiesTest.java
index 0fc9be32f4cf..6eba62e63740 100644
--- a/tests/net/common/java/android/net/LinkPropertiesTest.java
+++ b/tests/net/common/java/android/net/LinkPropertiesTest.java
@@ -16,6 +16,8 @@
package android.net;
+import static android.net.RouteInfo.RTN_THROW;
+import static android.net.RouteInfo.RTN_UNICAST;
import static android.net.RouteInfo.RTN_UNREACHABLE;
import static com.android.testutils.ParcelUtilsKt.assertParcelSane;
@@ -1282,4 +1284,20 @@ public class LinkPropertiesTest {
assertTrue(lp.hasIpv6UnreachableDefaultRoute());
assertFalse(lp.hasIpv4UnreachableDefaultRoute());
}
+
+ @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
+ public void testRouteAddWithSameKey() throws Exception {
+ LinkProperties lp = new LinkProperties();
+ lp.setInterfaceName("wlan0");
+ final IpPrefix v6 = new IpPrefix("64:ff9b::/96");
+ lp.addRoute(new RouteInfo(v6, address("fe80::1"), "wlan0", RTN_UNICAST, 1280));
+ assertEquals(1, lp.getRoutes().size());
+ lp.addRoute(new RouteInfo(v6, address("fe80::1"), "wlan0", RTN_UNICAST, 1500));
+ assertEquals(1, lp.getRoutes().size());
+ final IpPrefix v4 = new IpPrefix("192.0.2.128/25");
+ lp.addRoute(new RouteInfo(v4, address("192.0.2.1"), "wlan0", RTN_UNICAST, 1460));
+ assertEquals(2, lp.getRoutes().size());
+ lp.addRoute(new RouteInfo(v4, address("192.0.2.1"), "wlan0", RTN_THROW, 1460));
+ assertEquals(2, lp.getRoutes().size());
+ }
}
diff --git a/tests/net/common/java/android/net/RouteInfoTest.java b/tests/net/common/java/android/net/RouteInfoTest.java
index 8204b494bbb8..60cac0b6b0f5 100644
--- a/tests/net/common/java/android/net/RouteInfoTest.java
+++ b/tests/net/common/java/android/net/RouteInfoTest.java
@@ -25,6 +25,7 @@ import static com.android.testutils.ParcelUtilsKt.assertParcelingIsLossless;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -56,7 +57,7 @@ public class RouteInfoTest {
private static final int INVALID_ROUTE_TYPE = -1;
private InetAddress Address(String addr) {
- return InetAddress.parseNumericAddress(addr);
+ return InetAddresses.parseNumericAddress(addr);
}
private IpPrefix Prefix(String prefix) {
@@ -391,4 +392,43 @@ public class RouteInfoTest {
r = new RouteInfo(Prefix("0.0.0.0/0"), Address("0.0.0.0"), "wlan0");
assertEquals(0, r.getMtu());
}
+
+ @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
+ public void testRouteKey() {
+ RouteInfo.RouteKey k1, k2;
+ // Only prefix, null gateway and null interface
+ k1 = new RouteInfo(Prefix("2001:db8::/128"), null).getRouteKey();
+ k2 = new RouteInfo(Prefix("2001:db8::/128"), null).getRouteKey();
+ assertEquals(k1, k2);
+ assertEquals(k1.hashCode(), k2.hashCode());
+
+ // With prefix, gateway and interface. Type and MTU does not affect RouteKey equality
+ k1 = new RouteInfo(Prefix("192.0.2.0/24"), Address("192.0.2.1"), "wlan0",
+ RTN_UNREACHABLE, 1450).getRouteKey();
+ k2 = new RouteInfo(Prefix("192.0.2.0/24"), Address("192.0.2.1"), "wlan0",
+ RouteInfo.RTN_UNICAST, 1400).getRouteKey();
+ assertEquals(k1, k2);
+ assertEquals(k1.hashCode(), k2.hashCode());
+
+ // Different scope IDs are ignored by the kernel, so we consider them equal here too.
+ k1 = new RouteInfo(Prefix("2001:db8::/64"), Address("fe80::1%1"), "wlan0").getRouteKey();
+ k2 = new RouteInfo(Prefix("2001:db8::/64"), Address("fe80::1%2"), "wlan0").getRouteKey();
+ assertEquals(k1, k2);
+ assertEquals(k1.hashCode(), k2.hashCode());
+
+ // Different prefix
+ k1 = new RouteInfo(Prefix("192.0.2.0/24"), null).getRouteKey();
+ k2 = new RouteInfo(Prefix("192.0.3.0/24"), null).getRouteKey();
+ assertNotEquals(k1, k2);
+
+ // Different gateway
+ k1 = new RouteInfo(Prefix("ff02::1/128"), Address("2001:db8::1"), null).getRouteKey();
+ k2 = new RouteInfo(Prefix("ff02::1/128"), Address("2001:db8::2"), null).getRouteKey();
+ assertNotEquals(k1, k2);
+
+ // Different interface
+ k1 = new RouteInfo(Prefix("ff02::1/128"), null, "tun0").getRouteKey();
+ k2 = new RouteInfo(Prefix("ff02::1/128"), null, "tun1").getRouteKey();
+ assertNotEquals(k1, k2);
+ }
}
diff --git a/tests/net/java/android/net/DnsPacketTest.java b/tests/net/java/android/net/DnsPacketTest.java
deleted file mode 100644
index 975abf416944..000000000000
--- a/tests/net/java/android/net/DnsPacketTest.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.Arrays;
-import java.util.List;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class DnsPacketTest {
- private void assertHeaderParses(DnsPacket.DnsHeader header, int id, int flag,
- int qCount, int aCount, int nsCount, int arCount) {
- assertEquals(header.id, id);
- assertEquals(header.flags, flag);
- assertEquals(header.getRecordCount(DnsPacket.QDSECTION), qCount);
- assertEquals(header.getRecordCount(DnsPacket.ANSECTION), aCount);
- assertEquals(header.getRecordCount(DnsPacket.NSSECTION), nsCount);
- assertEquals(header.getRecordCount(DnsPacket.ARSECTION), arCount);
- }
-
- private void assertRecordParses(DnsPacket.DnsRecord record, String dname,
- int dtype, int dclass, int ttl, byte[] rr) {
- assertEquals(record.dName, dname);
- assertEquals(record.nsType, dtype);
- assertEquals(record.nsClass, dclass);
- assertEquals(record.ttl, ttl);
- assertTrue(Arrays.equals(record.getRR(), rr));
- }
-
- class TestDnsPacket extends DnsPacket {
- TestDnsPacket(byte[] data) throws ParseException {
- super(data);
- }
-
- public DnsHeader getHeader() {
- return mHeader;
- }
- public List<DnsRecord> getRecordList(int secType) {
- return mRecords[secType];
- }
- }
-
- @Test
- public void testNullDisallowed() {
- try {
- new TestDnsPacket(null);
- fail("Exception not thrown for null byte array");
- } catch (ParseException e) {
- }
- }
-
- @Test
- public void testV4Answer() throws Exception {
- final byte[] v4blob = new byte[] {
- /* Header */
- 0x55, 0x66, /* Transaction ID */
- (byte) 0x81, (byte) 0x80, /* Flags */
- 0x00, 0x01, /* Questions */
- 0x00, 0x01, /* Answer RRs */
- 0x00, 0x00, /* Authority RRs */
- 0x00, 0x00, /* Additional RRs */
- /* Queries */
- 0x03, 0x77, 0x77, 0x77, 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6c, 0x65,
- 0x03, 0x63, 0x6f, 0x6d, 0x00, /* Name */
- 0x00, 0x01, /* Type */
- 0x00, 0x01, /* Class */
- /* Answers */
- (byte) 0xc0, 0x0c, /* Name */
- 0x00, 0x01, /* Type */
- 0x00, 0x01, /* Class */
- 0x00, 0x00, 0x01, 0x2b, /* TTL */
- 0x00, 0x04, /* Data length */
- (byte) 0xac, (byte) 0xd9, (byte) 0xa1, (byte) 0x84 /* Address */
- };
- TestDnsPacket packet = new TestDnsPacket(v4blob);
-
- // Header part
- assertHeaderParses(packet.getHeader(), 0x5566, 0x8180, 1, 1, 0, 0);
-
- // Record part
- List<DnsPacket.DnsRecord> qdRecordList =
- packet.getRecordList(DnsPacket.QDSECTION);
- assertEquals(qdRecordList.size(), 1);
- assertRecordParses(qdRecordList.get(0), "www.google.com", 1, 1, 0, null);
-
- List<DnsPacket.DnsRecord> anRecordList =
- packet.getRecordList(DnsPacket.ANSECTION);
- assertEquals(anRecordList.size(), 1);
- assertRecordParses(anRecordList.get(0), "www.google.com", 1, 1, 0x12b,
- new byte[]{ (byte) 0xac, (byte) 0xd9, (byte) 0xa1, (byte) 0x84 });
- }
-
- @Test
- public void testV6Answer() throws Exception {
- final byte[] v6blob = new byte[] {
- /* Header */
- 0x77, 0x22, /* Transaction ID */
- (byte) 0x81, (byte) 0x80, /* Flags */
- 0x00, 0x01, /* Questions */
- 0x00, 0x01, /* Answer RRs */
- 0x00, 0x00, /* Authority RRs */
- 0x00, 0x00, /* Additional RRs */
- /* Queries */
- 0x03, 0x77, 0x77, 0x77, 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6c, 0x65,
- 0x03, 0x63, 0x6f, 0x6d, 0x00, /* Name */
- 0x00, 0x1c, /* Type */
- 0x00, 0x01, /* Class */
- /* Answers */
- (byte) 0xc0, 0x0c, /* Name */
- 0x00, 0x1c, /* Type */
- 0x00, 0x01, /* Class */
- 0x00, 0x00, 0x00, 0x37, /* TTL */
- 0x00, 0x10, /* Data length */
- 0x24, 0x04, 0x68, 0x00, 0x40, 0x05, 0x08, 0x0d,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x04 /* Address */
- };
- TestDnsPacket packet = new TestDnsPacket(v6blob);
-
- // Header part
- assertHeaderParses(packet.getHeader(), 0x7722, 0x8180, 1, 1, 0, 0);
-
- // Record part
- List<DnsPacket.DnsRecord> qdRecordList =
- packet.getRecordList(DnsPacket.QDSECTION);
- assertEquals(qdRecordList.size(), 1);
- assertRecordParses(qdRecordList.get(0), "www.google.com", 28, 1, 0, null);
-
- List<DnsPacket.DnsRecord> anRecordList =
- packet.getRecordList(DnsPacket.ANSECTION);
- assertEquals(anRecordList.size(), 1);
- assertRecordParses(anRecordList.get(0), "www.google.com", 28, 1, 0x37,
- new byte[]{ 0x24, 0x04, 0x68, 0x00, 0x40, 0x05, 0x08, 0x0d,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x04 });
- }
-}
diff --git a/tests/net/java/android/net/NetworkUtilsTest.java b/tests/net/java/android/net/NetworkUtilsTest.java
index 7748288aeb05..3158cc8637e4 100644
--- a/tests/net/java/android/net/NetworkUtilsTest.java
+++ b/tests/net/java/android/net/NetworkUtilsTest.java
@@ -16,10 +16,24 @@
package android.net;
+import static android.system.OsConstants.AF_INET;
+import static android.system.OsConstants.AF_INET6;
+import static android.system.OsConstants.AF_UNIX;
+import static android.system.OsConstants.EPERM;
+import static android.system.OsConstants.SOCK_DGRAM;
+import static android.system.OsConstants.SOCK_STREAM;
+
import static junit.framework.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import android.system.ErrnoException;
+import android.system.Os;
+
import androidx.test.runner.AndroidJUnit4;
+import libcore.io.IoUtils;
+
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -125,4 +139,50 @@ public class NetworkUtilsTest {
assertEquals(BigInteger.valueOf(7l - 4 + 4 + 16 + 65536),
NetworkUtils.routedIPv6AddressCount(set));
}
+
+ private static void expectSocketSuccess(String msg, int domain, int type) {
+ try {
+ IoUtils.closeQuietly(Os.socket(domain, type, 0));
+ } catch (ErrnoException e) {
+ fail(msg + e.getMessage());
+ }
+ }
+
+ private static void expectSocketPemissionError(String msg, int domain, int type) {
+ try {
+ IoUtils.closeQuietly(Os.socket(domain, type, 0));
+ fail(msg);
+ } catch (ErrnoException e) {
+ assertEquals(msg, e.errno, EPERM);
+ }
+ }
+
+ private static void expectHasNetworking() {
+ expectSocketSuccess("Creating a UNIX socket should not have thrown ErrnoException",
+ AF_UNIX, SOCK_STREAM);
+ expectSocketSuccess("Creating a AF_INET socket shouldn't have thrown ErrnoException",
+ AF_INET, SOCK_DGRAM);
+ expectSocketSuccess("Creating a AF_INET6 socket shouldn't have thrown ErrnoException",
+ AF_INET6, SOCK_DGRAM);
+ }
+
+ private static void expectNoNetworking() {
+ expectSocketSuccess("Creating a UNIX socket should not have thrown ErrnoException",
+ AF_UNIX, SOCK_STREAM);
+ expectSocketPemissionError(
+ "Creating a AF_INET socket should have thrown ErrnoException(EPERM)",
+ AF_INET, SOCK_DGRAM);
+ expectSocketPemissionError(
+ "Creating a AF_INET6 socket should have thrown ErrnoException(EPERM)",
+ AF_INET6, SOCK_DGRAM);
+ }
+
+ @Test
+ public void testSetAllowNetworkingForProcess() {
+ expectHasNetworking();
+ NetworkUtils.setAllowNetworkingForProcess(false);
+ expectNoNetworking();
+ NetworkUtils.setAllowNetworkingForProcess(true);
+ expectHasNetworking();
+ }
}
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index c86d388a3db9..385005f90c3b 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -100,6 +100,7 @@ import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.ArgumentMatchers.startsWith;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Mockito.any;
@@ -164,6 +165,8 @@ import android.net.LinkAddress;
import android.net.LinkProperties;
import android.net.MatchAllNetworkSpecifier;
import android.net.Network;
+import android.net.NetworkAgent;
+import android.net.NetworkAgentConfig;
import android.net.NetworkCapabilities;
import android.net.NetworkFactory;
import android.net.NetworkInfo;
@@ -6800,6 +6803,30 @@ public class ConnectivityServiceTest {
assertEquals(wifiLp, mService.getActiveLinkProperties());
}
+ @Test
+ public void testLegacyExtraInfoSentToNetworkMonitor() throws Exception {
+ class TestNetworkAgent extends NetworkAgent {
+ TestNetworkAgent(Context context, Looper looper, NetworkAgentConfig config) {
+ super(context, looper, "MockAgent", new NetworkCapabilities(),
+ new LinkProperties(), 40 , config, null /* provider */);
+ }
+ }
+ final NetworkAgent naNoExtraInfo = new TestNetworkAgent(
+ mServiceContext, mCsHandlerThread.getLooper(), new NetworkAgentConfig());
+ naNoExtraInfo.register();
+ verify(mNetworkStack).makeNetworkMonitor(any(), isNull(String.class), any());
+ naNoExtraInfo.unregister();
+
+ reset(mNetworkStack);
+ final NetworkAgentConfig config =
+ new NetworkAgentConfig.Builder().setLegacyExtraInfo("legacyinfo").build();
+ final NetworkAgent naExtraInfo = new TestNetworkAgent(
+ mServiceContext, mCsHandlerThread.getLooper(), config);
+ naExtraInfo.register();
+ verify(mNetworkStack).makeNetworkMonitor(any(), eq("legacyinfo"), any());
+ naExtraInfo.unregister();
+ }
+
private void setupLocationPermissions(
int targetSdk, boolean locationToggle, String op, String perm) throws Exception {
final ApplicationInfo applicationInfo = new ApplicationInfo();
diff --git a/tests/net/java/com/android/server/connectivity/DnsManagerTest.java b/tests/net/java/com/android/server/connectivity/DnsManagerTest.java
index 0a603b8e4b19..508b5cd9cb19 100644
--- a/tests/net/java/com/android/server/connectivity/DnsManagerTest.java
+++ b/tests/net/java/com/android/server/connectivity/DnsManagerTest.java
@@ -62,6 +62,8 @@ import androidx.test.runner.AndroidJUnit4;
import com.android.internal.util.MessageUtils;
import com.android.internal.util.test.FakeSettingsProvider;
+import libcore.net.InetAddressUtils;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -103,7 +105,8 @@ public class DnsManagerTest {
@NonNull ResolverOptionsParcel expected) {
assertEquals(actual.hosts, expected.hosts);
assertEquals(actual.tcMode, expected.tcMode);
- assertFieldCountEquals(2, ResolverOptionsParcel.class);
+ assertEquals(actual.enforceDnsUid, expected.enforceDnsUid);
+ assertFieldCountEquals(3, ResolverOptionsParcel.class);
}
private void assertResolverParamsEquals(@NonNull ResolverParamsParcel actual,
@@ -379,4 +382,49 @@ public class DnsManagerTest {
assertEquals(name, dnsTransTypes.get(i));
}
}
+
+ @Test
+ public void testGetPrivateDnsConfigForNetwork() throws Exception {
+ final Network network = new Network(TEST_NETID);
+ final InetAddress dnsAddr = InetAddressUtils.parseNumericAddress("3.3.3.3");
+ final InetAddress[] tlsAddrs = new InetAddress[]{
+ InetAddressUtils.parseNumericAddress("6.6.6.6"),
+ InetAddressUtils.parseNumericAddress("2001:db8:66:66::1")
+ };
+ final String tlsName = "strictmode.com";
+ LinkProperties lp = new LinkProperties();
+ lp.addDnsServer(dnsAddr);
+
+ // The PrivateDnsConfig map is empty, so the default PRIVATE_DNS_OFF is returned.
+ PrivateDnsConfig privateDnsCfg = mDnsManager.getPrivateDnsConfig(network);
+ assertFalse(privateDnsCfg.useTls);
+ assertEquals("", privateDnsCfg.hostname);
+ assertEquals(new InetAddress[0], privateDnsCfg.ips);
+
+ // An entry with default PrivateDnsConfig is added to the PrivateDnsConfig map.
+ mDnsManager.updatePrivateDns(network, mDnsManager.getPrivateDnsConfig());
+ mDnsManager.noteDnsServersForNetwork(TEST_NETID, lp);
+ mDnsManager.updatePrivateDnsValidation(
+ new DnsManager.PrivateDnsValidationUpdate(TEST_NETID, dnsAddr, "", true));
+ mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp);
+ privateDnsCfg = mDnsManager.getPrivateDnsConfig(network);
+ assertTrue(privateDnsCfg.useTls);
+ assertEquals("", privateDnsCfg.hostname);
+ assertEquals(new InetAddress[0], privateDnsCfg.ips);
+
+ // The original entry is overwritten by a new PrivateDnsConfig.
+ mDnsManager.updatePrivateDns(network, new PrivateDnsConfig(tlsName, tlsAddrs));
+ mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp);
+ privateDnsCfg = mDnsManager.getPrivateDnsConfig(network);
+ assertTrue(privateDnsCfg.useTls);
+ assertEquals(tlsName, privateDnsCfg.hostname);
+ assertEquals(tlsAddrs, privateDnsCfg.ips);
+
+ // The network is removed, so the PrivateDnsConfig map becomes empty again.
+ mDnsManager.removeNetwork(network);
+ privateDnsCfg = mDnsManager.getPrivateDnsConfig(network);
+ assertFalse(privateDnsCfg.useTls);
+ assertEquals("", privateDnsCfg.hostname);
+ assertEquals(new InetAddress[0], privateDnsCfg.ips);
+ }
}
diff --git a/tools/stats_log_api_gen/Android.bp b/tools/stats_log_api_gen/Android.bp
index b1e2487c54fe..e3b6db08c503 100644
--- a/tools/stats_log_api_gen/Android.bp
+++ b/tools/stats_log_api_gen/Android.bp
@@ -21,7 +21,6 @@ cc_binary_host {
name: "stats-log-api-gen",
srcs: [
"Collation.cpp",
- "atoms_info_writer.cpp",
"java_writer.cpp",
"java_writer_q.cpp",
"main.cpp",
diff --git a/tools/stats_log_api_gen/Collation.cpp b/tools/stats_log_api_gen/Collation.cpp
index 958e94efcf9c..a230de46dcf3 100644
--- a/tools/stats_log_api_gen/Collation.cpp
+++ b/tools/stats_log_api_gen/Collation.cpp
@@ -52,9 +52,7 @@ AtomDecl::AtomDecl(const AtomDecl& that)
defaultState(that.defaultState),
triggerStateReset(that.triggerStateReset),
nested(that.nested),
- uidField(that.uidField),
- whitelisted(that.whitelisted),
- truncateTimestamp(that.truncateTimestamp) {
+ uidField(that.uidField) {
}
AtomDecl::AtomDecl(int c, const string& n, const string& m) : code(c), name(n), message(m) {
@@ -520,13 +518,6 @@ int collate_atoms(const Descriptor* descriptor, const string& moduleName, Atoms*
shared_ptr<AtomDecl> atomDecl =
make_shared<AtomDecl>(atomField->number(), atomField->name(), atom->name());
- if (atomField->options().GetExtension(os::statsd::allow_from_any_uid) == true) {
- atomDecl->whitelisted = true;
- if (dbg) {
- printf("%s is whitelisted\n", atomField->name().c_str());
- }
- }
-
if (atomDecl->code < PULL_ATOM_START_ID &&
atomField->options().GetExtension(os::statsd::truncate_timestamp)) {
addAnnotationToAtomDecl(atomDecl.get(), ATOM_ID_FIELD_NUMBER,
diff --git a/tools/stats_log_api_gen/Collation.h b/tools/stats_log_api_gen/Collation.h
index 043f8b1e74d8..10b34ecf5f54 100644
--- a/tools/stats_log_api_gen/Collation.h
+++ b/tools/stats_log_api_gen/Collation.h
@@ -164,10 +164,6 @@ struct AtomDecl {
int uidField = 0;
- bool whitelisted = false;
-
- bool truncateTimestamp = false;
-
AtomDecl();
AtomDecl(const AtomDecl& that);
AtomDecl(int code, const string& name, const string& message);
diff --git a/tools/stats_log_api_gen/atoms_info_writer.cpp b/tools/stats_log_api_gen/atoms_info_writer.cpp
deleted file mode 100644
index 292cb21bac30..000000000000
--- a/tools/stats_log_api_gen/atoms_info_writer.cpp
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "atoms_info_writer.h"
-
-#include <map>
-#include <set>
-#include <vector>
-
-#include "utils.h"
-
-namespace android {
-namespace stats_log_api_gen {
-
-static void write_atoms_info_header_body(FILE* out) {
- fprintf(out, "struct AtomsInfo {\n");
- fprintf(out, " const static std::set<int> kWhitelistedAtoms;\n");
- fprintf(out, "};\n");
-}
-
-static void write_atoms_info_cpp_body(FILE* out, const Atoms& atoms) {
-
- fprintf(out, "const std::set<int> AtomsInfo::kWhitelistedAtoms = {\n");
- for (AtomDeclSet::const_iterator atomIt = atoms.decls.begin(); atomIt != atoms.decls.end();
- atomIt++) {
- if ((*atomIt)->whitelisted) {
- const string constant = make_constant_name((*atomIt)->name);
- fprintf(out, " %d, // %s\n", (*atomIt)->code, constant.c_str());
- }
- }
-
- fprintf(out, "};\n");
- fprintf(out, "\n");
-
-}
-
-int write_atoms_info_header(FILE* out, const string& namespaceStr) {
- // Print prelude
- fprintf(out, "// This file is autogenerated\n");
- fprintf(out, "\n");
- fprintf(out, "#pragma once\n");
- fprintf(out, "\n");
- fprintf(out, "#include <vector>\n");
- fprintf(out, "#include <map>\n");
- fprintf(out, "#include <set>\n");
- fprintf(out, "\n");
-
- write_namespace(out, namespaceStr);
-
- write_atoms_info_header_body(out);
-
- fprintf(out, "\n");
- write_closing_namespace(out, namespaceStr);
-
- return 0;
-}
-
-int write_atoms_info_cpp(FILE* out, const Atoms& atoms, const string& namespaceStr,
- const string& importHeader) {
- // Print prelude
- fprintf(out, "// This file is autogenerated\n");
- fprintf(out, "\n");
- fprintf(out, "#include <%s>\n", importHeader.c_str());
- fprintf(out, "\n");
-
- write_namespace(out, namespaceStr);
-
- write_atoms_info_cpp_body(out, atoms);
-
- // Print footer
- fprintf(out, "\n");
- write_closing_namespace(out, namespaceStr);
-
- return 0;
-}
-
-} // namespace stats_log_api_gen
-} // namespace android
diff --git a/tools/stats_log_api_gen/atoms_info_writer.h b/tools/stats_log_api_gen/atoms_info_writer.h
deleted file mode 100644
index 09a4303eaee6..000000000000
--- a/tools/stats_log_api_gen/atoms_info_writer.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <stdio.h>
-#include <string.h>
-
-#include "Collation.h"
-
-namespace android {
-namespace stats_log_api_gen {
-
-using namespace std;
-
-int write_atoms_info_cpp(FILE* out, const Atoms& atoms, const string& namespaceStr,
- const string& importHeader);
-
-int write_atoms_info_header(FILE* out, const string& namespaceStr);
-
-} // namespace stats_log_api_gen
-} // namespace android
diff --git a/tools/stats_log_api_gen/main.cpp b/tools/stats_log_api_gen/main.cpp
index 136933b8cfb2..b888ce904b31 100644
--- a/tools/stats_log_api_gen/main.cpp
+++ b/tools/stats_log_api_gen/main.cpp
@@ -9,7 +9,6 @@
#include <vector>
#include "Collation.h"
-#include "atoms_info_writer.h"
#include "frameworks/base/cmds/statsd/src/atoms.pb.h"
#include "java_writer.h"
#include "java_writer_q.h"
@@ -30,12 +29,6 @@ static void print_usage() {
fprintf(stderr, "OPTIONS\n");
fprintf(stderr, " --cpp FILENAME the header file to output for write helpers\n");
fprintf(stderr, " --header FILENAME the cpp file to output for write helpers\n");
- fprintf(stderr,
- " --atomsInfoCpp FILENAME the header file to output for "
- "statsd metadata\n");
- fprintf(stderr,
- " --atomsInfoHeader FILENAME the cpp file to output for statsd "
- "metadata\n");
fprintf(stderr, " --help this message\n");
fprintf(stderr, " --java FILENAME the java file to output\n");
fprintf(stderr, " --module NAME optional, module name to generate outputs for\n");
@@ -49,10 +42,6 @@ static void print_usage() {
" --importHeader NAME required for cpp/jni to say which header to "
"import "
"for write helpers\n");
- fprintf(stderr,
- " --atomsInfoImportHeader NAME required for cpp to say which "
- "header to import "
- "for statsd metadata\n");
fprintf(stderr, " --javaPackage PACKAGE the package for the java file.\n");
fprintf(stderr, " required for java with module\n");
fprintf(stderr, " --javaClass CLASS the class name of the java class.\n");
@@ -74,15 +63,12 @@ static int run(int argc, char const* const* argv) {
string cppFilename;
string headerFilename;
string javaFilename;
- string atomsInfoCppFilename;
- string atomsInfoHeaderFilename;
string javaPackage;
string javaClass;
string moduleName = DEFAULT_MODULE_NAME;
string cppNamespace = DEFAULT_CPP_NAMESPACE;
string cppHeaderImport = DEFAULT_CPP_HEADER_IMPORT;
- string atomsInfoCppHeaderImport = DEFAULT_ATOMS_INFO_CPP_HEADER_IMPORT;
bool supportQ = false;
bool supportWorkSource = false;
bool compileQ = false;
@@ -148,27 +134,6 @@ static int run(int argc, char const* const* argv) {
return 1;
}
javaClass = argv[index];
- } else if (0 == strcmp("--atomsInfoHeader", argv[index])) {
- index++;
- if (index >= argc) {
- print_usage();
- return 1;
- }
- atomsInfoHeaderFilename = argv[index];
- } else if (0 == strcmp("--atomsInfoCpp", argv[index])) {
- index++;
- if (index >= argc) {
- print_usage();
- return 1;
- }
- atomsInfoCppFilename = argv[index];
- } else if (0 == strcmp("--atomsInfoImportHeader", argv[index])) {
- index++;
- if (index >= argc) {
- print_usage();
- return 1;
- }
- atomsInfoCppHeaderImport = argv[index];
} else if (0 == strcmp("--supportQ", argv[index])) {
supportQ = true;
} else if (0 == strcmp("--worksource", argv[index])) {
@@ -180,8 +145,7 @@ static int run(int argc, char const* const* argv) {
index++;
}
- if (cppFilename.size() == 0 && headerFilename.size() == 0 && javaFilename.size() == 0 &&
- atomsInfoHeaderFilename.size() == 0 && atomsInfoCppFilename.size() == 0) {
+ if (cppFilename.size() == 0 && headerFilename.size() == 0 && javaFilename.size() == 0) {
print_usage();
return 1;
}
@@ -210,29 +174,6 @@ static int run(int argc, char const* const* argv) {
collate_atom(android::os::statsd::AttributionNode::descriptor(), &attributionDecl,
&attributionSignature);
- // Write the atoms info .cpp file
- if (atomsInfoCppFilename.size() != 0) {
- FILE* out = fopen(atomsInfoCppFilename.c_str(), "w");
- if (out == NULL) {
- fprintf(stderr, "Unable to open file for write: %s\n", atomsInfoCppFilename.c_str());
- return 1;
- }
- errorCount = android::stats_log_api_gen::write_atoms_info_cpp(out, atoms, cppNamespace,
- atomsInfoCppHeaderImport);
- fclose(out);
- }
-
- // Write the atoms info .h file
- if (atomsInfoHeaderFilename.size() != 0) {
- FILE* out = fopen(atomsInfoHeaderFilename.c_str(), "w");
- if (out == NULL) {
- fprintf(stderr, "Unable to open file for write: %s\n", atomsInfoHeaderFilename.c_str());
- return 1;
- }
- errorCount = android::stats_log_api_gen::write_atoms_info_header(out, cppNamespace);
- fclose(out);
- }
-
// Write the .cpp file
if (cppFilename.size() != 0) {
FILE* out = fopen(cppFilename.c_str(), "w");
diff --git a/tools/stats_log_api_gen/test.proto b/tools/stats_log_api_gen/test.proto
index d22acc6e6598..aaa488e44fee 100644
--- a/tools/stats_log_api_gen/test.proto
+++ b/tools/stats_log_api_gen/test.proto
@@ -187,24 +187,6 @@ message GoodStateAtom3 {
optional int32 state = 3 [(android.os.statsd.state_field_option).exclusive_state = true];
}
-message WhitelistedAtom {
- optional int32 field = 1;
-}
-
-message NonWhitelistedAtom {
- optional int32 field = 1;
-}
-
-message ListedAtoms {
- oneof event {
- // Atoms can be whitelisted i.e. they can be triggered by any source
- WhitelistedAtom whitelisted_atom = 1 [(android.os.statsd.allow_from_any_uid) = true];
- // Atoms are not whitelisted by default, so they can only be triggered
- // by whitelisted sources
- NonWhitelistedAtom non_whitelisted_atom = 2;
- }
-}
-
message ModuleOneAtom {
optional int32 field = 1 [(android.os.statsd.is_uid) = true];
}
diff --git a/tools/stats_log_api_gen/test_collation.cpp b/tools/stats_log_api_gen/test_collation.cpp
index 150475223bfa..dbae58889333 100644
--- a/tools/stats_log_api_gen/test_collation.cpp
+++ b/tools/stats_log_api_gen/test_collation.cpp
@@ -225,25 +225,6 @@ TEST(CollationTest, FailOnBadBinaryFieldAtom) {
EXPECT_TRUE(errorCount > 0);
}
-TEST(CollationTest, PassOnWhitelistedAtom) {
- Atoms atoms;
- int errorCount = collate_atoms(ListedAtoms::descriptor(), DEFAULT_MODULE_NAME, &atoms);
- EXPECT_EQ(errorCount, 0);
- EXPECT_EQ(atoms.decls.size(), 2ul);
-}
-
-TEST(CollationTest, RecogniseWhitelistedAtom) {
- Atoms atoms;
- collate_atoms(ListedAtoms::descriptor(), DEFAULT_MODULE_NAME, &atoms);
- for (const auto& atomDecl : atoms.decls) {
- if (atomDecl->code == 1) {
- EXPECT_TRUE(atomDecl->whitelisted);
- } else {
- EXPECT_FALSE(atomDecl->whitelisted);
- }
- }
-}
-
TEST(CollationTest, PassOnLogFromModuleAtom) {
Atoms atoms;
int errorCount = collate_atoms(ModuleAtoms::descriptor(), DEFAULT_MODULE_NAME, &atoms);
diff --git a/tools/stats_log_api_gen/utils.h b/tools/stats_log_api_gen/utils.h
index 7d6d08ebbcbe..73e0cb838227 100644
--- a/tools/stats_log_api_gen/utils.h
+++ b/tools/stats_log_api_gen/utils.h
@@ -32,7 +32,6 @@ using namespace std;
const string DEFAULT_CPP_NAMESPACE = "android,util";
const string DEFAULT_CPP_HEADER_IMPORT = "statslog.h";
-const string DEFAULT_ATOMS_INFO_CPP_HEADER_IMPORT = "atoms_info.h";
const int JAVA_MODULE_REQUIRES_FLOAT = 0x01;
const int JAVA_MODULE_REQUIRES_ATTRIBUTION = 0x02;
diff --git a/wifi/jarjar-rules.txt b/wifi/jarjar-rules.txt
index f0555e6ec93e..e253ae25659e 100644
--- a/wifi/jarjar-rules.txt
+++ b/wifi/jarjar-rules.txt
@@ -114,7 +114,6 @@ rule fi.iki.elonen.** com.android.wifi.x.@0
## used by both framework-wifi and service-wifi ##
rule android.content.pm.BaseParceledListSlice* com.android.wifi.x.@0
rule android.content.pm.ParceledListSlice* com.android.wifi.x.@0
-rule android.net.shared.Inet4AddressUtils* com.android.wifi.x.@0
rule android.net.util.MacAddressUtils* com.android.wifi.x.@0
rule android.net.util.nsd.DnsSdTxtRecord* com.android.wifi.x.@0
rule android.os.HandlerExecutor* com.android.wifi.x.@0
@@ -123,3 +122,5 @@ rule com.android.internal.util.AsyncChannel* com.android.wifi.x.@0
rule com.android.internal.util.AsyncService* com.android.wifi.x.@0
rule com.android.internal.util.Preconditions* com.android.wifi.x.@0
rule com.android.internal.util.Protocol* com.android.wifi.x.@0
+
+rule com.android.net.module.util.** com.android.wifi.x.@0
diff --git a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
index 7b86b084baab..d35ce3c7a42c 100644
--- a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
+++ b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
@@ -769,6 +769,10 @@ public class WifiEnterpriseConfig implements Parcelable {
* certificate when the config is saved and removing the certificate when
* the config is removed.
*
+ * Note: If no certificate is set for an Enterprise configuration, either by not calling this
+ * API (or the {@link #setCaCertificates(X509Certificate[])}, or by calling it with null, then
+ * the server certificate validation is skipped - which means that the connection is not secure.
+ *
* @param cert X.509 CA certificate
* @throws IllegalArgumentException if not a CA certificate
*/
@@ -808,6 +812,11 @@ public class WifiEnterpriseConfig implements Parcelable {
* certificates when the config is saved and removing the certificates when
* the config is removed.
*
+ * Note: If no certificates are set for an Enterprise configuration, either by not calling this
+ * API (or the {@link #setCaCertificate(X509Certificate)}, or by calling it with null, then the
+ * server certificate validation is skipped - which means that the
+ * connection is not secure.
+ *
* @param certs X.509 CA certificates
* @throws IllegalArgumentException if any of the provided certificates is
* not a CA certificate
@@ -859,6 +868,13 @@ public class WifiEnterpriseConfig implements Parcelable {
* like /etc/ssl/certs. If configured, these certificates are added to the
* list of trusted CAs. ca_cert may also be included in that case, but it is
* not required.
+ *
+ * Note: If no certificate path is set for an Enterprise configuration, either by not calling
+ * this API, or by calling it with null, and no certificate is set by
+ * {@link #setCaCertificate(X509Certificate)} or {@link #setCaCertificates(X509Certificate[])},
+ * then the server certificate validation is skipped - which means that the connection is not
+ * secure.
+ *
* @param path The path for CA certificate files, or empty string to clear.
* @hide
*/
@@ -868,7 +884,7 @@ public class WifiEnterpriseConfig implements Parcelable {
}
/**
- * Get the domain_suffix_match value. See setDomSuffixMatch.
+ * Get the ca_path directive from wpa_supplicant.
* @return The path for CA certificate files, or an empty string if unset.
* @hide
*/
@@ -1061,6 +1077,12 @@ public class WifiEnterpriseConfig implements Parcelable {
/**
* Set alternate subject match. This is the substring to be matched against the
* alternate subject of the authentication server certificate.
+ *
+ * Note: If no alternate subject is set for an Enterprise configuration, either by not calling
+ * this API, or by calling it with null, or not setting domain suffix match using the
+ * {@link #setDomainSuffixMatch(String)}, then the server certificate validation is incomplete -
+ * which means that the connection is not secure.
+ *
* @param altSubjectMatch substring to be matched, for example
* DNS:server.example.com;EMAIL:server@example.com
*/
@@ -1095,6 +1117,12 @@ public class WifiEnterpriseConfig implements Parcelable {
* ORed ogether.
* <p>For example, domain_suffix_match=example.com would match test.example.com but would not
* match test-example.com.
+ *
+ * Note: If no domain suffix is set for an Enterprise configuration, either by not calling this
+ * API, or by calling it with null, or not setting alternate subject match using the
+ * {@link #setAltSubjectMatch(String)}, then the server certificate
+ * validation is incomplete - which means that the connection is not secure.
+ *
* @param domain The domain value
*/
public void setDomainSuffixMatch(String domain) {
@@ -1397,10 +1425,19 @@ public class WifiEnterpriseConfig implements Parcelable {
if (mEapMethod != Eap.PEAP && mEapMethod != Eap.TLS && mEapMethod != Eap.TTLS) {
return false;
}
- if (!mIsAppInstalledCaCert && TextUtils.isEmpty(getCaPath())) {
+ if (TextUtils.isEmpty(getAltSubjectMatch())
+ && TextUtils.isEmpty(getDomainSuffixMatch())) {
+ // Both subject and domain match are not set, it's insecure.
return true;
}
- return TextUtils.isEmpty(getAltSubjectMatch()) && TextUtils.isEmpty(
- getDomainSuffixMatch());
+ if (mIsAppInstalledCaCert) {
+ // CA certificate is installed by App, it's secure.
+ return false;
+ }
+ if (getCaCertificateAliases() != null) {
+ // CA certificate alias from keyStore is set, it's secure.
+ return false;
+ }
+ return TextUtils.isEmpty(getCaPath());
}
}
diff --git a/wifi/java/android/net/wifi/WifiInfo.java b/wifi/java/android/net/wifi/WifiInfo.java
index b841921355e9..53883674e058 100644
--- a/wifi/java/android/net/wifi/WifiInfo.java
+++ b/wifi/java/android/net/wifi/WifiInfo.java
@@ -22,12 +22,13 @@ import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.net.NetworkInfo.DetailedState;
-import android.net.shared.Inet4AddressUtils;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
+import com.android.net.module.util.Inet4AddressUtils;
+
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 5f46cb3fa642..fb6af5b550b0 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -928,19 +928,26 @@ public class WifiManager {
/**
* Broadcast intent action indicating that the configured networks changed.
- * This can be as a result of adding/updating/deleting a network. If
- * {@link #EXTRA_MULTIPLE_NETWORKS_CHANGED} is set to true the new configuration
- * can be retreived with the {@link #EXTRA_WIFI_CONFIGURATION} extra. If multiple
- * Wi-Fi configurations changed, {@link #EXTRA_WIFI_CONFIGURATION} will not be present.
+ * This can be as a result of adding/updating/deleting a network.
+ * <br />
+ * {@link #EXTRA_CHANGE_REASON} contains whether the configuration was added/changed/removed.
+ * {@link #EXTRA_WIFI_CONFIGURATION} is never set starting in Android 11.
+ * {@link #EXTRA_MULTIPLE_NETWORKS_CHANGED} is set for backwards compatibility reasons, but
+ * its value is always true, even if only a single network changed.
+ * <br />
+ * The {@link android.Manifest.permission#ACCESS_WIFI_STATE ACCESS_WIFI_STATE} permission is
+ * required to receive this broadcast.
+ *
* @hide
*/
@SystemApi
public static final String CONFIGURED_NETWORKS_CHANGED_ACTION =
"android.net.wifi.CONFIGURED_NETWORKS_CHANGE";
/**
- * The lookup key for a (@link android.net.wifi.WifiConfiguration} object representing
+ * The lookup key for a {@link android.net.wifi.WifiConfiguration} object representing
* the changed Wi-Fi configuration when the {@link #CONFIGURED_NETWORKS_CHANGED_ACTION}
* broadcast is sent.
+ * Note: this extra is never set starting in Android 11.
* @hide
*/
@SystemApi
@@ -948,14 +955,16 @@ public class WifiManager {
/**
* Multiple network configurations have changed.
* @see #CONFIGURED_NETWORKS_CHANGED_ACTION
- *
+ * Note: this extra is always true starting in Android 11.
* @hide
*/
@SystemApi
public static final String EXTRA_MULTIPLE_NETWORKS_CHANGED = "multipleChanges";
/**
* The lookup key for an integer indicating the reason a Wi-Fi network configuration
- * has changed. Only present if {@link #EXTRA_MULTIPLE_NETWORKS_CHANGED} is {@code false}
+ * has changed. One of {@link #CHANGE_REASON_ADDED}, {@link #CHANGE_REASON_REMOVED},
+ * {@link #CHANGE_REASON_CONFIG_CHANGE}.
+ *
* @see #CONFIGURED_NETWORKS_CHANGED_ACTION
* @hide
*/
@@ -1894,9 +1903,10 @@ public class WifiManager {
* for a detailed explanation of the parameters.
* When the device decides to connect to one of the provided network suggestions, platform sends
* a directed broadcast {@link #ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION} to the app if
- * the network was created with {@link WifiNetworkSuggestion.Builder
- * #setIsAppInteractionRequired()} flag set and the app holds
- * {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION} permission.
+ * the network was created with
+ * {@link WifiNetworkSuggestion.Builder#setIsAppInteractionRequired(boolean)} flag set and the
+ * app holds {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION}
+ * permission.
*<p>
* NOTE:
* <li> These networks are just a suggestion to the platform. The platform will ultimately
diff --git a/wifi/tests/src/android/net/wifi/WifiEnterpriseConfigTest.java b/wifi/tests/src/android/net/wifi/WifiEnterpriseConfigTest.java
index 268645c85cae..62485ecb6f7b 100644
--- a/wifi/tests/src/android/net/wifi/WifiEnterpriseConfigTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiEnterpriseConfigTest.java
@@ -565,6 +565,13 @@ public class WifiEnterpriseConfigTest {
secureConfig.setCaCertificate(FakeKeys.CA_CERT0);
secureConfig.setDomainSuffixMatch(TEST_DOMAIN_SUFFIX_MATCH);
assertFalse(secureConfig.isInsecure());
+
+ WifiEnterpriseConfig secureConfigWithCaAlias = new WifiEnterpriseConfig();
+ secureConfigWithCaAlias.setEapMethod(Eap.PEAP);
+ secureConfigWithCaAlias.setPhase2Method(Phase2.MSCHAPV2);
+ secureConfigWithCaAlias.setCaCertificateAliases(new String[]{"alias1", "alisa2"});
+ secureConfigWithCaAlias.setDomainSuffixMatch(TEST_DOMAIN_SUFFIX_MATCH);
+ assertFalse(secureConfigWithCaAlias.isInsecure());
}
}