summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ApiDocs.bp3
-rw-r--r--core/api/current.txt18
-rw-r--r--core/api/module-lib-current.txt1
-rw-r--r--core/api/system-current.txt53
-rw-r--r--core/api/test-current.txt13
-rw-r--r--core/java/android/accounts/AccountManager.java3
-rw-r--r--core/java/android/app/ActivityThread.java33
-rw-r--r--core/java/android/app/ApplicationExitInfo.java12
-rw-r--r--core/java/android/app/BroadcastOptions.java135
-rw-r--r--core/java/android/app/ForegroundServiceTypePolicy.java16
-rw-r--r--core/java/android/app/GameManager.java75
-rw-r--r--core/java/android/app/GameModeConfiguration.aidl (renamed from core/java/android/app/timezone/ICallback.aidl)15
-rw-r--r--core/java/android/app/GameModeConfiguration.java192
-rw-r--r--core/java/android/app/GameModeInfo.java220
-rw-r--r--core/java/android/app/IApplicationThread.aidl1
-rw-r--r--core/java/android/app/IGameManagerService.aidl16
-rw-r--r--core/java/android/app/IGameModeListener.aidl25
-rw-r--r--core/java/android/app/IWallpaperManager.aidl11
-rw-r--r--core/java/android/app/Service.java9
-rw-r--r--core/java/android/app/SystemServiceRegistry.java8
-rw-r--r--core/java/android/app/WallpaperManager.java138
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java28
-rw-r--r--core/java/android/app/backup/BackupManagerMonitor.java18
-rw-r--r--core/java/android/app/backup/BackupTransport.java2
-rw-r--r--core/java/android/app/timezone/Callback.java80
-rw-r--r--core/java/android/app/timezone/DistroFormatVersion.java120
-rw-r--r--core/java/android/app/timezone/DistroRulesVersion.java132
-rw-r--r--core/java/android/app/timezone/IRulesManager.aidl84
-rw-r--r--core/java/android/app/timezone/OWNERS4
-rw-r--r--core/java/android/app/timezone/RulesManager.java235
-rw-r--r--core/java/android/app/timezone/RulesState.java302
-rw-r--r--core/java/android/app/timezone/RulesUpdaterContract.java89
-rw-r--r--core/java/android/app/timezone/Utils.java67
-rw-r--r--core/java/android/content/Context.java10
-rw-r--r--core/java/android/content/IntentFilter.java488
-rw-r--r--core/java/android/credentials/ui/Entry.java8
-rw-r--r--core/java/android/credentials/ui/ProviderPendingIntentResponse.java2
-rw-r--r--core/java/android/hardware/OverlayProperties.aidl (renamed from core/java/android/app/timezone/RulesState.aidl)8
-rw-r--r--core/java/android/hardware/OverlayProperties.java98
-rw-r--r--core/java/android/hardware/camera2/CameraCharacteristics.java72
-rw-r--r--core/java/android/hardware/display/DisplayManagerGlobal.java9
-rw-r--r--core/java/android/hardware/display/IDisplayManager.aidl4
-rw-r--r--core/java/android/hardware/input/InputManager.java26
-rw-r--r--core/java/android/hardware/input/VirtualTouchEvent.java9
-rw-r--r--core/java/android/hardware/radio/RadioManager.java5
-rw-r--r--core/java/android/net/vcn/VcnManager.java13
-rw-r--r--core/java/android/os/Binder.java18
-rw-r--r--core/java/android/os/ServiceManager.java2
-rw-r--r--core/java/android/os/storage/StorageManager.java16
-rw-r--r--core/java/android/provider/Settings.java9
-rw-r--r--core/java/android/service/wallpaper/IWallpaperEngine.aidl1
-rw-r--r--core/java/android/service/wallpaper/WallpaperService.java37
-rw-r--r--core/java/android/view/Display.java7
-rw-r--r--core/java/android/view/MotionEvent.java19
-rw-r--r--core/java/android/view/SurfaceControl.java10
-rw-r--r--core/java/android/view/SurfaceView.java184
-rw-r--r--core/java/android/view/ViewConfiguration.java1
-rw-r--r--core/java/android/view/accessibility/AccessibilityNodeInfo.java61
-rw-r--r--core/java/android/window/BackNavigationInfo.java15
-rw-r--r--core/java/com/android/internal/protolog/BaseProtoLogImpl.java14
-rw-r--r--core/java/com/android/internal/protolog/common/LogDataType.java3
-rw-r--r--core/java/com/android/internal/protolog/common/ProtoLog.java7
-rw-r--r--core/java/com/android/internal/statusbar/IStatusBar.aidl3
-rw-r--r--core/java/com/android/internal/statusbar/IStatusBarService.aidl3
-rw-r--r--core/jni/Android.bp1
-rw-r--r--core/jni/AndroidRuntime.cpp2
-rw-r--r--core/jni/OWNERS2
-rw-r--r--core/jni/android_hardware_OverlayProperties.cpp147
-rw-r--r--core/jni/android_media_AudioFormat.h16
-rw-r--r--core/jni/android_util_Binder.cpp6
-rw-r--r--core/jni/android_view_SurfaceControl.cpp12
-rw-r--r--core/jni/include/android_runtime/android_hardware_OverlayProperties.h31
-rw-r--r--core/proto/android/content/intent.proto2
-rw-r--r--core/proto/android/server/windowmanagerservice.proto9
-rw-r--r--core/res/AndroidManifest.xml17
-rw-r--r--core/res/res/values/strings.xml3
-rw-r--r--core/res/res/values/symbols.xml1
-rw-r--r--core/tests/BroadcastRadioTests/src/android/hardware/radio/tests/unittests/RadioManagerTest.java36
-rw-r--r--core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImplTest.java5
-rw-r--r--core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/TunerSessionTest.java18
-rw-r--r--core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/BroadcastRadioServiceHidlTest.java6
-rw-r--r--core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/ProgramInfoCacheTest.java4
-rw-r--r--core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/StartProgramListUpdatesFanoutTest.java20
-rw-r--r--core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/TunerSessionHidlTest.java15
-rw-r--r--core/tests/GameManagerTests/src/android/app/GameManagerTests.java46
-rw-r--r--core/tests/GameManagerTests/src/android/app/GameModeConfigurationTest.java94
-rw-r--r--core/tests/GameManagerTests/src/android/app/GameModeInfoTest.java87
-rw-r--r--core/tests/coretests/src/android/app/timezone/DistroFormatVersionTest.java85
-rw-r--r--core/tests/coretests/src/android/app/timezone/DistroRulesVersionTest.java85
-rw-r--r--core/tests/coretests/src/android/app/timezone/OWNERS2
-rw-r--r--core/tests/coretests/src/android/app/timezone/RulesStateTest.java146
-rw-r--r--core/tests/coretests/src/android/app/timezone/RulesUpdaterContractTest.java87
-rw-r--r--core/tests/coretests/src/android/hardware/input/VirtualTouchEventTest.java6
-rw-r--r--core/tests/coretests/src/android/os/BinderTest.java10
-rw-r--r--core/tests/coretests/src/android/view/accessibility/AccessibilityNodeInfoTest.java2
-rw-r--r--data/etc/Android.bp6
-rw-r--r--graphics/java/android/graphics/HardwareRenderer.java6
-rw-r--r--libs/WindowManager/Shell/res/values/strings.xml4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationAdapter.java36
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java17
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java43
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java11
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java5
-rw-r--r--location/java/android/location/GnssMeasurementsEvent.java50
-rw-r--r--media/java/android/media/AudioDeviceInfo.java30
-rw-r--r--media/java/android/media/AudioFormat.java77
-rw-r--r--media/java/android/media/AudioSystem.java4
-rw-r--r--media/java/android/media/ExifInterface.java15
-rw-r--r--media/java/android/media/MediaRouter2.java12
-rw-r--r--media/java/android/media/audio/common/AidlConversion.java2
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/ExifInterfaceTest.java62
-rw-r--r--media/tests/MediaRouter/AndroidTest.xml2
-rw-r--r--packages/CompanionDeviceManager/Android.bp1
-rw-r--r--packages/CompanionDeviceManager/res/drawable-night/ic_permission_app_streaming.xml (renamed from packages/CompanionDeviceManager/res/drawable-night/ic_apps.xml)0
-rw-r--r--packages/CompanionDeviceManager/res/drawable-night/ic_permission_calendar.xml25
-rw-r--r--packages/CompanionDeviceManager/res/drawable-night/ic_permission_contacts.xml25
-rw-r--r--packages/CompanionDeviceManager/res/drawable-night/ic_permission_nearby_devices.xml25
-rw-r--r--packages/CompanionDeviceManager/res/drawable-night/ic_permission_notifications.xml (renamed from packages/CompanionDeviceManager/res/drawable-night/ic_notifications.xml)0
-rw-r--r--packages/CompanionDeviceManager/res/drawable-night/ic_permission_phone.xml25
-rw-r--r--packages/CompanionDeviceManager/res/drawable-night/ic_permission_sms.xml25
-rw-r--r--packages/CompanionDeviceManager/res/drawable-night/ic_permission_storage.xml (renamed from packages/CompanionDeviceManager/res/drawable-night/ic_storage.xml)0
-rw-r--r--packages/CompanionDeviceManager/res/drawable/btn_expand_less.xml24
-rw-r--r--packages/CompanionDeviceManager/res/drawable/btn_expand_more.xml24
-rw-r--r--packages/CompanionDeviceManager/res/drawable/ic_device_other.xml3
-rw-r--r--packages/CompanionDeviceManager/res/drawable/ic_permission_app_streaming.xml (renamed from packages/CompanionDeviceManager/res/drawable/ic_apps.xml)0
-rw-r--r--packages/CompanionDeviceManager/res/drawable/ic_permission_calendar.xml24
-rw-r--r--packages/CompanionDeviceManager/res/drawable/ic_permission_contacts.xml25
-rw-r--r--packages/CompanionDeviceManager/res/drawable/ic_permission_nearby_devices.xml25
-rw-r--r--packages/CompanionDeviceManager/res/drawable/ic_permission_notifications.xml (renamed from packages/CompanionDeviceManager/res/drawable/ic_notifications.xml)0
-rw-r--r--packages/CompanionDeviceManager/res/drawable/ic_permission_phone.xml24
-rw-r--r--packages/CompanionDeviceManager/res/drawable/ic_permission_sms.xml25
-rw-r--r--packages/CompanionDeviceManager/res/drawable/ic_permission_storage.xml (renamed from packages/CompanionDeviceManager/res/drawable/ic_storage.xml)0
-rw-r--r--packages/CompanionDeviceManager/res/drawable/ic_permission_watch.xml25
-rw-r--r--packages/CompanionDeviceManager/res/layout/activity_confirmation.xml39
-rw-r--r--packages/CompanionDeviceManager/res/layout/helper_confirmation.xml3
-rw-r--r--packages/CompanionDeviceManager/res/layout/list_item_device.xml2
-rw-r--r--packages/CompanionDeviceManager/res/layout/list_item_permission.xml27
-rw-r--r--packages/CompanionDeviceManager/res/values/strings.xml76
-rw-r--r--packages/CompanionDeviceManager/res/values/styles.xml19
-rw-r--r--packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java148
-rw-r--r--packages/CompanionDeviceManager/src/com/android/companiondevicemanager/PermissionListAdapter.java85
-rw-r--r--packages/CredentialManager/res/values/strings.xml12
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt64
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorActivity.kt43
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt34
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/common/ProviderActivityResult.kt24
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt266
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialViewModel.kt107
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateModel.kt16
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt11
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialViewModel.kt45
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/getflow/GetModel.kt20
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/jetpack/provider/CredentialEntryUi.kt4
-rw-r--r--packages/SettingsLib/Spa/build.gradle4
-rw-r--r--packages/SettingsLib/Spa/gallery/AndroidManifest.xml7
-rw-r--r--packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsDimension.kt3
-rw-r--r--packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsTypography.kt4
-rw-r--r--packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/button/ActionButtons.kt8
-rw-r--r--packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/Text.kt14
-rw-r--r--packages/SettingsLib/Spa/tests/Android.bp7
-rw-r--r--packages/SettingsLib/Spa/tests/build.gradle5
-rw-r--r--packages/SettingsLib/Spa/testutils/Android.bp5
-rw-r--r--packages/SettingsLib/Spa/testutils/build.gradle5
-rw-r--r--packages/SettingsLib/Spa/testutils/src/com/android/settingslib/spa/testutils/ComposeContentTestRuleExt.kt41
-rw-r--r--packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppInfo.kt2
-rw-r--r--packages/SettingsLib/SpaPrivileged/tests/Android.bp3
-rw-r--r--packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppInfoTest.kt115
-rw-r--r--packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java1
-rw-r--r--packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java1
-rw-r--r--packages/SystemUI/Android.bp99
-rw-r--r--packages/SystemUI/customization/res/values-h700dp/dimens.xml (renamed from packages/SystemUI/res/values-h700dp/dimens.xml)4
-rw-r--r--packages/SystemUI/customization/res/values-h800dp/dimens.xml (renamed from data/etc/com.android.timezone.updater.xml)14
-rw-r--r--packages/SystemUI/customization/res/values/dimens.xml4
-rw-r--r--packages/SystemUI/docs/device-entry/quickaffordance.md94
-rw-r--r--packages/SystemUI/res/layout-sw600dp/global_actions_controls_list_view.xml30
-rw-r--r--packages/SystemUI/res/layout/controls_fullscreen.xml15
-rw-r--r--packages/SystemUI/res/layout/controls_with_favorites.xml26
-rw-r--r--packages/SystemUI/res/values-af/strings.xml72
-rw-r--r--packages/SystemUI/res/values-am/strings.xml45
-rw-r--r--packages/SystemUI/res/values-ar/strings.xml72
-rw-r--r--packages/SystemUI/res/values-as/strings.xml39
-rw-r--r--packages/SystemUI/res/values-az/strings.xml39
-rw-r--r--packages/SystemUI/res/values-b+sr+Latn/strings.xml72
-rw-r--r--packages/SystemUI/res/values-be/strings.xml72
-rw-r--r--packages/SystemUI/res/values-bg/strings.xml39
-rw-r--r--packages/SystemUI/res/values-bn/strings.xml39
-rw-r--r--packages/SystemUI/res/values-bs/strings.xml38
-rw-r--r--packages/SystemUI/res/values-ca/strings.xml76
-rw-r--r--packages/SystemUI/res/values-cs/strings.xml39
-rw-r--r--packages/SystemUI/res/values-da/strings.xml39
-rw-r--r--packages/SystemUI/res/values-de/strings.xml39
-rw-r--r--packages/SystemUI/res/values-el/strings.xml38
-rw-r--r--packages/SystemUI/res/values-en-rAU/strings.xml20
-rw-r--r--packages/SystemUI/res/values-en-rCA/strings.xml258
-rw-r--r--packages/SystemUI/res/values-en-rGB/strings.xml20
-rw-r--r--packages/SystemUI/res/values-en-rIN/strings.xml20
-rw-r--r--packages/SystemUI/res/values-en-rXC/strings.xml20
-rw-r--r--packages/SystemUI/res/values-es-rUS/strings.xml39
-rw-r--r--packages/SystemUI/res/values-es/strings.xml39
-rw-r--r--packages/SystemUI/res/values-et/strings.xml72
-rw-r--r--packages/SystemUI/res/values-eu/strings.xml39
-rw-r--r--packages/SystemUI/res/values-fa/strings.xml39
-rw-r--r--packages/SystemUI/res/values-fi/strings.xml39
-rw-r--r--packages/SystemUI/res/values-fr-rCA/strings.xml38
-rw-r--r--packages/SystemUI/res/values-fr/strings.xml39
-rw-r--r--packages/SystemUI/res/values-gl/strings.xml66
-rw-r--r--packages/SystemUI/res/values-gu/strings.xml39
-rw-r--r--packages/SystemUI/res/values-h800dp/dimens.xml3
-rw-r--r--packages/SystemUI/res/values-hi/strings.xml39
-rw-r--r--packages/SystemUI/res/values-hr/strings.xml38
-rw-r--r--packages/SystemUI/res/values-hu/strings.xml39
-rw-r--r--packages/SystemUI/res/values-hy/strings.xml39
-rw-r--r--packages/SystemUI/res/values-in/strings.xml39
-rw-r--r--packages/SystemUI/res/values-is/strings.xml39
-rw-r--r--packages/SystemUI/res/values-it/strings.xml39
-rw-r--r--packages/SystemUI/res/values-iw/strings.xml36
-rw-r--r--packages/SystemUI/res/values-ja/strings.xml37
-rw-r--r--packages/SystemUI/res/values-ka/strings.xml38
-rw-r--r--packages/SystemUI/res/values-kk/strings.xml39
-rw-r--r--packages/SystemUI/res/values-km/strings.xml39
-rw-r--r--packages/SystemUI/res/values-kn/strings.xml39
-rw-r--r--packages/SystemUI/res/values-ko/strings.xml39
-rw-r--r--packages/SystemUI/res/values-ky/strings.xml39
-rw-r--r--packages/SystemUI/res/values-lo/strings.xml39
-rw-r--r--packages/SystemUI/res/values-lt/strings.xml39
-rw-r--r--packages/SystemUI/res/values-lv/strings.xml45
-rw-r--r--packages/SystemUI/res/values-mk/strings.xml38
-rw-r--r--packages/SystemUI/res/values-ml/strings.xml39
-rw-r--r--packages/SystemUI/res/values-mn/strings.xml38
-rw-r--r--packages/SystemUI/res/values-mr/strings.xml39
-rw-r--r--packages/SystemUI/res/values-ms/strings.xml71
-rw-r--r--packages/SystemUI/res/values-my/strings.xml43
-rw-r--r--packages/SystemUI/res/values-nb/strings.xml39
-rw-r--r--packages/SystemUI/res/values-ne/strings.xml39
-rw-r--r--packages/SystemUI/res/values-nl/strings.xml39
-rw-r--r--packages/SystemUI/res/values-or/strings.xml71
-rw-r--r--packages/SystemUI/res/values-pa/strings.xml39
-rw-r--r--packages/SystemUI/res/values-pl/strings.xml72
-rw-r--r--packages/SystemUI/res/values-pt-rBR/strings.xml39
-rw-r--r--packages/SystemUI/res/values-pt-rPT/strings.xml35
-rw-r--r--packages/SystemUI/res/values-pt/strings.xml39
-rw-r--r--packages/SystemUI/res/values-ro/strings.xml38
-rw-r--r--packages/SystemUI/res/values-ru/strings.xml39
-rw-r--r--packages/SystemUI/res/values-si/strings.xml72
-rw-r--r--packages/SystemUI/res/values-sk/strings.xml39
-rw-r--r--packages/SystemUI/res/values-sl/strings.xml72
-rw-r--r--packages/SystemUI/res/values-sq/strings.xml39
-rw-r--r--packages/SystemUI/res/values-sr/strings.xml72
-rw-r--r--packages/SystemUI/res/values-sv/strings.xml39
-rw-r--r--packages/SystemUI/res/values-sw/strings.xml39
-rw-r--r--packages/SystemUI/res/values-sw600dp-land/dimens.xml1
-rw-r--r--packages/SystemUI/res/values-ta/strings.xml39
-rw-r--r--packages/SystemUI/res/values-te/strings.xml39
-rw-r--r--packages/SystemUI/res/values-th/strings.xml35
-rw-r--r--packages/SystemUI/res/values-tl/strings.xml38
-rw-r--r--packages/SystemUI/res/values-tr/strings.xml39
-rw-r--r--packages/SystemUI/res/values-uk/strings.xml39
-rw-r--r--packages/SystemUI/res/values-ur/strings.xml72
-rw-r--r--packages/SystemUI/res/values-uz/strings.xml38
-rw-r--r--packages/SystemUI/res/values-vi/strings.xml39
-rw-r--r--packages/SystemUI/res/values-zh-rCN/strings.xml41
-rw-r--r--packages/SystemUI/res/values-zh-rHK/strings.xml39
-rw-r--r--packages/SystemUI/res/values-zh-rTW/strings.xml39
-rw-r--r--packages/SystemUI/res/values-zu/strings.xml72
-rw-r--r--packages/SystemUI/res/values/strings.xml49
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/keyguard/data/content/KeyguardQuickAffordanceProviderContract.kt21
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/navigationbar/RegionSamplingHelper.java4
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardConstants.java1
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java4
-rw-r--r--packages/SystemUI/src/com/android/keyguard/logging/BiometricMessageDeferralLogger.kt4
-rw-r--r--packages/SystemUI/src/com/android/keyguard/logging/BiometricUnlockLogger.kt174
-rw-r--r--packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt7
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/controller/ControlsController.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/controller/ControlsControllerImpl.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/controller/StructureInfo.kt7
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/management/AppAdapter.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/ui/ControlsActivity.kt7
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiController.kt42
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt306
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/ui/PanelTaskViewController.kt102
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/dump/DumpHandler.kt9
-rw-r--r--packages/SystemUI/src/com/android/systemui/dump/DumpManager.kt89
-rw-r--r--packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebugStartable.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsReleaseStartable.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/flags/Flags.kt7
-rw-r--r--packages/SystemUI/src/com/android/systemui/globalactions/MinHeightScrollView.java43
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardQuickAffordanceProvider.kt19
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfig.kt33
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceConfig.kt73
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfig.kt24
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfig.kt75
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepository.kt65
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractor.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/shared/model/KeyguardQuickAffordancePickerRepresentation.kt18
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBouncerViewBinder.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBouncerViewModel.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/log/dagger/BiometricLog.java (renamed from packages/SystemUI/src/com/android/systemui/log/dagger/BiometricMessagesLog.java)2
-rw-r--r--packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/qrcodescanner/controller/QRCodeScannerController.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSFragment.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt10
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/QRCodeScannerTile.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java82
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/transition/ShadeTransitionController.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/transition/SplitShadeOverScroller.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java17
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/SplitShadeLockScreenOverScroller.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/ShadeListBuilderLogger.kt17
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableOutlineView.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java113
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/LetterboxAppearanceCalculator.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImpl.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/unfold/UnfoldLightRevealOverlayAnimation.kt10
-rw-r--r--packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserInteractor.kt86
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java15
-rw-r--r--packages/SystemUI/tests/robolectric/config/robolectric.properties16
-rw-r--r--packages/SystemUI/tests/robolectric/src/com/android/systemui/robotests/SysuiResourceLoadingTest.java35
-rw-r--r--packages/SystemUI/tests/robolectric/src/com/android/systemui/robotests/SysuiRoboBase.java (renamed from services/permission/java/com/android/server/permission/ModernPermissionManagerServiceImpl.kt)17
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/controls/management/AppAdapterTest.kt34
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsFavoritingActivityTest.kt3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsUiControllerImplTest.kt79
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/controls/ui/PanelTaskViewControllerTest.kt154
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/controls/ui/SelectionItemTest.kt112
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/dump/DumpHandlerTest.kt28
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/dump/DumpManagerTest.kt221
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardQuickAffordanceProviderTest.kt1
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigParameterizedStateTest.kt23
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfigTest.kt30
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfigTest.kt43
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt34
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorParameterizedTest.kt1
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt1
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractorTest.kt3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt1
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qrcodescanner/controller/QRCodeScannerControllerTest.java39
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java18
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt51
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QRCodeScannerTileTest.java8
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogControllerTest.java24
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/shade/CombinedShadeHeaderConstraintsTest.kt20
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java8
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java10
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/UserInteractorTest.kt88
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/StatusBarUserChipViewModelTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModelTest.kt6
-rw-r--r--services/backup/java/com/android/server/backup/fullbackup/FullBackupEngine.java12
-rw-r--r--services/backup/java/com/android/server/backup/fullbackup/PerformAdbBackupTask.java3
-rw-r--r--services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java3
-rw-r--r--services/backup/java/com/android/server/backup/keyvalue/KeyValueBackupTask.java3
-rw-r--r--services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java10
-rw-r--r--services/backup/java/com/android/server/backup/utils/BackupManagerMonitorUtils.java61
-rw-r--r--services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java7
-rw-r--r--services/core/java/com/android/server/VcnManagementService.java109
-rw-r--r--services/core/java/com/android/server/accounts/AccountManagerService.java16
-rw-r--r--services/core/java/com/android/server/am/ActiveServices.java112
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerConstants.java28
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java26
-rw-r--r--services/core/java/com/android/server/am/BroadcastQueueImpl.java5
-rw-r--r--services/core/java/com/android/server/am/BroadcastQueueModernImpl.java6
-rw-r--r--services/core/java/com/android/server/am/BroadcastRecord.java35
-rw-r--r--services/core/java/com/android/server/am/OomAdjuster.java388
-rw-r--r--services/core/java/com/android/server/am/ProcessServiceRecord.java58
-rw-r--r--services/core/java/com/android/server/am/ServiceRecord.java17
-rw-r--r--services/core/java/com/android/server/am/UidRecord.java2
-rw-r--r--services/core/java/com/android/server/app/GameManagerService.java250
-rw-r--r--services/core/java/com/android/server/app/GameManagerSettings.java13
-rw-r--r--services/core/java/com/android/server/audio/AudioService.java11
-rw-r--r--services/core/java/com/android/server/broadcastradio/RadioServiceUserController.java56
-rw-r--r--services/core/java/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImpl.java8
-rw-r--r--services/core/java/com/android/server/broadcastradio/aidl/RadioModule.java15
-rw-r--r--services/core/java/com/android/server/broadcastradio/aidl/TunerSession.java46
-rw-r--r--services/core/java/com/android/server/broadcastradio/hal1/BroadcastRadioService.java14
-rw-r--r--services/core/java/com/android/server/broadcastradio/hal1/Convert.java3
-rw-r--r--services/core/java/com/android/server/broadcastradio/hal1/Tuner.java49
-rw-r--r--services/core/java/com/android/server/broadcastradio/hal1/TunerCallback.java3
-rw-r--r--services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java6
-rw-r--r--services/core/java/com/android/server/broadcastradio/hal2/ProgramInfoCache.java2
-rw-r--r--services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java19
-rw-r--r--services/core/java/com/android/server/broadcastradio/hal2/TunerSession.java47
-rw-r--r--services/core/java/com/android/server/devicestate/DeviceStateManagerService.java22
-rw-r--r--services/core/java/com/android/server/display/DisplayManagerService.java19
-rw-r--r--services/core/java/com/android/server/input/InputManagerService.java14
-rw-r--r--services/core/java/com/android/server/media/MediaButtonReceiverHolder.java4
-rw-r--r--services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java13
-rw-r--r--services/core/java/com/android/server/pm/AppsFilterUtils.java6
-rw-r--r--services/core/java/com/android/server/pm/BackgroundDexOptService.java42
-rw-r--r--services/core/java/com/android/server/pm/ComputerEngine.java36
-rw-r--r--services/core/java/com/android/server/pm/CrossProfileIntentResolverEngine.java267
-rw-r--r--services/core/java/com/android/server/pm/DeletePackageHelper.java4
-rw-r--r--services/core/java/com/android/server/pm/DexOptHelper.java53
-rw-r--r--services/core/java/com/android/server/pm/IPackageManagerBase.java9
-rw-r--r--services/core/java/com/android/server/pm/InstallPackageHelper.java38
-rw-r--r--services/core/java/com/android/server/pm/InstallRequest.java21
-rw-r--r--services/core/java/com/android/server/pm/InstallSource.java133
-rw-r--r--services/core/java/com/android/server/pm/InstallingSession.java64
-rw-r--r--services/core/java/com/android/server/pm/PackageDexOptimizer.java8
-rw-r--r--services/core/java/com/android/server/pm/PackageHandler.java6
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerService.java13
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerSession.java51
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java99
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerShellCommand.java27
-rw-r--r--services/core/java/com/android/server/pm/PackageMetrics.java43
-rw-r--r--services/core/java/com/android/server/pm/PackageSessionVerifier.java2
-rw-r--r--services/core/java/com/android/server/pm/PackageSetting.java14
-rw-r--r--services/core/java/com/android/server/pm/RemovePackageHelper.java2
-rw-r--r--services/core/java/com/android/server/pm/Settings.java603
-rw-r--r--services/core/java/com/android/server/pm/VerifyingSession.java2
-rw-r--r--services/core/java/com/android/server/pm/dex/DexoptOptions.java15
-rw-r--r--services/core/java/com/android/server/pm/dex/SystemServerDexLoadReporter.java83
-rw-r--r--services/core/java/com/android/server/pm/pkg/mutate/PackageStateMutator.java5
-rw-r--r--services/core/java/com/android/server/pm/pkg/mutate/PackageStateWrite.java2
-rw-r--r--services/core/java/com/android/server/policy/DeviceStateProviderImpl.java17
-rw-r--r--services/core/java/com/android/server/security/FileIntegrityService.java140
-rw-r--r--services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java7
-rw-r--r--services/core/java/com/android/server/statusbar/StatusBarManagerService.java29
-rw-r--r--services/core/java/com/android/server/timedetector/ServerFlags.java12
-rw-r--r--services/core/java/com/android/server/timedetector/ServiceConfigAccessorImpl.java10
-rw-r--r--services/core/java/com/android/server/timedetector/TimeDetectorService.java2
-rw-r--r--services/core/java/com/android/server/timezonedetector/DeviceActivityMonitorImpl.java10
-rw-r--r--services/core/java/com/android/server/timezonedetector/ServiceConfigAccessorImpl.java10
-rw-r--r--services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java1
-rw-r--r--services/core/java/com/android/server/vcn/TelephonySubscriptionTracker.java9
-rw-r--r--services/core/java/com/android/server/vcn/util/PersistableBundleUtils.java14
-rw-r--r--services/core/java/com/android/server/wallpaper/WallpaperManagerService.java44
-rw-r--r--services/core/java/com/android/server/wm/ActivityStarter.java6
-rw-r--r--services/core/java/com/android/server/wm/AppTransitionController.java12
-rw-r--r--services/core/java/com/android/server/wm/BackNavigationController.java18
-rw-r--r--services/core/java/com/android/server/wm/LaunchParamsUtil.java42
-rw-r--r--services/core/java/com/android/server/wm/Task.java28
-rw-r--r--services/core/java/com/android/server/wm/TaskDisplayArea.java13
-rw-r--r--services/core/java/com/android/server/wm/TaskFragment.java50
-rw-r--r--services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java49
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java4
-rw-r--r--services/credentials/java/com/android/server/credentials/CreateRequestSession.java12
-rw-r--r--services/credentials/java/com/android/server/credentials/CredentialManagerUi.java20
-rw-r--r--services/credentials/java/com/android/server/credentials/GetRequestSession.java12
-rw-r--r--services/credentials/java/com/android/server/credentials/ProviderCreateSession.java2
-rw-r--r--services/devicepolicy/Android.bp1
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/BooleanPolicySerializer.java39
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java461
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java105
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/EnforcingAdmin.java219
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/IntegerPolicySerializer.java39
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/IntegerUnion.java39
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/LockTaskPolicy.java107
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/MostRestrictive.java47
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java232
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java130
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/PolicySerializer.java31
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/PolicyState.java139
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/ResolutionMechanism.java26
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/SetUnion.java40
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/TopPriority.java52
-rw-r--r--services/java/com/android/server/SystemServer.java15
-rw-r--r--services/permission/java/com/android/server/permission/access/AccessCheckingService.kt85
-rw-r--r--services/permission/java/com/android/server/permission/access/AccessPersistence.kt114
-rw-r--r--services/permission/java/com/android/server/permission/access/AccessPolicy.kt255
-rw-r--r--services/permission/java/com/android/server/permission/access/AccessState.kt126
-rw-r--r--services/permission/java/com/android/server/permission/access/AccessUri.kt83
-rw-r--r--services/permission/java/com/android/server/permission/access/appop/AppOpModes.kt27
-rw-r--r--services/permission/java/com/android/server/permission/access/appop/BaseAppOpPersistence.kt73
-rw-r--r--services/permission/java/com/android/server/permission/access/appop/BaseAppOpPolicy.kt72
-rw-r--r--services/permission/java/com/android/server/permission/access/appop/PackageAppOpPersistence.kt84
-rw-r--r--services/permission/java/com/android/server/permission/access/appop/PackageAppOpPolicy.kt59
-rw-r--r--services/permission/java/com/android/server/permission/access/appop/UidAppOpPersistence.kt81
-rw-r--r--services/permission/java/com/android/server/permission/access/appop/UidAppOpPolicy.kt54
-rw-r--r--services/permission/java/com/android/server/permission/access/collection/IndexedList.kt89
-rw-r--r--services/permission/java/com/android/server/permission/access/collection/IndexedListSet.kt140
-rw-r--r--services/permission/java/com/android/server/permission/access/collection/IndexedMap.kt133
-rw-r--r--services/permission/java/com/android/server/permission/access/collection/IndexedSet.kt100
-rw-r--r--services/permission/java/com/android/server/permission/access/collection/IntMap.kt140
-rw-r--r--services/permission/java/com/android/server/permission/access/collection/IntSet.kt120
-rw-r--r--services/permission/java/com/android/server/permission/access/collection/List.kt66
-rw-r--r--services/permission/java/com/android/server/permission/access/data/Package.kt43
-rw-r--r--services/permission/java/com/android/server/permission/access/data/Permission.kt130
-rw-r--r--services/permission/java/com/android/server/permission/access/external/CompatibilityPermissionInfo.kt29
-rw-r--r--services/permission/java/com/android/server/permission/access/external/KnownPackages.kt34
-rw-r--r--services/permission/java/com/android/server/permission/access/external/PackageInfoUtils.kt33
-rw-r--r--services/permission/java/com/android/server/permission/access/external/PackageState.kt65
-rw-r--r--services/permission/java/com/android/server/permission/access/external/RoSystemProperties.kt24
-rw-r--r--services/permission/java/com/android/server/permission/access/external/SigningDetails.kt42
-rw-r--r--services/permission/java/com/android/server/permission/access/external/UserHandle.kt (renamed from services/tests/servicestests/test-apps/FakeMediaApp/src/FakeMediaButtonBroadcastReceiver.java)25
-rw-r--r--services/permission/java/com/android/server/permission/access/permission/PermissionFlags.kt32
-rw-r--r--services/permission/java/com/android/server/permission/access/permission/UidPermissionPersistence.kt139
-rw-r--r--services/permission/java/com/android/server/permission/access/permission/UidPermissionPolicy.kt909
-rw-r--r--services/permission/java/com/android/server/permission/access/util/AtomicFileExtensions.kt47
-rw-r--r--services/permission/java/com/android/server/permission/access/util/BinaryXmlPullParserExtensions.kt300
-rw-r--r--services/permission/java/com/android/server/permission/access/util/BinaryXmlSerializerExtensions.kt262
-rw-r--r--services/permission/java/com/android/server/permission/access/util/IntExtensions.kt23
-rw-r--r--services/permission/java/com/android/server/permission/access/util/PermissionApex.kt40
-rw-r--r--services/robotests/backup/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java35
-rw-r--r--services/tests/PackageManagerServiceTests/TEST_MAPPING34
-rw-r--r--services/tests/PackageManagerServiceTests/apks/Android.bp (renamed from services/tests/servicestests/apks/Android.bp)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/OWNERS (renamed from services/tests/servicestests/apks/OWNERS)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/install-split-base/Android.bp (renamed from services/tests/servicestests/apks/install-split-base/Android.bp)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/install-split-base/AndroidManifest.xml (renamed from services/tests/servicestests/apks/install-split-base/AndroidManifest.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/install-split-base/src/com/google/android/dexapis/splitapp/BaseActivity.java (renamed from services/tests/servicestests/apks/install-split-base/src/com/google/android/dexapis/splitapp/BaseActivity.java)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/install-split-feature-a/Android.bp (renamed from services/tests/servicestests/apks/install-split-feature-a/Android.bp)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/install-split-feature-a/AndroidManifest.xml (renamed from services/tests/servicestests/apks/install-split-feature-a/AndroidManifest.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/install-split-feature-a/src/com/google/android/dexapis/splitapp/feature_a/FeatureAActivity.java (renamed from services/tests/servicestests/apks/install-split-feature-a/src/com/google/android/dexapis/splitapp/feature_a/FeatureAActivity.java)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/install/Android.bp (renamed from services/tests/servicestests/apks/install/Android.bp)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/install/AndroidManifest.xml (renamed from services/tests/servicestests/apks/install/AndroidManifest.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/install/res/values/strings.xml (renamed from services/tests/servicestests/apks/install/res/values/strings.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/install_bad_dex/Android.bp (renamed from services/tests/servicestests/apks/install_bad_dex/Android.bp)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/install_bad_dex/AndroidManifest.xml (renamed from services/tests/servicestests/apks/install_bad_dex/AndroidManifest.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/install_bad_dex/classes.dex (renamed from services/tests/servicestests/apks/install_bad_dex/classes.dex)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/install_bad_dex/res/values/strings.xml (renamed from services/tests/servicestests/apks/install_bad_dex/res/values/strings.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/install_bad_dex/src/com/android/frameworks/coretests/TestActivity.java (renamed from services/tests/servicestests/apks/install_bad_dex/src/com/android/frameworks/coretests/TestActivity.java)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/install_complete_package_info/Android.bp (renamed from services/tests/servicestests/apks/install_complete_package_info/Android.bp)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/install_complete_package_info/AndroidManifest.xml (renamed from services/tests/servicestests/apks/install_complete_package_info/AndroidManifest.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/install_complete_package_info/src/com/android/frameworks/coretests/TestActivity.java (renamed from services/tests/servicestests/apks/install_complete_package_info/src/com/android/frameworks/coretests/TestActivity.java)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/install_complete_package_info/src/com/android/frameworks/coretests/TestProvider.java (renamed from services/tests/servicestests/apks/install_complete_package_info/src/com/android/frameworks/coretests/TestProvider.java)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/install_complete_package_info/src/com/android/frameworks/coretests/TestReceiver.java (renamed from services/tests/servicestests/apks/install_complete_package_info/src/com/android/frameworks/coretests/TestReceiver.java)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/install_complete_package_info/src/com/android/frameworks/coretests/TestService.java (renamed from services/tests/servicestests/apks/install_complete_package_info/src/com/android/frameworks/coretests/TestService.java)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/install_decl_perm/Android.bp (renamed from services/tests/servicestests/apks/install_decl_perm/Android.bp)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/install_decl_perm/AndroidManifest.xml (renamed from services/tests/servicestests/apks/install_decl_perm/AndroidManifest.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/install_decl_perm/res/values/strings.xml (renamed from services/tests/servicestests/apks/install_decl_perm/res/values/strings.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/install_intent_filters/Android.bp (renamed from services/tests/servicestests/apks/install_intent_filters/Android.bp)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/install_intent_filters/AndroidManifest.xml (renamed from services/tests/servicestests/apks/install_intent_filters/AndroidManifest.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/install_intent_filters/src/com/android/frameworks/servicestests/TestActivity.java (renamed from services/tests/servicestests/apks/install_intent_filters/src/com/android/frameworks/servicestests/TestActivity.java)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/install_loc_auto/Android.bp (renamed from services/tests/servicestests/apks/install_loc_auto/Android.bp)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/install_loc_auto/AndroidManifest.xml (renamed from services/tests/servicestests/apks/install_loc_auto/AndroidManifest.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/install_loc_auto/res/values/strings.xml (renamed from services/tests/servicestests/apks/install_loc_auto/res/values/strings.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/install_loc_internal/Android.bp (renamed from services/tests/servicestests/apks/install_loc_internal/Android.bp)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/install_loc_internal/AndroidManifest.xml (renamed from services/tests/servicestests/apks/install_loc_internal/AndroidManifest.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/install_loc_internal/res/values/strings.xml (renamed from services/tests/servicestests/apks/install_loc_internal/res/values/strings.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/install_loc_sdcard/Android.bp (renamed from services/tests/servicestests/apks/install_loc_sdcard/Android.bp)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/install_loc_sdcard/AndroidManifest.xml (renamed from services/tests/servicestests/apks/install_loc_sdcard/AndroidManifest.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/install_loc_sdcard/res/values/strings.xml (renamed from services/tests/servicestests/apks/install_loc_sdcard/res/values/strings.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/install_loc_unspecified/Android.bp (renamed from services/tests/servicestests/apks/install_loc_unspecified/Android.bp)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/install_loc_unspecified/AndroidManifest.xml (renamed from services/tests/servicestests/apks/install_loc_unspecified/AndroidManifest.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/install_loc_unspecified/res/values/strings.xml (renamed from services/tests/servicestests/apks/install_loc_unspecified/res/values/strings.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/install_use_perm_good/Android.bp (renamed from services/tests/servicestests/apks/install_use_perm_good/Android.bp)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/install_use_perm_good/AndroidManifest.xml (renamed from services/tests/servicestests/apks/install_use_perm_good/AndroidManifest.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/install_use_perm_good/res/values/strings.xml (renamed from services/tests/servicestests/apks/install_use_perm_good/res/values/strings.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/install_uses_feature/Android.bp (renamed from services/tests/servicestests/apks/install_uses_feature/Android.bp)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/install_uses_feature/AndroidManifest.xml (renamed from services/tests/servicestests/apks/install_uses_feature/AndroidManifest.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/install_uses_feature/res/values/strings.xml (renamed from services/tests/servicestests/apks/install_uses_feature/res/values/strings.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/install_uses_sdk/Android.bp (renamed from services/tests/servicestests/apks/install_uses_sdk/Android.bp)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/install_uses_sdk/AndroidManifest-0.xml (renamed from services/tests/servicestests/apks/install_uses_sdk/AndroidManifest-0.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/install_uses_sdk/AndroidManifest-q0-r0.xml (renamed from services/tests/servicestests/apks/install_uses_sdk/AndroidManifest-q0-r0.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/install_uses_sdk/AndroidManifest-q0.xml (renamed from services/tests/servicestests/apks/install_uses_sdk/AndroidManifest-q0.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/install_uses_sdk/AndroidManifest-r-none.xml (renamed from services/tests/servicestests/apks/install_uses_sdk/AndroidManifest-r-none.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/install_uses_sdk/AndroidManifest-r0-s0.xml (renamed from services/tests/servicestests/apks/install_uses_sdk/AndroidManifest-r0-s0.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/install_uses_sdk/AndroidManifest-r0-s1000.xml (renamed from services/tests/servicestests/apks/install_uses_sdk/AndroidManifest-r0-s1000.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/install_uses_sdk/AndroidManifest-r0.xml (renamed from services/tests/servicestests/apks/install_uses_sdk/AndroidManifest-r0.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/install_uses_sdk/AndroidManifest-r1000.xml (renamed from services/tests/servicestests/apks/install_uses_sdk/AndroidManifest-r1000.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/install_uses_sdk/res/values/strings.xml (renamed from services/tests/servicestests/apks/install_uses_sdk/res/values/strings.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/keyset/Android.bp (renamed from services/tests/servicestests/apks/keyset/Android.bp)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/keyset/api_test/AndroidManifest.xml (renamed from services/tests/servicestests/apks/keyset/api_test/AndroidManifest.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/keyset/permDef/AndroidManifest.xml (renamed from services/tests/servicestests/apks/keyset/permDef/AndroidManifest.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/keyset/permUse/AndroidManifest.xml (renamed from services/tests/servicestests/apks/keyset/permUse/AndroidManifest.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/keyset/res/values/strings.xml (renamed from services/tests/servicestests/apks/keyset/res/values/strings.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/keyset/uA/AndroidManifest.xml (renamed from services/tests/servicestests/apks/keyset/uA/AndroidManifest.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/keyset/uAB/AndroidManifest.xml (renamed from services/tests/servicestests/apks/keyset/uAB/AndroidManifest.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/keyset/uAuB/AndroidManifest.xml (renamed from services/tests/servicestests/apks/keyset/uAuB/AndroidManifest.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/keyset/uB/AndroidManifest.xml (renamed from services/tests/servicestests/apks/keyset/uB/AndroidManifest.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/apks/keyset/uNone/AndroidManifest.xml (renamed from services/tests/servicestests/apks/keyset/uNone/AndroidManifest.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/Android.bp159
-rw-r--r--services/tests/PackageManagerServiceTests/server/AndroidManifest.xml126
-rw-r--r--services/tests/PackageManagerServiceTests/server/AndroidTest.xml33
-rw-r--r--services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/certs/ec-p256-lineage-2-signers (renamed from services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256-lineage-2-signers)bin879 -> 879 bytes
-rw-r--r--services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/certs/ec-p256-lineage-3-signers (renamed from services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256-lineage-3-signers)bin1349 -> 1349 bytes
-rw-r--r--services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/certs/ec-p256.pk8 (renamed from services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256.pk8)bin138 -> 138 bytes
-rw-r--r--services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/certs/ec-p256.x509.der (renamed from services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256.x509.der)bin368 -> 368 bytes
-rw-r--r--services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/certs/ec-p256_2.pk8 (renamed from services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256_2.pk8)bin138 -> 138 bytes
-rw-r--r--services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/certs/ec-p256_2.x509.der (renamed from services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256_2.x509.der)bin369 -> 369 bytes
-rw-r--r--services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/certs/ec-p256_3.pk8 (renamed from services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256_3.pk8)bin138 -> 138 bytes
-rw-r--r--services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/certs/ec-p256_3.x509.der (renamed from services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256_3.x509.der)bin370 -> 370 bytes
-rw-r--r--services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/README (renamed from services/tests/servicestests/assets/PackageSignaturesTest/xml/README)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/one-signer-extra-cert-tag.xml (renamed from services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-extra-cert-tag.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/one-signer-invalid-cert-index.xml (renamed from services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-invalid-cert-index.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/one-signer-invalid-cert-key.xml (renamed from services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-invalid-cert-key.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/one-signer-invalid-public-key-cert-key.xml (renamed from services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-invalid-public-key-cert-key.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/one-signer-invalid-tag.xml (renamed from services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-invalid-tag.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/one-signer-missing-cert-index.xml (renamed from services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-missing-cert-index.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/one-signer-missing-cert-key.xml (renamed from services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-missing-cert-key.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/one-signer-missing-cert-tag.xml (renamed from services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-missing-cert-tag.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/one-signer-missing-scheme-version.xml (renamed from services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-missing-scheme-version.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/one-signer-missing-sigs-count.xml (renamed from services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-missing-sigs-count.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/one-signer-previous-cert.xml (renamed from services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-previous-cert.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/one-signer.xml (renamed from services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/three-signers-in-lineage-invalid-pastSigs-count.xml (renamed from services/tests/servicestests/assets/PackageSignaturesTest/xml/three-signers-in-lineage-invalid-pastSigs-count.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/three-signers-in-lineage-missing-pastSigs-cert-tag.xml (renamed from services/tests/servicestests/assets/PackageSignaturesTest/xml/three-signers-in-lineage-missing-pastSigs-cert-tag.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/three-signers-in-lineage-missing-pastSigs-count.xml (renamed from services/tests/servicestests/assets/PackageSignaturesTest/xml/three-signers-in-lineage-missing-pastSigs-count.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/three-signers-in-lineage-missing-scheme-version.xml (renamed from services/tests/servicestests/assets/PackageSignaturesTest/xml/three-signers-in-lineage-missing-scheme-version.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/three-signers-in-lineage.xml (renamed from services/tests/servicestests/assets/PackageSignaturesTest/xml/three-signers-in-lineage.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/two-signers-in-lineage-invalid-certs-flags.xml (renamed from services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-invalid-certs-flags.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/two-signers-in-lineage-invalid-pastSigs-cert-index.xml (renamed from services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-invalid-pastSigs-cert-index.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/two-signers-in-lineage-missing-certs-flags.xml (renamed from services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-missing-certs-flags.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/two-signers-in-lineage-missing-pastSigs-cert-index.xml (renamed from services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-missing-pastSigs-cert-index.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/two-signers-in-lineage-multiple-pastSigs-tags.xml (renamed from services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-multiple-pastSigs-tags.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/two-signers-in-lineage-no-caps.xml (renamed from services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-no-caps.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/two-signers-in-lineage-undefined-pastSigs-index.xml (renamed from services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-undefined-pastSigs-index.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/two-signers-in-lineage.xml (renamed from services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/two-signers-v1v2-missing-cert-tag.xml (renamed from services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-v1v2-missing-cert-tag.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/two-signers-v1v2.xml (renamed from services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-v1v2.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/res/raw/PackageParsingTestAppEmptyActionSdkQ.apk (renamed from services/tests/servicestests/res/raw/PackageParsingTestAppEmptyActionSdkQ.apk)bin534055 -> 534055 bytes
-rw-r--r--services/tests/PackageManagerServiceTests/server/res/raw/PackageParsingTestAppEmptyActionSdkR.apk (renamed from services/tests/servicestests/res/raw/PackageParsingTestAppEmptyActionSdkR.apk)bin534055 -> 534055 bytes
-rw-r--r--services/tests/PackageManagerServiceTests/server/res/raw/PackageParsingTestAppEmptyCategorySdkQ.apk (renamed from services/tests/servicestests/res/raw/PackageParsingTestAppEmptyCategorySdkQ.apk)bin534055 -> 534055 bytes
-rw-r--r--services/tests/PackageManagerServiceTests/server/res/raw/PackageParsingTestAppEmptyCategorySdkR.apk (renamed from services/tests/servicestests/res/raw/PackageParsingTestAppEmptyCategorySdkR.apk)bin534055 -> 534055 bytes
-rw-r--r--services/tests/PackageManagerServiceTests/server/res/raw/PackageParsingTestAppMissingAppSdkQ.apk (renamed from services/tests/servicestests/res/raw/PackageParsingTestAppMissingAppSdkQ.apk)bin12638 -> 12638 bytes
-rw-r--r--services/tests/PackageManagerServiceTests/server/res/raw/PackageParsingTestAppMissingAppSdkR.apk (renamed from services/tests/servicestests/res/raw/PackageParsingTestAppMissingAppSdkR.apk)bin12630 -> 12630 bytes
-rw-r--r--services/tests/PackageManagerServiceTests/server/res/raw/install_app1_cert1 (renamed from services/tests/servicestests/res/raw/install_app1_cert1)bin4468 -> 4468 bytes
-rw-r--r--services/tests/PackageManagerServiceTests/server/res/raw/install_app1_cert1_cert2 (renamed from services/tests/servicestests/res/raw/install_app1_cert1_cert2)bin5619 -> 5619 bytes
-rw-r--r--services/tests/PackageManagerServiceTests/server/res/raw/install_app1_cert2 (renamed from services/tests/servicestests/res/raw/install_app1_cert2)bin4464 -> 4464 bytes
-rw-r--r--services/tests/PackageManagerServiceTests/server/res/raw/install_app1_cert3 (renamed from services/tests/servicestests/res/raw/install_app1_cert3)bin4464 -> 4464 bytes
-rw-r--r--services/tests/PackageManagerServiceTests/server/res/raw/install_app1_cert3_cert4 (renamed from services/tests/servicestests/res/raw/install_app1_cert3_cert4)bin5615 -> 5615 bytes
-rw-r--r--services/tests/PackageManagerServiceTests/server/res/raw/install_app1_cert5 (renamed from services/tests/servicestests/res/raw/install_app1_cert5)bin12760 -> 12760 bytes
-rw-r--r--services/tests/PackageManagerServiceTests/server/res/raw/install_app1_cert5_rotated_cert6 (renamed from services/tests/servicestests/res/raw/install_app1_cert5_rotated_cert6)bin16856 -> 16856 bytes
-rw-r--r--services/tests/PackageManagerServiceTests/server/res/raw/install_app1_cert6 (renamed from services/tests/servicestests/res/raw/install_app1_cert6)bin12760 -> 12760 bytes
-rw-r--r--services/tests/PackageManagerServiceTests/server/res/raw/install_app1_unsigned (renamed from services/tests/servicestests/res/raw/install_app1_unsigned)bin2919 -> 2919 bytes
-rw-r--r--services/tests/PackageManagerServiceTests/server/res/raw/install_app2_cert1 (renamed from services/tests/servicestests/res/raw/install_app2_cert1)bin4476 -> 4476 bytes
-rw-r--r--services/tests/PackageManagerServiceTests/server/res/raw/install_app2_cert1_cert2 (renamed from services/tests/servicestests/res/raw/install_app2_cert1_cert2)bin5628 -> 5628 bytes
-rw-r--r--services/tests/PackageManagerServiceTests/server/res/raw/install_app2_cert2 (renamed from services/tests/servicestests/res/raw/install_app2_cert2)bin4457 -> 4457 bytes
-rw-r--r--services/tests/PackageManagerServiceTests/server/res/raw/install_app2_cert3 (renamed from services/tests/servicestests/res/raw/install_app2_cert3)bin4474 -> 4474 bytes
-rw-r--r--services/tests/PackageManagerServiceTests/server/res/raw/install_app2_cert5_rotated_cert6 (renamed from services/tests/servicestests/res/raw/install_app2_cert5_rotated_cert6)bin16856 -> 16856 bytes
-rw-r--r--services/tests/PackageManagerServiceTests/server/res/raw/install_app2_unsigned (renamed from services/tests/servicestests/res/raw/install_app2_unsigned)bin2925 -> 2925 bytes
-rw-r--r--services/tests/PackageManagerServiceTests/server/res/raw/install_shared1_cert1 (renamed from services/tests/servicestests/res/raw/install_shared1_cert1)bin13348 -> 13348 bytes
-rw-r--r--services/tests/PackageManagerServiceTests/server/res/raw/install_shared1_cert1_cert2 (renamed from services/tests/servicestests/res/raw/install_shared1_cert1_cert2)bin14597 -> 14597 bytes
-rw-r--r--services/tests/PackageManagerServiceTests/server/res/raw/install_shared1_cert2 (renamed from services/tests/servicestests/res/raw/install_shared1_cert2)bin13345 -> 13345 bytes
-rw-r--r--services/tests/PackageManagerServiceTests/server/res/raw/install_shared1_unsigned (renamed from services/tests/servicestests/res/raw/install_shared1_unsigned)bin11597 -> 11597 bytes
-rw-r--r--services/tests/PackageManagerServiceTests/server/res/raw/install_shared2_cert1 (renamed from services/tests/servicestests/res/raw/install_shared2_cert1)bin13347 -> 13347 bytes
-rw-r--r--services/tests/PackageManagerServiceTests/server/res/raw/install_shared2_cert1_cert2 (renamed from services/tests/servicestests/res/raw/install_shared2_cert1_cert2)bin14598 -> 14598 bytes
-rw-r--r--services/tests/PackageManagerServiceTests/server/res/raw/install_shared2_cert2 (renamed from services/tests/servicestests/res/raw/install_shared2_cert2)bin13343 -> 13343 bytes
-rw-r--r--services/tests/PackageManagerServiceTests/server/res/raw/install_shared2_unsigned (renamed from services/tests/servicestests/res/raw/install_shared2_unsigned)bin11598 -> 11598 bytes
-rw-r--r--services/tests/PackageManagerServiceTests/server/res/values/values.xml (renamed from services/tests/servicestests/test-apps/FakeMediaApp/AndroidManifest.xml)19
-rw-r--r--services/tests/PackageManagerServiceTests/server/res/xml/unparseable_metadata1.xml (renamed from services/tests/servicestests/res/xml/unparseable_metadata1.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/res/xml/unparseable_metadata2.xml (renamed from services/tests/servicestests/res/xml/unparseable_metadata2.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/res/xml/well_formed_metadata.xml (renamed from services/tests/servicestests/res/xml/well_formed_metadata.xml)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/src/com/android/server/AppsFilterImplTest.java (renamed from services/tests/servicestests/src/com/android/server/pm/AppsFilterImplTest.java)20
-rw-r--r--services/tests/PackageManagerServiceTests/server/src/com/android/server/BundleUtilsTest.java (renamed from services/tests/servicestests/src/com/android/server/pm/BundleUtilsTest.java)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/src/com/android/server/CompatibilityModeTest.java (renamed from services/tests/servicestests/src/com/android/server/pm/CompatibilityModeTest.java)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/src/com/android/server/CrossProfileAppsServiceImplTest.java (renamed from services/tests/servicestests/src/com/android/server/pm/CrossProfileAppsServiceImplTest.java)37
-rw-r--r--services/tests/PackageManagerServiceTests/server/src/com/android/server/InstallerTest.java (renamed from services/tests/servicestests/src/com/android/server/pm/InstallerTest.java)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/src/com/android/server/KeySetManagerServiceTest.java (renamed from services/tests/servicestests/src/com/android/server/pm/KeySetManagerServiceTest.java)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/src/com/android/server/KeySetStrings.java (renamed from services/tests/servicestests/src/com/android/server/pm/KeySetStrings.java)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/src/com/android/server/KeySetUtils.java (renamed from services/tests/servicestests/src/com/android/server/pm/KeySetUtils.java)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/src/com/android/server/ModuleInfoProviderTest.java (renamed from services/tests/servicestests/src/com/android/server/pm/ModuleInfoProviderTest.java)2
-rw-r--r--services/tests/PackageManagerServiceTests/server/src/com/android/server/PackageInstallerSessionTest.java (renamed from services/tests/servicestests/src/com/android/server/pm/PackageInstallerSessionTest.java)8
-rw-r--r--services/tests/PackageManagerServiceTests/server/src/com/android/server/PackageManagerServiceTest.java (renamed from services/tests/servicestests/src/com/android/server/pm/PackageManagerServiceTest.java)2
-rw-r--r--services/tests/PackageManagerServiceTests/server/src/com/android/server/PackageManagerSettingsTests.java (renamed from services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java)246
-rw-r--r--services/tests/PackageManagerServiceTests/server/src/com/android/server/PackageManagerTests.java (renamed from services/tests/servicestests/src/com/android/server/pm/PackageManagerTests.java)2
-rw-r--r--services/tests/PackageManagerServiceTests/server/src/com/android/server/PackageParserTest.java (renamed from services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/src/com/android/server/PackageSignaturesTest.java (renamed from services/tests/servicestests/src/com/android/server/pm/PackageSignaturesTest.java)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/src/com/android/server/PackageUserStateTest.java (renamed from services/tests/servicestests/src/com/android/server/pm/PackageUserStateTest.java)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/src/com/android/server/PackageVerificationStateTest.java (renamed from services/tests/servicestests/src/com/android/server/pm/PackageVerificationStateTest.java)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/src/com/android/server/ParallelPackageParserTest.java (renamed from services/tests/servicestests/src/com/android/server/pm/ParallelPackageParserTest.java)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/src/com/android/server/PreferredComponentTest.java (renamed from services/tests/servicestests/src/com/android/server/pm/PreferredComponentTest.java)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/src/com/android/server/RestrictionsSetTest.java (renamed from services/tests/servicestests/src/com/android/server/pm/RestrictionsSetTest.java)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/src/com/android/server/ScanRequestBuilder.java (renamed from services/tests/servicestests/src/com/android/server/pm/ScanRequestBuilder.java)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/src/com/android/server/ScanTests.java (renamed from services/tests/servicestests/src/com/android/server/pm/ScanTests.java)2
-rw-r--r--services/tests/PackageManagerServiceTests/server/src/com/android/server/UserDataPreparerTest.java (renamed from services/tests/servicestests/src/com/android/server/pm/UserDataPreparerTest.java)10
-rw-r--r--services/tests/PackageManagerServiceTests/server/src/com/android/server/WatchedIntentHandlingTest.java (renamed from services/tests/servicestests/src/com/android/server/pm/WatchedIntentHandlingTest.java)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/src/com/android/server/parsing/PackageParserLegacyCoreTest.java (renamed from services/tests/servicestests/src/com/android/server/pm/parsing/PackageParserLegacyCoreTest.java)2
-rw-r--r--services/tests/PackageManagerServiceTests/server/src/com/android/server/parsing/PackageParsingDeferErrorTest.kt (renamed from services/tests/servicestests/src/com/android/server/pm/parsing/PackageParsingDeferErrorTest.kt)2
-rw-r--r--services/tests/PackageManagerServiceTests/server/src/com/android/server/parsing/SystemPartitionParseTest.kt (renamed from services/tests/servicestests/src/com/android/server/pm/parsing/SystemPartitionParseTest.kt)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/src/com/android/server/parsing/library/AndroidHidlUpdaterTest.java (renamed from services/tests/servicestests/src/com/android/server/pm/parsing/library/AndroidHidlUpdaterTest.java)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/src/com/android/server/parsing/library/AndroidNetIpSecIkeUpdaterTest.java (renamed from services/tests/servicestests/src/com/android/server/pm/parsing/library/AndroidNetIpSecIkeUpdaterTest.java)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/src/com/android/server/parsing/library/AndroidTestBaseUpdaterTest.java (renamed from services/tests/servicestests/src/com/android/server/pm/parsing/library/AndroidTestBaseUpdaterTest.java)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/src/com/android/server/parsing/library/AndroidTestRunnerSplitUpdaterTest.java (renamed from services/tests/servicestests/src/com/android/server/pm/parsing/library/AndroidTestRunnerSplitUpdaterTest.java)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/src/com/android/server/parsing/library/ApexSharedLibraryUpdaterTest.java (renamed from services/tests/servicestests/src/com/android/server/pm/parsing/library/ApexSharedLibraryUpdaterTest.java)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/src/com/android/server/parsing/library/ComGoogleAndroidMapsUpdaterTest.java (renamed from services/tests/servicestests/src/com/android/server/pm/parsing/library/ComGoogleAndroidMapsUpdaterTest.java)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/src/com/android/server/parsing/library/OptionalClassRunner.java (renamed from services/tests/servicestests/src/com/android/server/pm/parsing/library/OptionalClassRunner.java)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/src/com/android/server/parsing/library/OrgApacheHttpLegacyUpdaterTest.java (renamed from services/tests/servicestests/src/com/android/server/pm/parsing/library/OrgApacheHttpLegacyUpdaterTest.java)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/src/com/android/server/parsing/library/PackageBackwardCompatibilityTest.java (renamed from services/tests/servicestests/src/com/android/server/pm/parsing/library/PackageBackwardCompatibilityTest.java)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/src/com/android/server/parsing/library/PackageSharedLibraryUpdaterTest.java (renamed from services/tests/servicestests/src/com/android/server/pm/parsing/library/PackageSharedLibraryUpdaterTest.java)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/src/com/android/server/parsing/library/RemoveUnnecessaryAndroidTestBaseLibraryTest.java (renamed from services/tests/servicestests/src/com/android/server/pm/parsing/library/RemoveUnnecessaryAndroidTestBaseLibraryTest.java)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/src/com/android/server/parsing/library/RemoveUnnecessaryOrgApacheHttpLegacyLibraryTest.java (renamed from services/tests/servicestests/src/com/android/server/pm/parsing/library/RemoveUnnecessaryOrgApacheHttpLegacyLibraryTest.java)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/src/com/android/server/utils/OWNERS4
-rw-r--r--services/tests/PackageManagerServiceTests/server/src/com/android/server/utils/WatchableTester.java (renamed from services/tests/servicestests/src/com/android/server/utils/WatchableTester.java)0
-rw-r--r--services/tests/PackageManagerServiceTests/server/src/com/android/server/utils/WatcherTest.java (renamed from services/tests/servicestests/src/com/android/server/utils/WatcherTest.java)2
-rw-r--r--services/tests/mockingservicestests/res/xml/game_manager_service_metadata_config_interventions_enabled_battery_opt_in.xml9
-rw-r--r--services/tests/mockingservicestests/res/xml/game_manager_service_metadata_config_interventions_enabled_performance_opt_in.xml9
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java79
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/am/BroadcastRecordTest.java144
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java155
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/app/GameManagerServiceTests.java489
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/pm/AsyncUserVisibilityListener.java3
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/pm/StagingManagerTest.java2
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorTestCase.java31
-rw-r--r--services/tests/servicestests/Android.bp67
-rw-r--r--services/tests/servicestests/AndroidManifest.xml13
-rw-r--r--services/tests/servicestests/AndroidTest.xml1
-rw-r--r--services/tests/servicestests/src/com/android/server/app/GameManagerServiceSettingsTests.java2
-rw-r--r--services/tests/servicestests/src/com/android/server/backup/UserBackupManagerServiceTest.java2
-rw-r--r--services/tests/servicestests/src/com/android/server/backup/utils/BackupManagerMonitorUtilsTest.java51
-rw-r--r--services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java29
-rw-r--r--services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java12
-rw-r--r--services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java8
-rw-r--r--services/tests/servicestests/src/com/android/server/media/MediaButtonReceiverHolderTest.java45
-rw-r--r--services/tests/servicestests/src/com/android/server/media/OWNERS2
-rw-r--r--services/tests/servicestests/src/com/android/server/utils/OWNERS4
-rw-r--r--services/tests/servicestests/test-apps/FakeMediaApp/Android.bp37
-rw-r--r--services/tests/servicestests/test-apps/FakeMediaApp/OWNERS2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java3
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java8
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java45
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java45
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java8
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/LaunchParamsPersisterTests.java6
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ProtoLogIntegrationTest.java10
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java36
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/RootTaskTests.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java4
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java38
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java92
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskTests.java20
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java16
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java64
-rw-r--r--services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java2
-rw-r--r--services/voiceinteraction/java/com/android/server/voiceinteraction/TrustedHotwordDetectorSession.java1324
-rw-r--r--telecomm/java/android/telecom/Call.java29
-rw-r--r--telecomm/java/android/telecom/Connection.java21
-rw-r--r--telecomm/java/android/telecom/ParcelableCall.java26
-rw-r--r--tests/ApkVerityTest/src/com/android/apkverity/ApkVerityTest.java8
-rw-r--r--tests/InputMethodStressTest/AndroidManifest.xml6
-rw-r--r--tests/InputMethodStressTest/TEST_MAPPING2
-rw-r--r--tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/AutoShowTest.java503
-rw-r--r--tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeOpenCloseStressTest.java555
-rw-r--r--tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeStressTestUtil.java395
-rw-r--r--tests/Internal/src/com/android/internal/protolog/ProtoLogImplTest.java8
-rw-r--r--tests/Internal/src/com/android/internal/protolog/common/LogDataTypeTest.java5
-rw-r--r--tests/utils/hostutils/src/com/android/fsverity/AddFsVerityCertRule.java77
-rw-r--r--tests/vcn/java/com/android/server/VcnManagementServiceTest.java243
-rw-r--r--tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java35
-rw-r--r--tools/locked_region_code_injection/Android.bp8
-rw-r--r--tools/protologtool/tests/com/android/protolog/tool/LogParserTest.kt16
-rw-r--r--tools/sdkparcelables/Android.bp2
-rw-r--r--tools/traceinjection/Android.bp8
744 files changed, 21586 insertions, 6906 deletions
diff --git a/ApiDocs.bp b/ApiDocs.bp
index bf3a6a356e31..a46ecce5c721 100644
--- a/ApiDocs.bp
+++ b/ApiDocs.bp
@@ -183,6 +183,7 @@ droidstubs {
/////////////////////////////////////////////////////////////////////
framework_docs_only_args = " -android -manifest $(location core/res/AndroidManifest.xml) " +
+ "-metalavaApiSince " +
"-werror -lerror -hide 111 -hide 113 -hide 125 -hide 126 -hide 127 -hide 128 " +
"-overview $(location core/java/overview.html) " +
// Federate Support Library references against local API file.
@@ -374,7 +375,7 @@ droiddoc {
],
proofread_file: "ds-docs-proofread.txt",
args: framework_docs_only_args +
- " -toroot / -yamlV2 -metalavaApiSince -samplegroup Admin " +
+ " -toroot / -yamlV2 -samplegroup Admin " +
" -samplegroup Background " +
" -samplegroup Connectivity " +
" -samplegroup Content " +
diff --git a/core/api/current.txt b/core/api/current.txt
index 3ca7dadfcddc..2b946940b073 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -5612,6 +5612,7 @@ package android.app {
method public int getGameMode();
method public void setGameState(@NonNull android.app.GameState);
field public static final int GAME_MODE_BATTERY = 3; // 0x3
+ field public static final int GAME_MODE_CUSTOM = 4; // 0x4
field public static final int GAME_MODE_PERFORMANCE = 2; // 0x2
field public static final int GAME_MODE_STANDARD = 1; // 0x1
field public static final int GAME_MODE_UNSUPPORTED = 0; // 0x0
@@ -7272,6 +7273,7 @@ package android.app {
method @RequiresPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE) public android.os.ParcelFileDescriptor getWallpaperFile(int);
method public int getWallpaperId(int);
method public android.app.WallpaperInfo getWallpaperInfo();
+ method @Nullable public android.app.WallpaperInfo getWallpaperInfo(int);
method public boolean hasResourceWallpaper(@RawRes int);
method public boolean isSetWallpaperAllowed();
method public boolean isWallpaperSupported();
@@ -19737,6 +19739,7 @@ package android.location {
method public int describeContents();
method @NonNull public android.location.GnssClock getClock();
method @NonNull public java.util.Collection<android.location.GnssAutomaticGainControl> getGnssAutomaticGainControls();
+ method public boolean getIsFullTracking();
method @NonNull public java.util.Collection<android.location.GnssMeasurement> getMeasurements();
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.location.GnssMeasurementsEvent> CREATOR;
@@ -19748,6 +19751,7 @@ package android.location {
method @NonNull public android.location.GnssMeasurementsEvent build();
method @NonNull public android.location.GnssMeasurementsEvent.Builder setClock(@NonNull android.location.GnssClock);
method @NonNull public android.location.GnssMeasurementsEvent.Builder setGnssAutomaticGainControls(@NonNull java.util.Collection<android.location.GnssAutomaticGainControl>);
+ method @NonNull public android.location.GnssMeasurementsEvent.Builder setIsFullTracking(boolean);
method @NonNull public android.location.GnssMeasurementsEvent.Builder setMeasurements(@NonNull java.util.Collection<android.location.GnssMeasurement>);
}
@@ -20276,6 +20280,7 @@ package android.media {
field public static final int TYPE_BUILTIN_SPEAKER_SAFE = 24; // 0x18
field public static final int TYPE_BUS = 21; // 0x15
field public static final int TYPE_DOCK = 13; // 0xd
+ field public static final int TYPE_DOCK_ANALOG = 31; // 0x1f
field public static final int TYPE_FM = 14; // 0xe
field public static final int TYPE_FM_TUNER = 16; // 0x10
field public static final int TYPE_HDMI = 9; // 0x9
@@ -20402,7 +20407,10 @@ package android.media {
field public static final int ENCODING_DRA = 28; // 0x1c
field public static final int ENCODING_DTS = 7; // 0x7
field public static final int ENCODING_DTS_HD = 8; // 0x8
- field public static final int ENCODING_DTS_UHD = 27; // 0x1b
+ field public static final int ENCODING_DTS_HD_MA = 29; // 0x1d
+ field @Deprecated public static final int ENCODING_DTS_UHD = 27; // 0x1b
+ field public static final int ENCODING_DTS_UHD_P1 = 27; // 0x1b
+ field public static final int ENCODING_DTS_UHD_P2 = 30; // 0x1e
field public static final int ENCODING_E_AC3 = 6; // 0x6
field public static final int ENCODING_E_AC3_JOC = 18; // 0x12
field public static final int ENCODING_IEC61937 = 13; // 0xd
@@ -40008,6 +40016,7 @@ package android.service.wallpaper {
method public int getDesiredMinimumWidth();
method @Nullable public android.content.Context getDisplayContext();
method public android.view.SurfaceHolder getSurfaceHolder();
+ method public int getWallpaperFlags();
method public boolean isPreview();
method public boolean isVisible();
method public void notifyColorsChanged();
@@ -40024,6 +40033,7 @@ package android.service.wallpaper {
method @MainThread public void onSurfaceRedrawNeeded(android.view.SurfaceHolder);
method @MainThread public void onTouchEvent(android.view.MotionEvent);
method @MainThread public void onVisibilityChanged(boolean);
+ method @MainThread public void onWallpaperFlagsChanged(int);
method @MainThread public void onZoomChanged(@FloatRange(from=0.0f, to=1.0f) float);
method public void setOffsetNotificationsEnabled(boolean);
method public void setTouchEventsEnabled(boolean);
@@ -40517,6 +40527,7 @@ package android.telecom {
method public int getCallerNumberVerificationStatus();
method public final long getConnectTimeMillis();
method @Nullable public String getContactDisplayName();
+ method @Nullable public android.net.Uri getContactPhotoUri();
method public long getCreationTimeMillis();
method public android.telecom.DisconnectCause getDisconnectCause();
method public android.os.Bundle getExtras();
@@ -49563,6 +49574,7 @@ package android.view {
method public float getY(int);
method public float getYPrecision();
method public boolean isButtonPressed(int);
+ method @Nullable public static android.view.MotionEvent obtain(long, long, int, int, @NonNull android.view.MotionEvent.PointerProperties[], @NonNull android.view.MotionEvent.PointerCoords[], int, int, float, float, int, int, int, int, int, int);
method public static android.view.MotionEvent obtain(long, long, int, int, android.view.MotionEvent.PointerProperties[], android.view.MotionEvent.PointerCoords[], int, int, float, float, int, int, int, int);
method @Deprecated public static android.view.MotionEvent obtain(long, long, int, int, int[], android.view.MotionEvent.PointerCoords[], int, float, float, int, int, int, int);
method public static android.view.MotionEvent obtain(long, long, int, float, float, float, float, int, float, float, int, int);
@@ -52468,6 +52480,7 @@ package android.view.accessibility {
method public String getViewIdResourceName();
method public android.view.accessibility.AccessibilityWindowInfo getWindow();
method public int getWindowId();
+ method public boolean hasRequestInitialAccessibilityFocus();
method public boolean isAccessibilityFocused();
method public boolean isCheckable();
method public boolean isChecked();
@@ -52547,6 +52560,7 @@ package android.view.accessibility {
method public void setPassword(boolean);
method public void setQueryFromAppProcessEnabled(@NonNull android.view.View, boolean);
method public void setRangeInfo(android.view.accessibility.AccessibilityNodeInfo.RangeInfo);
+ method public void setRequestInitialAccessibilityFocus(boolean);
method public void setScreenReaderFocusable(boolean);
method public void setScrollable(boolean);
method public void setSelected(boolean);
@@ -52617,13 +52631,11 @@ package android.view.accessibility {
field public static final int FOCUS_ACCESSIBILITY = 2; // 0x2
field public static final int FOCUS_INPUT = 1; // 0x1
field public static final int MAX_NUMBER_OF_PREFETCHED_NODES = 50; // 0x32
- field public static final int MINIMUM_MIN_MILLIS_BETWEEN_CONTENT_CHANGES = 100; // 0x64
field public static final int MOVEMENT_GRANULARITY_CHARACTER = 1; // 0x1
field public static final int MOVEMENT_GRANULARITY_LINE = 4; // 0x4
field public static final int MOVEMENT_GRANULARITY_PAGE = 16; // 0x10
field public static final int MOVEMENT_GRANULARITY_PARAGRAPH = 8; // 0x8
field public static final int MOVEMENT_GRANULARITY_WORD = 2; // 0x2
- field public static final int UNDEFINED_MIN_MILLIS_BETWEEN_CONTENT_CHANGES = -1; // 0xffffffff
}
public static final class AccessibilityNodeInfo.AccessibilityAction implements android.os.Parcelable {
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index 07af1d5f1634..b6e2d2a3e98b 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -360,7 +360,6 @@ package android.os {
method @NonNull public static String[] getDeclaredInstances(@NonNull String);
method public static boolean isDeclared(@NonNull String);
method @Nullable public static android.os.IBinder waitForDeclaredService(@NonNull String);
- method @Nullable public static android.os.IBinder waitForService(@NonNull String);
}
public class StatsServiceManager {
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index baf1f3107e2c..8ff9f875c824 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -241,7 +241,7 @@ package android {
field public static final String PROVIDE_TRUST_AGENT = "android.permission.PROVIDE_TRUST_AGENT";
field public static final String PROVISION_DEMO_DEVICE = "android.permission.PROVISION_DEMO_DEVICE";
field public static final String QUERY_ADMIN_POLICY = "android.permission.QUERY_ADMIN_POLICY";
- field public static final String QUERY_TIME_ZONE_RULES = "android.permission.QUERY_TIME_ZONE_RULES";
+ field @Deprecated public static final String QUERY_TIME_ZONE_RULES = "android.permission.QUERY_TIME_ZONE_RULES";
field public static final String QUERY_USERS = "android.permission.QUERY_USERS";
field public static final String RADIO_SCAN_WITHOUT_LOCATION = "android.permission.RADIO_SCAN_WITHOUT_LOCATION";
field public static final String READ_ACTIVE_EMERGENCY_SESSION = "android.permission.READ_ACTIVE_EMERGENCY_SESSION";
@@ -344,7 +344,7 @@ package android {
field public static final String UPDATE_DOMAIN_VERIFICATION_USER_SELECTION = "android.permission.UPDATE_DOMAIN_VERIFICATION_USER_SELECTION";
field public static final String UPDATE_FONTS = "android.permission.UPDATE_FONTS";
field public static final String UPDATE_LOCK = "android.permission.UPDATE_LOCK";
- field public static final String UPDATE_TIME_ZONE_RULES = "android.permission.UPDATE_TIME_ZONE_RULES";
+ field @Deprecated public static final String UPDATE_TIME_ZONE_RULES = "android.permission.UPDATE_TIME_ZONE_RULES";
field public static final String UPGRADE_RUNTIME_PERMISSIONS = "android.permission.UPGRADE_RUNTIME_PERMISSIONS";
field public static final String USER_ACTIVITY = "android.permission.USER_ACTIVITY";
field public static final String USE_COLORIZED_NOTIFICATIONS = "android.permission.USE_COLORIZED_NOTIFICATIONS";
@@ -783,13 +783,19 @@ package android.app {
}
public class BroadcastOptions {
+ method public void clearDeliveryGroupMatchingFilter();
+ method public void clearDeliveryGroupMatchingKey();
method public void clearDeliveryGroupPolicy();
method public void clearRequireCompatChange();
+ method @Nullable public android.content.IntentFilter getDeliveryGroupMatchingFilter();
+ method @Nullable public String getDeliveryGroupMatchingKey();
method public int getDeliveryGroupPolicy();
method public boolean isPendingIntentBackgroundActivityLaunchAllowed();
method public static android.app.BroadcastOptions makeBasic();
method @RequiresPermission(android.Manifest.permission.ACCESS_BROADCAST_RESPONSE_STATS) public void recordResponseEventWhileInBackground(@IntRange(from=0) long);
method @RequiresPermission(android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND) public void setBackgroundActivityStartsAllowed(boolean);
+ method public void setDeliveryGroupMatchingFilter(@NonNull android.content.IntentFilter);
+ method public void setDeliveryGroupMatchingKey(@NonNull String, @NonNull String);
method public void setDeliveryGroupPolicy(int);
method public void setDontSendToRestrictedApps(boolean);
method public void setPendingIntentBackgroundActivityLaunchAllowed(boolean);
@@ -811,17 +817,50 @@ package android.app {
public final class GameManager {
method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_GAME_MODE) public android.app.GameModeInfo getGameModeInfo(@NonNull String);
method @RequiresPermission(android.Manifest.permission.MANAGE_GAME_MODE) public void setGameMode(@NonNull String, int);
+ method @RequiresPermission(android.Manifest.permission.MANAGE_GAME_MODE) public void updateCustomGameModeConfiguration(@NonNull String, @NonNull android.app.GameModeConfiguration);
+ }
+
+ public final class GameModeConfiguration implements android.os.Parcelable {
+ method public int describeContents();
+ method public int getFpsOverride();
+ method public float getScalingFactor();
+ method @NonNull public android.app.GameModeConfiguration.Builder toBuilder();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.app.GameModeConfiguration> CREATOR;
+ field public static final int FPS_OVERRIDE_NONE = 0; // 0x0
+ }
+
+ public static final class GameModeConfiguration.Builder {
+ ctor public GameModeConfiguration.Builder();
+ method @NonNull public android.app.GameModeConfiguration build();
+ method @NonNull public android.app.GameModeConfiguration.Builder setFpsOverride(int);
+ method @NonNull public android.app.GameModeConfiguration.Builder setScalingFactor(float);
}
public final class GameModeInfo implements android.os.Parcelable {
- ctor public GameModeInfo(int, @NonNull int[]);
+ ctor @Deprecated public GameModeInfo(int, @NonNull int[]);
method public int describeContents();
method public int getActiveGameMode();
method @NonNull public int[] getAvailableGameModes();
+ method @Nullable public android.app.GameModeConfiguration getGameModeConfiguration(int);
+ method @NonNull public int[] getOptedInGameModes();
+ method public boolean isDownscalingAllowed();
+ method public boolean isFpsOverrideAllowed();
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.app.GameModeInfo> CREATOR;
}
+ public static final class GameModeInfo.Builder {
+ ctor public GameModeInfo.Builder();
+ method @NonNull public android.app.GameModeInfo build();
+ method @NonNull public android.app.GameModeInfo.Builder setActiveGameMode(@NonNull int);
+ method @NonNull public android.app.GameModeInfo.Builder setAvailableGameModes(@NonNull int[]);
+ method @NonNull public android.app.GameModeInfo.Builder setDownscalingAllowed(boolean);
+ method @NonNull public android.app.GameModeInfo.Builder setFpsOverrideAllowed(boolean);
+ method @NonNull public android.app.GameModeInfo.Builder setGameModeConfiguration(int, @NonNull android.app.GameModeConfiguration);
+ method @NonNull public android.app.GameModeInfo.Builder setOptedInGameModes(@NonNull int[]);
+ }
+
public abstract class InstantAppResolverService extends android.app.Service {
ctor public InstantAppResolverService();
method public final void attachBaseContext(android.content.Context);
@@ -1082,6 +1121,7 @@ package android.app {
method @FloatRange(from=0.0f, to=1.0f) @RequiresPermission(android.Manifest.permission.SET_WALLPAPER_DIM_AMOUNT) public float getWallpaperDimAmount();
method public void setDisplayOffset(android.os.IBinder, int, int);
method @RequiresPermission(android.Manifest.permission.SET_WALLPAPER_COMPONENT) public boolean setWallpaperComponent(android.content.ComponentName);
+ method @RequiresPermission(android.Manifest.permission.SET_WALLPAPER_COMPONENT) public boolean setWallpaperComponentWithFlags(@NonNull android.content.ComponentName, int);
method @RequiresPermission(android.Manifest.permission.SET_WALLPAPER_DIM_AMOUNT) public void setWallpaperDimAmount(@FloatRange(from=0.0f, to=1.0f) float);
}
@@ -1470,6 +1510,7 @@ package android.app.backup {
public class BackupManagerMonitor {
ctor public BackupManagerMonitor();
method public void onEvent(android.os.Bundle);
+ field public static final String EXTRA_LOG_AGENT_LOGGING_RESULTS = "android.app.backup.extra.LOG_AGENT_LOGGING_RESULTS";
field public static final String EXTRA_LOG_CANCEL_ALL = "android.app.backup.extra.LOG_CANCEL_ALL";
field public static final String EXTRA_LOG_EVENT_CATEGORY = "android.app.backup.extra.LOG_EVENT_CATEGORY";
field public static final String EXTRA_LOG_EVENT_ID = "android.app.backup.extra.LOG_EVENT_ID";
@@ -1488,6 +1529,7 @@ package android.app.backup {
field public static final int LOG_EVENT_CATEGORY_AGENT = 2; // 0x2
field public static final int LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY = 3; // 0x3
field public static final int LOG_EVENT_CATEGORY_TRANSPORT = 1; // 0x1
+ field public static final int LOG_EVENT_ID_AGENT_LOGGING_RESULTS = 52; // 0x34
field public static final int LOG_EVENT_ID_APK_NOT_INSTALLED = 40; // 0x28
field public static final int LOG_EVENT_ID_APP_HAS_NO_AGENT = 28; // 0x1c
field public static final int LOG_EVENT_ID_BACKUP_DISABLED = 13; // 0xd
@@ -1562,6 +1604,7 @@ package android.app.backup {
method public int finishBackup();
method public void finishRestore();
method public android.app.backup.RestoreSet[] getAvailableRestoreSets();
+ method @Nullable public android.app.backup.BackupManagerMonitor getBackupManagerMonitor();
method public long getBackupQuota(String, boolean);
method public android.os.IBinder getBinder();
method public long getCurrentRestoreSet();
@@ -3182,7 +3225,9 @@ package android.content {
}
public class IntentFilter implements android.os.Parcelable {
+ method @NonNull public final android.os.PersistableBundle getExtras();
method public final int getOrder();
+ method public final void setExtras(@NonNull android.os.PersistableBundle);
method public final void setOrder(int);
}
@@ -10172,7 +10217,7 @@ package android.os.storage {
method @WorkerThread public long getAllocatableBytes(@NonNull java.util.UUID, @RequiresPermission int) throws java.io.IOException;
method @RequiresPermission(android.Manifest.permission.WRITE_MEDIA_STORAGE) public int getExternalStorageMountMode(int, @NonNull String);
method public static boolean hasIsolatedStorage();
- method @RequiresPermission(android.Manifest.permission.MANAGE_EXTERNAL_STORAGE) public void updateExternalStorageFileQuotaType(@NonNull java.io.File, int) throws java.io.IOException;
+ method public void updateExternalStorageFileQuotaType(@NonNull java.io.File, int) throws java.io.IOException;
field @RequiresPermission(android.Manifest.permission.ALLOCATE_AGGRESSIVE) public static final int FLAG_ALLOCATE_AGGRESSIVE = 1; // 0x1
field public static final int MOUNT_MODE_EXTERNAL_ANDROID_WRITABLE = 4; // 0x4
field public static final int MOUNT_MODE_EXTERNAL_DEFAULT = 1; // 0x1
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 85d73ec7d65a..121741e07d43 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -2955,7 +2955,6 @@ package android.view {
method public static int getHoverTooltipHideTimeout();
method public static int getHoverTooltipShowTimeout();
method public static int getLongPressTooltipHideTimeout();
- method public static long getSendRecurringAccessibilityEventsInterval();
method public boolean isPreferKeepClearForFocusEnabled();
}
@@ -3307,6 +3306,18 @@ package android.widget.inline {
package android.window {
+ public final class BackNavigationInfo implements android.os.Parcelable {
+ method @NonNull public static String typeToString(int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.window.BackNavigationInfo> CREATOR;
+ field public static final String KEY_TRIGGER_BACK = "TriggerBack";
+ field public static final int TYPE_CALLBACK = 4; // 0x4
+ field public static final int TYPE_CROSS_ACTIVITY = 2; // 0x2
+ field public static final int TYPE_CROSS_TASK = 3; // 0x3
+ field public static final int TYPE_DIALOG_CLOSE = 0; // 0x0
+ field public static final int TYPE_RETURN_TO_HOME = 1; // 0x1
+ field public static final int TYPE_UNDEFINED = -1; // 0xffffffff
+ }
+
public final class DisplayAreaAppearedInfo implements android.os.Parcelable {
ctor public DisplayAreaAppearedInfo(@NonNull android.window.DisplayAreaInfo, @NonNull android.view.SurfaceControl);
method public int describeContents();
diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java
index 62b0f5c4fb90..dbdee0771ad4 100644
--- a/core/java/android/accounts/AccountManager.java
+++ b/core/java/android/accounts/AccountManager.java
@@ -623,6 +623,9 @@ public class AccountManager {
*
* <p>No permission is required to call this method.
*
+ * <p>Caller targeting API level 34 and above, the results are filtered
+ * by the rules of <a href="/training/basics/intents/package-visibility">package visibility</a>.
+ *
* @return An array of {@link AuthenticatorDescription} for every
* authenticator known to the AccountManager service. Empty (never
* null) if no authenticators are known.
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index e001c7df506e..a61ade08bac6 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -1105,6 +1105,11 @@ public final class ActivityThread extends ClientTransactionHandler
}
@Override
+ public final void scheduleTimeoutService(IBinder token, int startId) {
+ sendMessage(H.TIMEOUT_SERVICE, token, startId);
+ }
+
+ @Override
public final void bindApplication(String processName, ApplicationInfo appInfo,
String sdkSandboxClientAppVolumeUuid, String sdkSandboxClientAppPackage,
ProviderInfoList providerList, ComponentName instrumentationName,
@@ -2081,6 +2086,7 @@ public final class ActivityThread extends ClientTransactionHandler
public static final int SET_CONTENT_CAPTURE_OPTIONS_CALLBACK = 164;
public static final int DUMP_GFXINFO = 165;
public static final int DUMP_RESOURCES = 166;
+ public static final int TIMEOUT_SERVICE = 167;
public static final int INSTRUMENT_WITHOUT_RESTART = 170;
public static final int FINISH_INSTRUMENTATION_WITHOUT_RESTART = 171;
@@ -2135,6 +2141,7 @@ public final class ActivityThread extends ClientTransactionHandler
case FINISH_INSTRUMENTATION_WITHOUT_RESTART:
return "FINISH_INSTRUMENTATION_WITHOUT_RESTART";
case DUMP_RESOURCES: return "DUMP_RESOURCES";
+ case TIMEOUT_SERVICE: return "TIMEOUT_SERVICE";
}
}
return Integer.toString(code);
@@ -2201,6 +2208,11 @@ public final class ActivityThread extends ClientTransactionHandler
schedulePurgeIdler();
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
+ case TIMEOUT_SERVICE:
+ Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceTimeout");
+ handleTimeoutService((IBinder) msg.obj, msg.arg1);
+ Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
+ break;
case CONFIGURATION_CHANGED:
mConfigurationController.handleConfigurationChanged((Configuration) msg.obj);
break;
@@ -4726,6 +4738,27 @@ public final class ActivityThread extends ClientTransactionHandler
//Slog.i(TAG, "Running services: " + mServices);
}
+ private void handleTimeoutService(IBinder token, int startId) {
+ Service s = mServices.get(token);
+ if (s != null) {
+ try {
+ if (localLOGV) Slog.v(TAG, "Timeout short service " + s);
+ s.callOnTimeout(startId);
+
+ // TODO(short-service): Do we need "service executing" for timeout?
+ // (see handleStopService())
+ } catch (Exception e) {
+ if (!mInstrumentation.onException(s, e)) {
+ throw new RuntimeException(
+ "Unable to timeout service " + s
+ + ": " + e.toString(), e);
+ }
+ Slog.i(TAG, "handleTimeoutService: exception for " + token, e);
+ }
+ } else {
+ Slog.wtf(TAG, "handleTimeoutService: token=" + token + " not found.");
+ }
+ }
/**
* Resume the activity.
* @param r Target activity record.
diff --git a/core/java/android/app/ApplicationExitInfo.java b/core/java/android/app/ApplicationExitInfo.java
index 5517c57d1f1e..871d15ec0b40 100644
--- a/core/java/android/app/ApplicationExitInfo.java
+++ b/core/java/android/app/ApplicationExitInfo.java
@@ -407,6 +407,15 @@ public final class ApplicationExitInfo implements Parcelable {
*/
public static final int SUBREASON_PACKAGE_UPDATE = 25;
+ /**
+ * The process was killed because of undelivered broadcasts; this would be set only when the
+ * reason is {@link #REASON_OTHER}.
+ *
+ * For internal use only.
+ * @hide
+ */
+ public static final int SUBREASON_UNDELIVERED_BROADCAST = 26;
+
// If there is any OEM code which involves additional app kill reasons, it should
// be categorized in {@link #REASON_OTHER}, with subreason code starting from 1000.
@@ -579,6 +588,7 @@ public final class ApplicationExitInfo implements Parcelable {
SUBREASON_STOP_APP,
SUBREASON_KILL_BACKGROUND,
SUBREASON_PACKAGE_UPDATE,
+ SUBREASON_UNDELIVERED_BROADCAST,
})
@Retention(RetentionPolicy.SOURCE)
public @interface SubReason {}
@@ -1283,6 +1293,8 @@ public final class ApplicationExitInfo implements Parcelable {
return "KILL BACKGROUND";
case SUBREASON_PACKAGE_UPDATE:
return "PACKAGE UPDATE";
+ case SUBREASON_UNDELIVERED_BROADCAST:
+ return "UNDELIVERED BROADCAST";
default:
return "UNKNOWN";
}
diff --git a/core/java/android/app/BroadcastOptions.java b/core/java/android/app/BroadcastOptions.java
index 1777f37202c2..f25e639a9c80 100644
--- a/core/java/android/app/BroadcastOptions.java
+++ b/core/java/android/app/BroadcastOptions.java
@@ -66,8 +66,9 @@ public class BroadcastOptions extends ComponentOptions {
private long mIdForResponseEvent;
private @Nullable IntentFilter mRemoveMatchingFilter;
private @DeliveryGroupPolicy int mDeliveryGroupPolicy;
- private @Nullable String mDeliveryGroupKey;
+ private @Nullable String mDeliveryGroupMatchingKey;
private @Nullable BundleMerger mDeliveryGroupExtrasMerger;
+ private @Nullable IntentFilter mDeliveryGroupMatchingFilter;
/**
* Change ID which is invalid.
@@ -206,10 +207,10 @@ public class BroadcastOptions extends ComponentOptions {
"android:broadcast.deliveryGroupPolicy";
/**
- * Corresponds to {@link #setDeliveryGroupKey(String, String)}.
+ * Corresponds to {@link #setDeliveryGroupMatchingKey(String, String)}.
*/
private static final String KEY_DELIVERY_GROUP_KEY =
- "android:broadcast.deliveryGroupKey";
+ "android:broadcast.deliveryGroupMatchingKey";
/**
* Corresponds to {@link #setDeliveryGroupExtrasMerger(BundleMerger)}.
@@ -218,6 +219,12 @@ public class BroadcastOptions extends ComponentOptions {
"android:broadcast.deliveryGroupExtrasMerger";
/**
+ * Corresponds to {@link #setDeliveryGroupMatchingFilter(IntentFilter)}.
+ */
+ private static final String KEY_DELIVERY_GROUP_MATCHING_FILTER =
+ "android:broadcast.deliveryGroupMatchingFilter";
+
+ /**
* The list of delivery group policies which specify how multiple broadcasts belonging to
* the same delivery group has to be handled.
* @hide
@@ -304,9 +311,11 @@ public class BroadcastOptions extends ComponentOptions {
IntentFilter.class);
mDeliveryGroupPolicy = opts.getInt(KEY_DELIVERY_GROUP_POLICY,
DELIVERY_GROUP_POLICY_ALL);
- mDeliveryGroupKey = opts.getString(KEY_DELIVERY_GROUP_KEY);
+ mDeliveryGroupMatchingKey = opts.getString(KEY_DELIVERY_GROUP_KEY);
mDeliveryGroupExtrasMerger = opts.getParcelable(KEY_DELIVERY_GROUP_EXTRAS_MERGER,
BundleMerger.class);
+ mDeliveryGroupMatchingFilter = opts.getParcelable(KEY_DELIVERY_GROUP_MATCHING_FILTER,
+ IntentFilter.class);
}
/**
@@ -733,7 +742,7 @@ public class BroadcastOptions extends ComponentOptions {
/**
* Clears any previously set delivery group policies using
- * {@link #setDeliveryGroupKey(String, String)} and resets the delivery group policy to
+ * {@link #setDeliveryGroupMatchingKey(String, String)} and resets the delivery group policy to
* the default value ({@link #DELIVERY_GROUP_POLICY_ALL}).
*
* @hide
@@ -745,22 +754,92 @@ public class BroadcastOptions extends ComponentOptions {
/**
* Set namespace and key to identify the delivery group that this broadcast belongs to.
- * If no namespace and key is set, then by default {@link Intent#filterEquals(Intent)} will be
- * used to identify the delivery group.
+ *
+ * <p> If {@code namespace} and {@code key} are specified, then another broadcast will be
+ * considered to be in the same delivery group as this iff it has the same {@code namespace}
+ * and {@code key}.
+ *
+ * <p> If neither matching key using this API nor matching filter using
+ * {@link #setDeliveryGroupMatchingFilter(IntentFilter)} is specified, then by default
+ * {@link Intent#filterEquals(Intent)} will be used to identify the delivery group.
*
* @hide
*/
- public void setDeliveryGroupKey(@NonNull String namespace, @NonNull String key) {
+ @SystemApi
+ public void setDeliveryGroupMatchingKey(@NonNull String namespace, @NonNull String key) {
Preconditions.checkArgument(!namespace.contains("/"),
"namespace should not contain '/'");
Preconditions.checkArgument(!key.contains("/"),
"key should not contain '/'");
- mDeliveryGroupKey = namespace + "/" + key;
+ mDeliveryGroupMatchingKey = namespace + "/" + key;
}
- /** @hide */
- public String getDeliveryGroupKey() {
- return mDeliveryGroupKey;
+ /**
+ * Return the namespace and key that is used to identify the delivery group that this
+ * broadcast belongs to.
+ *
+ * @return the delivery group namespace and key that was previously set using
+ * {@link #setDeliveryGroupMatchingKey(String, String)}, concatenated with a {@code /}.
+ * @hide
+ */
+ @SystemApi
+ @Nullable
+ public String getDeliveryGroupMatchingKey() {
+ return mDeliveryGroupMatchingKey;
+ }
+
+ /**
+ * Clears the namespace and key that was previously set using
+ * {@link #setDeliveryGroupMatchingKey(String, String)}.
+ *
+ * @hide
+ */
+ @SystemApi
+ public void clearDeliveryGroupMatchingKey() {
+ mDeliveryGroupMatchingKey = null;
+ }
+
+ /**
+ * Set the {@link IntentFilter} object to identify the delivery group that this broadcast
+ * belongs to.
+ *
+ * <p> If a {@code matchingFilter} is specified, then another broadcast will be considered
+ * to be in the same delivery group as this iff the {@code matchingFilter} matches it's intent.
+ *
+ * <p> If neither matching key using {@link #setDeliveryGroupMatchingKey(String, String)} nor
+ * matching filter using this API is specified, then by default
+ * {@link Intent#filterEquals(Intent)} will be used to identify the delivery group.
+ *
+ * @hide
+ */
+ @SystemApi
+ public void setDeliveryGroupMatchingFilter(@NonNull IntentFilter matchingFilter) {
+ mDeliveryGroupMatchingFilter = Objects.requireNonNull(matchingFilter);
+ }
+
+ /**
+ * Return the {@link IntentFilter} object that is used to identify the delivery group
+ * that this broadcast belongs to.
+ *
+ * @return the {@link IntentFilter} object that was previously set using
+ * {@link #setDeliveryGroupMatchingFilter(IntentFilter)}.
+ * @hide
+ */
+ @SystemApi
+ @Nullable
+ public IntentFilter getDeliveryGroupMatchingFilter() {
+ return mDeliveryGroupMatchingFilter;
+ }
+
+ /**
+ * Clears the {@link IntentFilter} object that was previously set using
+ * {@link #setDeliveryGroupMatchingFilter(IntentFilter)}.
+ *
+ * @hide
+ */
+ @SystemApi
+ public void clearDeliveryGroupMatchingFilter() {
+ mDeliveryGroupMatchingFilter = null;
}
/**
@@ -773,16 +852,33 @@ public class BroadcastOptions extends ComponentOptions {
* @hide
*/
public void setDeliveryGroupExtrasMerger(@NonNull BundleMerger extrasMerger) {
- Preconditions.checkNotNull(extrasMerger);
- mDeliveryGroupExtrasMerger = extrasMerger;
+ mDeliveryGroupExtrasMerger = Objects.requireNonNull(extrasMerger);
}
- /** @hide */
- public @Nullable BundleMerger getDeliveryGroupExtrasMerger() {
+ /**
+ * Return the {@link BundleMerger} that specifies how to merge the extras data from
+ * broadcasts in a delivery group.
+ *
+ * @return the {@link BundleMerger} object that was previously set using
+ * {@link #setDeliveryGroupExtrasMerger(BundleMerger)}.
+ * @hide
+ */
+ @Nullable
+ public BundleMerger getDeliveryGroupExtrasMerger() {
return mDeliveryGroupExtrasMerger;
}
/**
+ * Clear the {@link BundleMerger} object that was previously set using
+ * {@link #setDeliveryGroupExtrasMerger(BundleMerger)}.
+ *
+ * @hide
+ */
+ public void clearDeliveryGroupExtrasMerger() {
+ mDeliveryGroupExtrasMerger = null;
+ }
+
+ /**
* Returns the created options as a Bundle, which can be passed to
* {@link android.content.Context#sendBroadcast(android.content.Intent)
* Context.sendBroadcast(Intent)} and related methods.
@@ -837,8 +933,8 @@ public class BroadcastOptions extends ComponentOptions {
if (mDeliveryGroupPolicy != DELIVERY_GROUP_POLICY_ALL) {
b.putInt(KEY_DELIVERY_GROUP_POLICY, mDeliveryGroupPolicy);
}
- if (mDeliveryGroupKey != null) {
- b.putString(KEY_DELIVERY_GROUP_KEY, mDeliveryGroupKey);
+ if (mDeliveryGroupMatchingKey != null) {
+ b.putString(KEY_DELIVERY_GROUP_KEY, mDeliveryGroupMatchingKey);
}
if (mDeliveryGroupPolicy == DELIVERY_GROUP_POLICY_MERGED) {
if (mDeliveryGroupExtrasMerger != null) {
@@ -849,6 +945,9 @@ public class BroadcastOptions extends ComponentOptions {
+ "when delivery group policy is 'MERGED'");
}
}
+ if (mDeliveryGroupMatchingFilter != null) {
+ b.putParcelable(KEY_DELIVERY_GROUP_MATCHING_FILTER, mDeliveryGroupMatchingFilter);
+ }
return b.isEmpty() ? null : b;
}
}
diff --git a/core/java/android/app/ForegroundServiceTypePolicy.java b/core/java/android/app/ForegroundServiceTypePolicy.java
index eccc5631d86a..e419e0602f2a 100644
--- a/core/java/android/app/ForegroundServiceTypePolicy.java
+++ b/core/java/android/app/ForegroundServiceTypePolicy.java
@@ -31,6 +31,7 @@ import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE;
import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_NONE;
import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_PHONE_CALL;
import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_REMOTE_MESSAGING;
+import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_SHORT_SERVICE;
import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_SPECIAL_USE;
import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_SYSTEM_EXEMPTED;
@@ -378,6 +379,19 @@ public abstract class ForegroundServiceTypePolicy {
);
/**
+ * The policy for the {@link ServiceInfo#FOREGROUND_SERVICE_TYPE_SHORT_SERVICE}.
+ *
+ * @hide
+ */
+ public static final @NonNull ForegroundServiceTypePolicyInfo FGS_TYPE_POLICY_SHORT_SERVICE =
+ new ForegroundServiceTypePolicyInfo(
+ FOREGROUND_SERVICE_TYPE_SHORT_SERVICE,
+ ForegroundServiceTypePolicyInfo.INVALID_CHANGE_ID,
+ ForegroundServiceTypePolicyInfo.INVALID_CHANGE_ID,
+ null /* no type specific permissions */, null /* no type specific permissions */
+ );
+
+ /**
* The policy for the {@link ServiceInfo#FOREGROUND_SERVICE_TYPE_SPECIAL_USE}.
*
* @hide
@@ -964,6 +978,8 @@ public abstract class ForegroundServiceTypePolicy {
FGS_TYPE_POLICY_REMOTE_MESSAGING);
mForegroundServiceTypePolicies.put(FOREGROUND_SERVICE_TYPE_SYSTEM_EXEMPTED,
FGS_TYPE_POLICY_SYSTEM_EXEMPTED);
+ mForegroundServiceTypePolicies.put(FOREGROUND_SERVICE_TYPE_SHORT_SERVICE,
+ FGS_TYPE_POLICY_SHORT_SERVICE);
mForegroundServiceTypePolicies.put(FOREGROUND_SERVICE_TYPE_SPECIAL_USE,
FGS_TYPE_POLICY_SPECIAL_USE);
}
diff --git a/core/java/android/app/GameManager.java b/core/java/android/app/GameManager.java
index a5adaa4e0196..f92194d3ffac 100644
--- a/core/java/android/app/GameManager.java
+++ b/core/java/android/app/GameManager.java
@@ -26,6 +26,9 @@ import android.annotation.SystemService;
import android.annotation.TestApi;
import android.annotation.UserHandleAware;
import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.os.Build;
import android.os.Handler;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -51,6 +54,7 @@ public final class GameManager {
GAME_MODE_STANDARD, // 1
GAME_MODE_PERFORMANCE, // 2
GAME_MODE_BATTERY, // 3
+ GAME_MODE_CUSTOM, // 4
})
@Retention(RetentionPolicy.SOURCE)
public @interface GameMode {
@@ -79,6 +83,15 @@ public final class GameManager {
*/
public static final int GAME_MODE_BATTERY = 3;
+ /**
+ * Custom game mode that has user-provided configuration overrides.
+ * <p>
+ * Custom game mode is expected to be handled only by the platform using users'
+ * preferred config. It is currently not allowed to opt in custom mode in game mode XML file nor
+ * expected to perform app-based optimizations when activated.
+ */
+ public static final int GAME_MODE_CUSTOM = 4;
+
GameManager(Context context, Handler handler) throws ServiceNotFoundException {
mContext = context;
mService = IGameManagerService.Stub.asInterface(
@@ -93,19 +106,23 @@ public final class GameManager {
* application is not a game, always return {@link #GAME_MODE_UNSUPPORTED}.
* <p>
* Developers should call this API every time the application is resumed.
+ * <p>
+ * If a game's <code>targetSdkVersion</code> is {@link android.os.Build.VERSION_CODES#TIRAMISU}
+ * or lower, and when the game mode is set to {@link #GAME_MODE_CUSTOM} which is available in
+ * {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE} or newer, this API will return
+ * {@link #GAME_MODE_STANDARD} instead for backward compatibility.
*/
public @GameMode int getGameMode() {
- try {
- return mService.getGameMode(mContext.getPackageName(), mContext.getUserId());
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ return getGameModeImpl(mContext.getPackageName(),
+ mContext.getApplicationInfo().targetSdkVersion);
}
/**
* Gets the game mode for the given package.
* <p>
* The caller must have {@link android.Manifest.permission#MANAGE_GAME_MODE}.
+ * <p>
+ * Also see {@link #getGameMode()} on how it handles SDK version compatibility.
*
* @hide
*/
@@ -113,11 +130,32 @@ public final class GameManager {
@UserHandleAware
@RequiresPermission(Manifest.permission.MANAGE_GAME_MODE)
public @GameMode int getGameMode(@NonNull String packageName) {
+ final int targetSdkVersion;
+ try {
+ final ApplicationInfo applicationInfo = mContext.getPackageManager().getApplicationInfo(
+ packageName, PackageManager.ApplicationInfoFlags.of(0));
+ targetSdkVersion = applicationInfo.targetSdkVersion;
+ } catch (PackageManager.NameNotFoundException ex) {
+ return GAME_MODE_UNSUPPORTED;
+ }
+ return getGameModeImpl(packageName, targetSdkVersion);
+ }
+
+ // This target SDK version check can be performed against any game by a privileged app, and
+ // we don't want a binder call each time to check on behalf of an app using CompatChange.
+ @SuppressWarnings("AndroidFrameworkCompatChange")
+ private @GameMode int getGameModeImpl(@NonNull String packageName, int targetSdkVersion) {
+ final int gameMode;
try {
- return mService.getGameMode(packageName, mContext.getUserId());
+ gameMode = mService.getGameMode(packageName,
+ mContext.getUserId());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
+ if (gameMode == GAME_MODE_CUSTOM && targetSdkVersion <= Build.VERSION_CODES.TIRAMISU) {
+ return GAME_MODE_STANDARD;
+ }
+ return gameMode;
}
/**
@@ -149,7 +187,9 @@ public final class GameManager {
* Sets the game mode for the given package.
* <p>
* The caller must have {@link android.Manifest.permission#MANAGE_GAME_MODE}.
- *
+ * <p>
+ * Setting the game mode on a non-game application or setting a game to
+ * {@link #GAME_MODE_UNSUPPORTED} will have no effect.
* @hide
*/
@SystemApi
@@ -241,4 +281,25 @@ public final class GameManager {
throw e.rethrowFromSystemServer();
}
}
+
+ /**
+ * Updates the config for the game's {@link #GAME_MODE_CUSTOM} mode.
+ * <p>
+ * The caller must have {@link android.Manifest.permission#MANAGE_GAME_MODE}.
+ *
+ * @param gameModeConfig The configuration to use for game mode interventions
+ * @hide
+ */
+ @SystemApi
+ @UserHandleAware
+ @RequiresPermission(Manifest.permission.MANAGE_GAME_MODE)
+ public void updateCustomGameModeConfiguration(@NonNull String packageName,
+ @NonNull GameModeConfiguration gameModeConfig) {
+ try {
+ mService.updateCustomGameModeConfiguration(packageName, gameModeConfig,
+ mContext.getUserId());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
}
diff --git a/core/java/android/app/timezone/ICallback.aidl b/core/java/android/app/GameModeConfiguration.aidl
index 519ef1a86350..14ac9cde8896 100644
--- a/core/java/android/app/timezone/ICallback.aidl
+++ b/core/java/android/app/GameModeConfiguration.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,14 +14,7 @@
* limitations under the License.
*/
-package android.app.timezone;
+package android.app;
-/**
- * Callback interface for a timezone updater to receive information about the success or failure of
- * an installation/uninstallation attempt.
- *
- * {@hide}
- */
-oneway interface ICallback {
- void onFinished(int error);
-} \ No newline at end of file
+/** @hide*/
+parcelable GameModeConfiguration; \ No newline at end of file
diff --git a/core/java/android/app/GameModeConfiguration.java b/core/java/android/app/GameModeConfiguration.java
new file mode 100644
index 000000000000..b081e82e19b0
--- /dev/null
+++ b/core/java/android/app/GameModeConfiguration.java
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.view.Display;
+
+import androidx.annotation.FloatRange;
+import androidx.annotation.IntRange;
+
+import com.android.internal.annotations.Immutable;
+import com.android.internal.util.Preconditions;
+
+/**
+ * GameModeConfiguration is the game's platform configuration for a game mode.
+ * <p>
+ * Only the game modes that are enabled by OEMs will have an active configuration, whereas game
+ * modes opted in by the game will not.
+ *
+ * @hide
+ */
+@Immutable
+@SystemApi
+public final class GameModeConfiguration implements Parcelable {
+ // Default value indicating that no FPS override will be applied as game intervention, or
+ // default to the current display mode's frame rate.
+ public static final int FPS_OVERRIDE_NONE = 0;
+
+ public static final @NonNull Creator<GameModeConfiguration> CREATOR = new Creator<>() {
+ @Override
+ public GameModeConfiguration createFromParcel(Parcel in) {
+ return new GameModeConfiguration(in);
+ }
+
+ @Override
+ public GameModeConfiguration[] newArray(int size) {
+ return new GameModeConfiguration[size];
+ }
+ };
+
+ /**
+ * Builder for {@link GameModeConfiguration}.
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final class Builder {
+ /** Constructs a new Builder for a game mode’s configuration */
+ public Builder() {
+ }
+
+ /**
+ * Sets the scaling factor used for game resolution downscaling.
+ * <br>
+ *
+ * @param scalingFactor the desired scaling factor ranged from 0.1 to 1.0 inclusively
+ * @throws IllegalArgumentException if the scaling factor is not in range of [0.1, 1.0]
+ */
+ @NonNull
+ public GameModeConfiguration.Builder setScalingFactor(
+ @FloatRange(from = 0.1, to = 1.0) float scalingFactor) {
+ Preconditions.checkArgument(scalingFactor >= 0.1 && scalingFactor <= 1.0,
+ "Scaling factor should fall between 0.1 and 1.0 (inclusive)");
+ mScalingFactor = scalingFactor;
+ return this;
+ }
+
+ /**
+ * Sets the FPS override used for game frame rate throttling.
+ * <br>
+ * The list of valid throttled frame rates can be queried by
+ * <ol>
+ * <li>Obtain display modes by calling {@link Display#getSupportedModes}
+ * <li>For each mode, get valid FPS by getting the divisor of the
+ * {@link Display.Mode#getRefreshRate()} that is >= 30,
+ * e.g. when Display.Mode#getRefreshRate() is 120 Hz, the valid FPS
+ * of this mode is 120, 60, 40, 30
+ * <li>Aggregate the valid FPS of each mode to get the full list
+ * </ol>
+ * <br>
+ *
+ * @param fpsOverride the desired non-negative FPS override value, default to
+ * {@link #FPS_OVERRIDE_NONE}.
+ * @throws IllegalArgumentException if the provided value is negative
+ */
+ @NonNull
+ public GameModeConfiguration.Builder setFpsOverride(@IntRange(from = 0) int fpsOverride) {
+ Preconditions.checkArgument(fpsOverride >= 0,
+ "FPS override should be non-negative");
+ mFpsOverride = fpsOverride;
+ return this;
+ }
+
+ /**
+ * Builds a GameModeConfiguration.
+ */
+ @NonNull
+ public GameModeConfiguration build() {
+ return new GameModeConfiguration(mScalingFactor, mFpsOverride);
+ }
+
+ ;
+ private float mScalingFactor;
+ private int mFpsOverride;
+ }
+
+ GameModeConfiguration(float scalingFactor, int fpsOverride) {
+ this.mScalingFactor = scalingFactor;
+ this.mFpsOverride = fpsOverride;
+ }
+
+ GameModeConfiguration(Parcel in) {
+ this.mScalingFactor = in.readFloat();
+ this.mFpsOverride = in.readInt();
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeFloat(mScalingFactor);
+ dest.writeInt(mFpsOverride);
+ }
+
+ /**
+ * Gets the scaling factor used for game resolution downscaling.
+ */
+ public float getScalingFactor() {
+ return mScalingFactor;
+ }
+
+ /**
+ * Gets the FPS override used for frame rate throttling.
+ */
+ public int getFpsOverride() {
+ return mFpsOverride;
+ }
+
+ /**
+ * Converts and returns the game mode config as a new builder.
+ */
+ @NonNull
+ public GameModeConfiguration.Builder toBuilder() {
+ return new GameModeConfiguration.Builder()
+ .setFpsOverride(mFpsOverride)
+ .setScalingFactor(mScalingFactor);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (!(obj instanceof GameModeConfiguration)) {
+ return false;
+ }
+ GameModeConfiguration config = (GameModeConfiguration) obj;
+ return config.mFpsOverride == this.mFpsOverride
+ && config.mScalingFactor == this.mScalingFactor;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = 7;
+ result = 31 * result + mFpsOverride;
+ result = 31 * result + Float.floatToIntBits(mScalingFactor);
+ return result;
+ }
+
+ private final float mScalingFactor;
+ private final int mFpsOverride;
+}
diff --git a/core/java/android/app/GameModeInfo.java b/core/java/android/app/GameModeInfo.java
index fe0ac352404d..31255c2e381f 100644
--- a/core/java/android/app/GameModeInfo.java
+++ b/core/java/android/app/GameModeInfo.java
@@ -20,9 +20,34 @@ import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
+import android.util.ArrayMap;
+
+import androidx.annotation.Nullable;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.util.Arrays;
+import java.util.Map;
/**
* GameModeInfo returned from {@link GameManager#getGameModeInfo(String)}.
+ *
+ * Developers can enable game modes or interventions by adding
+ * <pre>{@code
+ * <meta-data android:name="android.game_mode_intervention"
+ * android:resource="@xml/GAME_MODE_CONFIG_FILE" />
+ * }</pre>
+ * to the <pre>{@code <application>}</pre>, where the GAME_MODE_CONFIG_FILE is an XML file that
+ * specifies the game mode enablement and intervention configuration:
+ * <pre>{@code
+ * <game-mode-config xmlns:android="http://schemas.android.com/apk/res/android"
+ * android:gameModePerformance="true"
+ * android:gameModeBattery="false"
+ * android:allowGameDownscaling="true"
+ * android:allowGameFpsOverride="false"
+ * />
+ * }</pre>
+ *
* @hide
*/
@SystemApi
@@ -40,52 +65,196 @@ public final class GameModeInfo implements Parcelable {
}
};
+ /**
+ * Builder for {@link GameModeInfo}.
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final class Builder {
+ /** Constructs a new Builder for a game mode info. */
+ public Builder() {
+ }
+
+ /**
+ * Sets the available game modes.
+ */
+ @NonNull
+ public GameModeInfo.Builder setAvailableGameModes(
+ @NonNull @GameManager.GameMode int[] availableGameModes) {
+ mAvailableGameModes = availableGameModes;
+ return this;
+ }
+
+ /**
+ * Sets the opted-in game modes.
+ */
+ @NonNull
+ public GameModeInfo.Builder setOptedInGameModes(
+ @NonNull @GameManager.GameMode int[] optedInGameModes) {
+ mOptedInGameModes = optedInGameModes;
+ return this;
+ }
+
+ /**
+ * Sets the active game mode.
+ */
+ @NonNull
+ public GameModeInfo.Builder setActiveGameMode(
+ @NonNull @GameManager.GameMode int activeGameMode) {
+ mActiveGameMode = activeGameMode;
+ return this;
+ }
+
+ /**
+ * Sets the downscaling intervention flag.
+ */
+ @NonNull
+ public GameModeInfo.Builder setDownscalingAllowed(boolean allowed) {
+ mIsDownscalingAllowed = allowed;
+ return this;
+ }
+
+ /**
+ * Sets the FPS override flag.
+ */
+ @NonNull
+ public GameModeInfo.Builder setFpsOverrideAllowed(boolean allowed) {
+ mIsFpsOverrideAllowed = allowed;
+ return this;
+ }
+
+ /**
+ * Sets the GameModeConfiguration for a game mode.
+ */
+ @NonNull
+ public GameModeInfo.Builder setGameModeConfiguration(
+ @GameManager.GameMode int gameMode,
+ @NonNull GameModeConfiguration gameModeConfiguration) {
+ mConfigMap.put(gameMode, gameModeConfiguration);
+ return this;
+ }
+
+ /**
+ * Builds a GameModeInfo.
+ */
+ @NonNull
+ public GameModeInfo build() {
+ return new GameModeInfo(mActiveGameMode, mAvailableGameModes, mOptedInGameModes,
+ mIsDownscalingAllowed, mIsFpsOverrideAllowed, mConfigMap);
+ }
+
+ private @GameManager.GameMode int[] mAvailableGameModes = new int[]{};
+ private @GameManager.GameMode int[] mOptedInGameModes = new int[]{};
+ private @GameManager.GameMode int mActiveGameMode;
+ private boolean mIsDownscalingAllowed;
+ private boolean mIsFpsOverrideAllowed;
+ private Map<Integer, GameModeConfiguration> mConfigMap = new ArrayMap<>();
+ }
+
+ /**
+ * Creates a game mode info.
+ *
+ * @deprecated Use the {@link Builder} instead.
+ */
public GameModeInfo(@GameManager.GameMode int activeGameMode,
@NonNull @GameManager.GameMode int[] availableGameModes) {
+ this(activeGameMode, availableGameModes, new int[]{}, true, true, new ArrayMap<>());
+ }
+
+ private GameModeInfo(@GameManager.GameMode int activeGameMode,
+ @NonNull @GameManager.GameMode int[] availableGameModes,
+ @NonNull @GameManager.GameMode int[] optedInGameModes, boolean isDownscalingAllowed,
+ boolean isFpsOverrideAllowed, @NonNull Map<Integer, GameModeConfiguration> configMap) {
mActiveGameMode = activeGameMode;
- mAvailableGameModes = availableGameModes;
+ mAvailableGameModes = Arrays.copyOf(availableGameModes, availableGameModes.length);
+ mOptedInGameModes = Arrays.copyOf(optedInGameModes, optedInGameModes.length);
+ mIsDownscalingAllowed = isDownscalingAllowed;
+ mIsFpsOverrideAllowed = isFpsOverrideAllowed;
+ mConfigMap = configMap;
}
- GameModeInfo(Parcel in) {
+ /** @hide */
+ @VisibleForTesting
+ public GameModeInfo(Parcel in) {
mActiveGameMode = in.readInt();
- final int availableGameModesCount = in.readInt();
- mAvailableGameModes = new int[availableGameModesCount];
- in.readIntArray(mAvailableGameModes);
+ mAvailableGameModes = in.createIntArray();
+ mOptedInGameModes = in.createIntArray();
+ mIsDownscalingAllowed = in.readBoolean();
+ mIsFpsOverrideAllowed = in.readBoolean();
+ mConfigMap = new ArrayMap<>();
+ in.readMap(mConfigMap,
+ getClass().getClassLoader(), Integer.class, GameModeConfiguration.class);
}
/**
* Returns the {@link GameManager.GameMode} the application is currently using.
- * Developers can enable game modes by adding
- * <code>
- * <meta-data android:name="android.game_mode_intervention"
- * android:resource="@xml/GAME_MODE_CONFIG_FILE" />
- * </code>
- * to the {@link <application> tag}, where the GAME_MODE_CONFIG_FILE is an XML file that
- * specifies the game mode enablement and configuration:
- * <code>
- * <game-mode-config xmlns:android="http://schemas.android.com/apk/res/android"
- * android:gameModePerformance="true"
- * android:gameModeBattery="false"
- * />
- * </code>
*/
public @GameManager.GameMode int getActiveGameMode() {
return mActiveGameMode;
}
/**
- * The collection of {@link GameManager.GameMode GameModes} that can be applied to the game.
+ * Gets the collection of {@link GameManager.GameMode} that can be applied to the game.
+ * <p>
+ * Available games include all game modes that are either supported by the OEM in device
+ * config, or opted in by the game developers in game mode config XML, plus the default enabled
+ * modes for any game including {@link GameManager#GAME_MODE_STANDARD} and
+ * {@link GameManager#GAME_MODE_CUSTOM}.
+ * <p>
+ * Also see {@link GameModeInfo}.
*/
@NonNull
public @GameManager.GameMode int[] getAvailableGameModes() {
- return mAvailableGameModes;
+ return Arrays.copyOf(mAvailableGameModes, mAvailableGameModes.length);
+ }
+
+ /**
+ * Gets the collection of {@link GameManager.GameMode} that are opted in by the game.
+ * <p>
+ * Also see {@link GameModeInfo}.
+ */
+ @NonNull
+ public @GameManager.GameMode int[] getOptedInGameModes() {
+ return Arrays.copyOf(mOptedInGameModes, mOptedInGameModes.length);
}
- // Ideally there should be callback that the caller can register to know when the available
- // GameMode and/or the active GameMode is changed, however, there's no concrete use case
- // at the moment so there's no callback mechanism introduced .
+ /**
+ * Gets the current game mode configuration of a game mode.
+ * <p>
+ * The game mode can be null if it's opted in by the game itself, or not configured in device
+ * config nor set by the user as custom game mode configuration.
+ */
+ public @Nullable GameModeConfiguration getGameModeConfiguration(
+ @GameManager.GameMode int gameMode) {
+ return mConfigMap.get(gameMode);
+ }
+
+ /**
+ * Returns if downscaling is allowed (not opted out) by the game in their Game Mode config.
+ * <p>
+ * Also see {@link GameModeInfo}.
+ */
+ public boolean isDownscalingAllowed() {
+ return mIsDownscalingAllowed;
+ }
+
+ /**
+ * Returns if FPS override is allowed (not opted out) by the game in their Game Mode config.
+ * <p>
+ * Also see {@link GameModeInfo}.
+ */
+ public boolean isFpsOverrideAllowed() {
+ return mIsFpsOverrideAllowed;
+ }
+
+
private final @GameManager.GameMode int[] mAvailableGameModes;
+ private final @GameManager.GameMode int[] mOptedInGameModes;
private final @GameManager.GameMode int mActiveGameMode;
+ private final boolean mIsDownscalingAllowed;
+ private final boolean mIsFpsOverrideAllowed;
+ private final Map<Integer, GameModeConfiguration> mConfigMap;
@Override
public int describeContents() {
@@ -95,7 +264,10 @@ public final class GameModeInfo implements Parcelable {
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeInt(mActiveGameMode);
- dest.writeInt(mAvailableGameModes.length);
dest.writeIntArray(mAvailableGameModes);
+ dest.writeIntArray(mOptedInGameModes);
+ dest.writeBoolean(mIsDownscalingAllowed);
+ dest.writeBoolean(mIsFpsOverrideAllowed);
+ dest.writeMap(mConfigMap);
}
}
diff --git a/core/java/android/app/IApplicationThread.aidl b/core/java/android/app/IApplicationThread.aidl
index 843b6846d053..595c7f7ab008 100644
--- a/core/java/android/app/IApplicationThread.aidl
+++ b/core/java/android/app/IApplicationThread.aidl
@@ -165,4 +165,5 @@ oneway interface IApplicationThread {
void updateUiTranslationState(IBinder activityToken, int state, in TranslationSpec sourceSpec,
in TranslationSpec targetSpec, in List<AutofillId> viewIds,
in UiTranslationSpec uiTranslationSpec);
+ void scheduleTimeoutService(IBinder token, int startId);
}
diff --git a/core/java/android/app/IGameManagerService.aidl b/core/java/android/app/IGameManagerService.aidl
index 481e7b0050ab..aea097d069dc 100644
--- a/core/java/android/app/IGameManagerService.aidl
+++ b/core/java/android/app/IGameManagerService.aidl
@@ -16,21 +16,37 @@
package android.app;
+import android.app.GameModeConfiguration;
import android.app.GameModeInfo;
import android.app.GameState;
+import android.app.IGameModeListener;
/**
* @hide
*/
interface IGameManagerService {
int getGameMode(String packageName, int userId);
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.MANAGE_GAME_MODE)")
void setGameMode(String packageName, int gameMode, int userId);
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.MANAGE_GAME_MODE)")
int[] getAvailableGameModes(String packageName);
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.MANAGE_GAME_MODE)")
boolean isAngleEnabled(String packageName, int userId);
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.MANAGE_GAME_MODE)")
void notifyGraphicsEnvironmentSetup(String packageName, int userId);
void setGameState(String packageName, in GameState gameState, int userId);
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.MANAGE_GAME_MODE)")
GameModeInfo getGameModeInfo(String packageName, int userId);
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.SET_GAME_SERVICE)")
void setGameServiceProvider(String packageName);
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.MANAGE_GAME_MODE)")
void updateResolutionScalingFactor(String packageName, int gameMode, float scalingFactor, int userId);
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.MANAGE_GAME_MODE)")
float getResolutionScalingFactor(String packageName, int gameMode, int userId);
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.MANAGE_GAME_MODE)")
+ void updateCustomGameModeConfiguration(String packageName, in GameModeConfiguration gameModeConfig, int userId);
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.MANAGE_GAME_MODE)")
+ void addGameModeListener(IGameModeListener gameModeListener);
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.MANAGE_GAME_MODE)")
+ void removeGameModeListener(IGameModeListener gameModeListener);
}
diff --git a/core/java/android/app/IGameModeListener.aidl b/core/java/android/app/IGameModeListener.aidl
new file mode 100644
index 000000000000..77fcac07f7e7
--- /dev/null
+++ b/core/java/android/app/IGameModeListener.aidl
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app;
+
+/** @hide */
+interface IGameModeListener {
+ /**
+ * Called when the game mode of the user has changed.
+ */
+ void onGameModeChanged(String packageName, int gameModeFrom, int gameModeTo, int userId);
+}
diff --git a/core/java/android/app/IWallpaperManager.aidl b/core/java/android/app/IWallpaperManager.aidl
index 167de463ad17..b1ed152e3344 100644
--- a/core/java/android/app/IWallpaperManager.aidl
+++ b/core/java/android/app/IWallpaperManager.aidl
@@ -50,9 +50,10 @@ interface IWallpaperManager {
IWallpaperManagerCallback completion, int userId);
/**
- * Set the live wallpaper. This only affects the system wallpaper.
+ * Set the live wallpaper.
*/
- void setWallpaperComponentChecked(in ComponentName name, in String callingPackage, int userId);
+ void setWallpaperComponentChecked(in ComponentName name, in String callingPackage, int which,
+ int userId);
/**
* Set the live wallpaper. This only affects the system wallpaper.
@@ -89,6 +90,12 @@ interface IWallpaperManager {
WallpaperInfo getWallpaperInfo(int userId);
/**
+ * If the current wallpaper for destination `which` is a live wallpaper component, return the
+ * information about that wallpaper. Otherwise, if it is a static image, simply return null.
+ */
+ WallpaperInfo getWallpaperInfoWithFlags(int which, int userId);
+
+ /**
* Clear the system wallpaper.
*/
void clearWallpaper(in String callingPackage, int which, int userId);
diff --git a/core/java/android/app/Service.java b/core/java/android/app/Service.java
index 754e3b628f79..291edbb74c35 100644
--- a/core/java/android/app/Service.java
+++ b/core/java/android/app/Service.java
@@ -1107,6 +1107,15 @@ public abstract class Service extends ContextWrapper implements ComponentCallbac
}
}
+ /** @hide */
+ public final void callOnTimeout(int startId) {
+ // TODO(short-service): Do we need any check here, to avoid races?
+ // e.g. if the service is already stopped, but ActivityThread.handleTimeoutService() is
+ // already scheduled, then we'll call this method anyway. It should be doable to prevent
+ // that if we keep track of startForeground, stopForeground, and onDestroy.
+ onTimeout(startId);
+ }
+
/**
* Callback called on timeout for {@link ServiceInfo#FOREGROUND_SERVICE_TYPE_SHORT_SERVICE}.
*
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index aaa3d21a0b25..e5cb0eaebdd3 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -42,7 +42,6 @@ import android.app.smartspace.SmartspaceManager;
import android.app.time.TimeManager;
import android.app.timedetector.TimeDetector;
import android.app.timedetector.TimeDetectorImpl;
-import android.app.timezone.RulesManager;
import android.app.timezonedetector.TimeZoneDetector;
import android.app.timezonedetector.TimeZoneDetectorImpl;
import android.app.trust.TrustManager;
@@ -1282,13 +1281,6 @@ public final class SystemServiceRegistry {
}
});
- registerService(Context.TIME_ZONE_RULES_MANAGER_SERVICE, RulesManager.class,
- new CachedServiceFetcher<RulesManager>() {
- @Override
- public RulesManager createService(ContextImpl ctx) {
- return new RulesManager(ctx.getOuterContext());
- }});
-
registerService(Context.CROSS_PROFILE_APPS_SERVICE, CrossProfileApps.class,
new CachedServiceFetcher<CrossProfileApps>() {
@Override
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index 6f1737aa6660..b9a7186dcd2e 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -67,7 +67,6 @@ import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.os.StrictMode;
import android.os.SystemProperties;
-import android.service.wallpaper.WallpaperService;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -521,10 +520,7 @@ public class WallpaperManager {
}
WallpaperColors getWallpaperColors(int which, int userId, int displayId) {
- if (which != FLAG_LOCK && which != FLAG_SYSTEM) {
- throw new IllegalArgumentException(
- "Must request colors for exactly one kind of wallpaper");
- }
+ checkExactlyOneWallpaperFlagSet(which);
try {
return mService.getWallpaperColors(which, userId, displayId);
@@ -857,9 +853,7 @@ public class WallpaperManager {
throw new RuntimeException(new DeadSystemException());
}
- if (which != FLAG_SYSTEM && which != FLAG_LOCK) {
- throw new IllegalArgumentException("Must request exactly one kind of wallpaper");
- }
+ checkExactlyOneWallpaperFlagSet(which);
Resources resources = mContext.getResources();
horizontalAlignment = Math.max(0, Math.min(1, horizontalAlignment));
@@ -1115,6 +1109,19 @@ public class WallpaperManager {
}
/**
+ * Like {@link #getDrawable()} but returns a Bitmap.
+ *
+ * @param hardware Asks for a hardware backed bitmap.
+ * @param which Specifies home or lock screen
+ * @see Bitmap.Config#HARDWARE
+ * @hide
+ */
+ @Nullable
+ public Bitmap getBitmap(boolean hardware, @SetWallpaperFlags int which) {
+ return getBitmapAsUser(mContext.getUserId(), hardware, which);
+ }
+
+ /**
* Like {@link #getDrawable()} but returns a Bitmap for the provided user.
*
* @hide
@@ -1125,6 +1132,17 @@ public class WallpaperManager {
}
/**
+ * Like {@link #getDrawable()} but returns a Bitmap for the provided user.
+ *
+ * @param which Specifies home or lock screen
+ * @hide
+ */
+ public Bitmap getBitmapAsUser(int userId, boolean hardware, @SetWallpaperFlags int which) {
+ final ColorManagementProxy cmProxy = getColorManagementProxy();
+ return sGlobals.peekWallpaperBitmap(mContext, true, which, userId, hardware, cmProxy);
+ }
+
+ /**
* Peek the dimensions of system wallpaper of the user without decoding it.
*
* @return the dimensions of system wallpaper
@@ -1281,9 +1299,7 @@ public class WallpaperManager {
*/
@UnsupportedAppUsage
public ParcelFileDescriptor getWallpaperFile(@SetWallpaperFlags int which, int userId) {
- if (which != FLAG_SYSTEM && which != FLAG_LOCK) {
- throw new IllegalArgumentException("Must request exactly one kind of wallpaper");
- }
+ checkExactlyOneWallpaperFlagSet(which);
if (sGlobals.mService == null) {
Log.w(TAG, "WallpaperService not running");
@@ -1333,16 +1349,7 @@ public class WallpaperManager {
* @hide
*/
public WallpaperInfo getWallpaperInfoForUser(int userId) {
- try {
- if (sGlobals.mService == null) {
- Log.w(TAG, "WallpaperService not running");
- throw new RuntimeException(new DeadSystemException());
- } else {
- return sGlobals.mService.getWallpaperInfo(userId);
- }
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ return getWallpaperInfo(FLAG_SYSTEM, userId);
}
/**
@@ -1353,10 +1360,10 @@ public class WallpaperManager {
* @param which Specifies wallpaper to request (home or lock).
* @throws IllegalArgumentException if {@code which} is not exactly one of
* {{@link #FLAG_SYSTEM},{@link #FLAG_LOCK}}.
- * @hide
*/
+ @Nullable
public WallpaperInfo getWallpaperInfo(@SetWallpaperFlags int which) {
- return getWallpaperInfo();
+ return getWallpaperInfo(which, mContext.getUserId());
}
/**
@@ -1371,7 +1378,17 @@ public class WallpaperManager {
* @hide
*/
public WallpaperInfo getWallpaperInfo(@SetWallpaperFlags int which, int userId) {
- return getWallpaperInfoForUser(userId);
+ checkExactlyOneWallpaperFlagSet(which);
+ try {
+ if (sGlobals.mService == null) {
+ Log.w(TAG, "WallpaperService not running");
+ throw new RuntimeException(new DeadSystemException());
+ } else {
+ return sGlobals.mService.getWallpaperInfoWithFlags(which, userId);
+ }
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
}
/**
@@ -2012,7 +2029,10 @@ public class WallpaperManager {
}
/**
- * Set the live wallpaper.
+ * Set the implementation of {@link android.service.wallpaper.WallpaperService} used to render
+ * wallpaper, usually in order to set a live wallpaper.
+ *
+ * @param name Name of the component to use.
*
* @hide
*/
@@ -2080,43 +2100,72 @@ public class WallpaperManager {
}
/**
- * Set the live wallpaper.
+ * Set the implementation of {@link android.service.wallpaper.WallpaperService} used to render
+ * wallpaper, usually in order to set a live wallpaper.
*
* This can only be called by packages with android.permission.SET_WALLPAPER_COMPONENT
* permission. The caller must hold the INTERACT_ACROSS_USERS_FULL permission to change
* another user's wallpaper.
*
+ * @param name Name of the component to use.
+ * @param userId User for whom the component should be set.
+ *
* @hide
*/
@RequiresPermission(android.Manifest.permission.SET_WALLPAPER_COMPONENT)
@UnsupportedAppUsage
public boolean setWallpaperComponent(ComponentName name, int userId) {
- if (sGlobals.mService == null) {
- Log.w(TAG, "WallpaperService not running");
- throw new RuntimeException(new DeadSystemException());
- }
- try {
- sGlobals.mService.setWallpaperComponentChecked(name, mContext.getOpPackageName(),
- userId);
- return true;
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ return setWallpaperComponentWithFlags(name, FLAG_SYSTEM | FLAG_LOCK, userId);
}
/**
- * Set the live wallpaper for the given screen(s).
+ * Set the implementation of {@link android.service.wallpaper.WallpaperService} used to render
+ * wallpaper, usually in order to set a live wallpaper, for a given wallpaper destination.
*
* This can only be called by packages with android.permission.SET_WALLPAPER_COMPONENT
* permission. The caller must hold the INTERACT_ACROSS_USERS_FULL permission to change
* another user's wallpaper.
*
+ * @param name Name of the component to use.
+ * @param which Specifies wallpaper destination (home and/or lock).
+ *
* @hide
*/
+ @SystemApi
@RequiresPermission(android.Manifest.permission.SET_WALLPAPER_COMPONENT)
public boolean setWallpaperComponentWithFlags(@NonNull ComponentName name,
@SetWallpaperFlags int which) {
- return setWallpaperComponent(name);
+ return setWallpaperComponentWithFlags(name, which, mContext.getUserId());
+ }
+
+ /**
+ * Set the implementation of {@link android.service.wallpaper.WallpaperService} used to render
+ * wallpaper, usually in order to set a live wallpaper, for a given wallpaper destination.
+ *
+ * This can only be called by packages with android.permission.SET_WALLPAPER_COMPONENT
+ * permission. The caller must hold the INTERACT_ACROSS_USERS_FULL permission to change
+ * another user's wallpaper.
+ *
+ * @param name Name of the component to use.
+ * @param which Specifies wallpaper destination (home and/or lock).
+ * @param userId User for whom the component should be set.
+ *
+ * @hide
+ */
+ @RequiresPermission(android.Manifest.permission.SET_WALLPAPER_COMPONENT)
+ public boolean setWallpaperComponentWithFlags(@NonNull ComponentName name,
+ @SetWallpaperFlags int which, int userId) {
+ if (sGlobals.mService == null) {
+ Log.w(TAG, "WallpaperManagerService not running");
+ throw new RuntimeException(new DeadSystemException());
+ }
+ try {
+ sGlobals.mService.setWallpaperComponentChecked(name, mContext.getOpPackageName(),
+ which, userId);
+ return true;
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
}
/**
@@ -2440,6 +2489,13 @@ public class WallpaperManager {
return mCmProxy;
}
+ private static void checkExactlyOneWallpaperFlagSet(@SetWallpaperFlags int which) {
+ if (which == FLAG_SYSTEM || which == FLAG_LOCK) {
+ return;
+ }
+ throw new IllegalArgumentException("Must specify exactly one kind of wallpaper");
+ }
+
/**
* A hidden class to help {@link Globals#getCurrentWallpaperLocked} handle color management.
* @hide
@@ -2519,7 +2575,7 @@ public class WallpaperManager {
*
* @param colors Wallpaper color info, {@code null} when not available.
* @param which A combination of {@link #FLAG_LOCK} and {@link #FLAG_SYSTEM}
- * @see WallpaperService.Engine#onComputeColors()
+ * @see android.service.wallpaper.WallpaperService.Engine#onComputeColors()
*/
void onColorsChanged(@Nullable WallpaperColors colors, int which);
@@ -2531,7 +2587,7 @@ public class WallpaperManager {
* @param colors Wallpaper color info, {@code null} when not available.
* @param which A combination of {@link #FLAG_LOCK} and {@link #FLAG_SYSTEM}
* @param userId Owner of the wallpaper
- * @see WallpaperService.Engine#onComputeColors()
+ * @see android.service.wallpaper.WallpaperService.Engine#onComputeColors()
* @hide
*/
default void onColorsChanged(@Nullable WallpaperColors colors, int which, int userId) {
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index be4df9d24c25..ecea1bb9ac8e 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -3937,6 +3937,34 @@ public class DevicePolicyManager {
throw new SecurityException("not implemented");
}
+ // TODO: Expose this as SystemAPI once we add the query API
+ /**
+ * @hide
+ */
+ public static final String AUTO_TIMEZONE_POLICY = "autoTimezone";
+
+ /**
+ * @hide
+ */
+ public static final String PERMISSION_GRANT_POLICY_KEY = "permissionGrant";
+
+ // TODO: Expose this as SystemAPI once we add the query API
+ /**
+ * @hide
+ */
+ public static String PERMISSION_GRANT_POLICY(
+ @NonNull String packageName, @NonNull String permission) {
+ Objects.requireNonNull(packageName);
+ Objects.requireNonNull(permission);
+ return PERMISSION_GRANT_POLICY_KEY + "_" + packageName + "_" + permission;
+ }
+
+ // TODO: Expose this as SystemAPI once we add the query API
+ /**
+ * @hide
+ */
+ public static final String LOCK_TASK_POLICY = "lockTask";
+
/**
* This object is a single place to tack on invalidation and disable calls. All
* binder caches in this class derive from this Config, so all can be invalidated or
diff --git a/core/java/android/app/backup/BackupManagerMonitor.java b/core/java/android/app/backup/BackupManagerMonitor.java
index 07e7688a48ae..d134ca27b354 100644
--- a/core/java/android/app/backup/BackupManagerMonitor.java
+++ b/core/java/android/app/backup/BackupManagerMonitor.java
@@ -129,6 +129,13 @@ public class BackupManagerMonitor {
*/
public static final String EXTRA_LOG_OLD_VERSION = "android.app.backup.extra.LOG_OLD_VERSION";
+ /**
+ * ParcelableList: when we have an event of id LOG_EVENT_ID_AGENT_LOGGING_RESULTS we send a list
+ * of {@link android.app.backup.BackupRestoreEventLogger.DataTypeResult}.
+ */
+ public static final String EXTRA_LOG_AGENT_LOGGING_RESULTS =
+ "android.app.backup.extra.LOG_AGENT_LOGGING_RESULTS";
+
// TODO complete this list with all log messages. And document properly.
public static final int LOG_EVENT_ID_FULL_BACKUP_CANCEL = 4;
public static final int LOG_EVENT_ID_ILLEGAL_KEY = 5;
@@ -171,15 +178,10 @@ public class BackupManagerMonitor {
public static final int LOG_EVENT_ID_WIDGET_UNKNOWN_VERSION = 48;
public static final int LOG_EVENT_ID_NO_PACKAGES = 49;
public static final int LOG_EVENT_ID_TRANSPORT_IS_NULL = 50;
+ /** The transport returned {@link BackupTransport#TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED}. */
+ public static final int LOG_EVENT_ID_TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED = 51;
- /**
- * The transport returned {@link BackupTransport#TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED}.
- */
- public static final int LOG_EVENT_ID_TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED = 51;
-
-
-
-
+ public static final int LOG_EVENT_ID_AGENT_LOGGING_RESULTS = 52;
/**
* This method will be called each time something important happens on BackupManager.
diff --git a/core/java/android/app/backup/BackupTransport.java b/core/java/android/app/backup/BackupTransport.java
index 90e9df47bc4b..f56c8c3b0bdb 100644
--- a/core/java/android/app/backup/BackupTransport.java
+++ b/core/java/android/app/backup/BackupTransport.java
@@ -661,8 +661,6 @@ public class BackupTransport {
*
* <p>Backups requested from outside the framework may pass in a monitor with the request,
* however backups initiated by the framework will call this method to retrieve one.
- *
- * @hide
*/
@Nullable
public BackupManagerMonitor getBackupManagerMonitor() {
diff --git a/core/java/android/app/timezone/Callback.java b/core/java/android/app/timezone/Callback.java
deleted file mode 100644
index e3840be6fe10..000000000000
--- a/core/java/android/app/timezone/Callback.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.app.timezone;
-
-import android.annotation.IntDef;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Callback interface for receiving information about an async time zone operation.
- * The methods will be called on your application's main thread.
- *
- * @hide
- */
-public abstract class Callback {
-
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(prefix = { "SUCCESS", "ERROR_" }, value = {
- SUCCESS,
- ERROR_UNKNOWN_FAILURE,
- ERROR_INSTALL_BAD_DISTRO_STRUCTURE,
- ERROR_INSTALL_BAD_DISTRO_FORMAT_VERSION,
- ERROR_INSTALL_RULES_TOO_OLD,
- ERROR_INSTALL_VALIDATION_ERROR
- })
- public @interface AsyncResultCode {}
-
- /**
- * Indicates that an operation succeeded.
- */
- public static final int SUCCESS = 0;
-
- /**
- * Indicates an install / uninstall did not fully succeed for an unknown reason.
- */
- public static final int ERROR_UNKNOWN_FAILURE = 1;
-
- /**
- * Indicates an install failed because of a structural issue with the provided distro,
- * e.g. it wasn't in the right format or the contents were structured incorrectly.
- */
- public static final int ERROR_INSTALL_BAD_DISTRO_STRUCTURE = 2;
-
- /**
- * Indicates an install failed because of a versioning issue with the provided distro,
- * e.g. it was created for a different version of Android.
- */
- public static final int ERROR_INSTALL_BAD_DISTRO_FORMAT_VERSION = 3;
-
- /**
- * Indicates an install failed because the rules provided are too old for the device,
- * e.g. the Android device shipped with a newer rules version.
- */
- public static final int ERROR_INSTALL_RULES_TOO_OLD = 4;
-
- /**
- * Indicates an install failed because the distro contents failed validation.
- */
- public static final int ERROR_INSTALL_VALIDATION_ERROR = 5;
-
- /**
- * Reports the result of an async time zone operation.
- */
- public abstract void onFinished(@AsyncResultCode int status);
-}
diff --git a/core/java/android/app/timezone/DistroFormatVersion.java b/core/java/android/app/timezone/DistroFormatVersion.java
deleted file mode 100644
index 13ecaf51052c..000000000000
--- a/core/java/android/app/timezone/DistroFormatVersion.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.app.timezone;
-
-import android.annotation.Nullable;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Versioning information about a distro's format or a device's supported format.
- *
- * <p>The following properties are included:
- * <dl>
- * <dt>majorVersion</dt>
- * <dd>the major distro format version. Major versions differences are not compatible - e.g.
- * 2 is not compatible with 1 or 3.</dd>
- * <dt>minorVersion</dt>
- * <dd>the minor distro format version. Minor versions should be backwards compatible iff the
- * major versions match exactly, i.e. version 2.2 will be compatible with 2.1 devices but not
- * 2.3 devices.</dd>
- * </dl>
- *
- * @hide
- */
-public final class DistroFormatVersion implements Parcelable {
-
- private final int mMajorVersion;
- private final int mMinorVersion;
-
- public DistroFormatVersion(int majorVersion, int minorVersion) {
- mMajorVersion = Utils.validateVersion("major", majorVersion);
- mMinorVersion = Utils.validateVersion("minor", minorVersion);
- }
-
- public static final @android.annotation.NonNull Creator<DistroFormatVersion> CREATOR = new Creator<DistroFormatVersion>() {
- public DistroFormatVersion createFromParcel(Parcel in) {
- int majorVersion = in.readInt();
- int minorVersion = in.readInt();
- return new DistroFormatVersion(majorVersion, minorVersion);
- }
-
- public DistroFormatVersion[] newArray(int size) {
- return new DistroFormatVersion[size];
- }
- };
-
- public int getMajorVersion() {
- return mMajorVersion;
- }
-
- public int getMinorVersion() {
- return mMinorVersion;
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel out, int flags) {
- out.writeInt(mMajorVersion);
- out.writeInt(mMinorVersion);
- }
-
- /**
- * If this object describes a device's supported version and the parameter describes a distro's
- * version, this method returns whether the device would accept the distro.
- */
- public boolean supports(DistroFormatVersion distroFormatVersion) {
- return mMajorVersion == distroFormatVersion.mMajorVersion
- && mMinorVersion <= distroFormatVersion.mMinorVersion;
- }
-
- @Override
- public boolean equals(@Nullable Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
-
- DistroFormatVersion that = (DistroFormatVersion) o;
-
- if (mMajorVersion != that.mMajorVersion) {
- return false;
- }
- return mMinorVersion == that.mMinorVersion;
- }
-
- @Override
- public int hashCode() {
- int result = mMajorVersion;
- result = 31 * result + mMinorVersion;
- return result;
- }
-
- @Override
- public String toString() {
- return "DistroFormatVersion{"
- + "mMajorVersion=" + mMajorVersion
- + ", mMinorVersion=" + mMinorVersion
- + '}';
- }
-}
diff --git a/core/java/android/app/timezone/DistroRulesVersion.java b/core/java/android/app/timezone/DistroRulesVersion.java
deleted file mode 100644
index 54937b8e6c3a..000000000000
--- a/core/java/android/app/timezone/DistroRulesVersion.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.app.timezone;
-
-import static android.app.timezone.Utils.validateRulesVersion;
-import static android.app.timezone.Utils.validateVersion;
-
-import android.annotation.Nullable;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Versioning information about a set of time zone rules.
- *
- * <p>The following properties are included:
- * <dl>
- * <dt>rulesVersion</dt>
- * <dd>the IANA rules version. e.g. "2017a"</dd>
- * <dt>revision</dt>
- * <dd>the revision for the rules. Allows there to be several revisions for a given IANA rules
- * release. Numerically higher is newer.</dd>
- * </dl>
- *
- * @hide
- */
-public final class DistroRulesVersion implements Parcelable {
-
- private final String mRulesVersion;
- private final int mRevision;
-
- public DistroRulesVersion(String rulesVersion, int revision) {
- mRulesVersion = validateRulesVersion("rulesVersion", rulesVersion);
- mRevision = validateVersion("revision", revision);
- }
-
- public static final @android.annotation.NonNull Creator<DistroRulesVersion> CREATOR = new Creator<DistroRulesVersion>() {
- public DistroRulesVersion createFromParcel(Parcel in) {
- String rulesVersion = in.readString();
- int revision = in.readInt();
- return new DistroRulesVersion(rulesVersion, revision);
- }
-
- public DistroRulesVersion[] newArray(int size) {
- return new DistroRulesVersion[size];
- }
- };
-
- public String getRulesVersion() {
- return mRulesVersion;
- }
-
- public int getRevision() {
- return mRevision;
- }
-
- /**
- * Returns true if this DistroRulesVersion is older than the one supplied. It returns false if
- * it is the same or newer. This method compares the {@code rulesVersion} and the
- * {@code revision}.
- */
- public boolean isOlderThan(DistroRulesVersion distroRulesVersion) {
- int rulesComparison = mRulesVersion.compareTo(distroRulesVersion.mRulesVersion);
- if (rulesComparison < 0) {
- return true;
- }
- if (rulesComparison > 0) {
- return false;
- }
- return mRevision < distroRulesVersion.mRevision;
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel out, int flags) {
- out.writeString(mRulesVersion);
- out.writeInt(mRevision);
- }
-
- @Override
- public boolean equals(@Nullable Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
-
- DistroRulesVersion that = (DistroRulesVersion) o;
-
- if (mRevision != that.mRevision) {
- return false;
- }
- return mRulesVersion.equals(that.mRulesVersion);
- }
-
- @Override
- public int hashCode() {
- int result = mRulesVersion.hashCode();
- result = 31 * result + mRevision;
- return result;
- }
-
- @Override
- public String toString() {
- return "DistroRulesVersion{"
- + "mRulesVersion='" + mRulesVersion + '\''
- + ", mRevision='" + mRevision + '\''
- + '}';
- }
-
- public String toDumpString() {
- return mRulesVersion + "," + mRevision;
- }
-}
diff --git a/core/java/android/app/timezone/IRulesManager.aidl b/core/java/android/app/timezone/IRulesManager.aidl
deleted file mode 100644
index 40f3fd22ac6b..000000000000
--- a/core/java/android/app/timezone/IRulesManager.aidl
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.app.timezone;
-
-import android.app.timezone.ICallback;
-import android.app.timezone.RulesState;
-import android.os.ParcelFileDescriptor;
-
- /**
- * Interface to the TimeZone Rules Manager Service.
- *
- * <p>This interface is only intended for system apps to call. They should use the
- * {@link android.app.timezone.RulesManager} class rather than going through this
- * Binder interface directly. See {@link android.app.timezone.RulesManager} for more complete
- * documentation.
- *
- * {@hide}
- */
-interface IRulesManager {
-
- /**
- * Returns information about the current time zone rules state such as the IANA version of
- * the system and any currently installed distro. This method is intended to allow clients to
- * determine if the current state can be improved; for example by passing the information to a
- * server that may provide a new distro for download.
- */
- RulesState getRulesState();
-
- /**
- * Requests installation of the supplied distro. The distro must have been checked for integrity
- * by the caller or have been received via a trusted mechanism.
- *
- * @param distroFileDescriptor the file descriptor for the distro
- * @param checkToken an optional token provided if the install was triggered in response to a
- * {@link RulesUpdaterContract#ACTION_TRIGGER_RULES_UPDATE_CHECK} intent
- * @param callback the {@link ICallback} to receive callbacks related to the
- * installation
- * @return zero if the installation will be attempted; nonzero on error
- */
- int requestInstall(in ParcelFileDescriptor distroFileDescriptor, in byte[] checkToken,
- ICallback callback);
-
- /**
- * Requests uninstallation of the currently installed distro (leaving the device with no
- * distro installed).
- *
- * @param checkToken an optional token provided if the uninstall was triggered in response to a
- * {@link RulesUpdaterContract#ACTION_TRIGGER_RULES_UPDATE_CHECK} intent
- * @param callback the {@link ICallback} to receive callbacks related to the
- * uninstall
- * @return zero if the uninstallation will be attempted; nonzero on error
- */
- int requestUninstall(in byte[] checkToken, ICallback callback);
-
- /**
- * Requests the system does not modify the currently installed time zone distro, if any. This
- * method records the fact that a time zone check operation triggered by the system is now
- * complete and there was nothing to do. The token passed should be the one presented when the
- * check was triggered.
- *
- * <p>Note: Passing {@code success == false} may result in more checks being triggered. Clients
- * should be careful not to pass false if the failure is unlikely to resolve by itself.
- *
- * @param checkToken an optional token provided if the install was triggered in response to a
- * {@link RulesUpdaterContract#ACTION_TRIGGER_RULES_UPDATE_CHECK} intent
- * @param success true if the check was successful, false if it was not successful but may
- * succeed if it is retried
- */
- void requestNothing(in byte[] token, boolean success);
-}
diff --git a/core/java/android/app/timezone/OWNERS b/core/java/android/app/timezone/OWNERS
deleted file mode 100644
index 04d78f23517f..000000000000
--- a/core/java/android/app/timezone/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-# Bug component: 24949
-# Internal APIs related to APK-based time zone rule updates.
-# Deprecated, deletion tracked by b/148144561
-include /services/core/java/com/android/server/timezone/OWNERS
diff --git a/core/java/android/app/timezone/RulesManager.java b/core/java/android/app/timezone/RulesManager.java
deleted file mode 100644
index fe83113b5d56..000000000000
--- a/core/java/android/app/timezone/RulesManager.java
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.app.timezone;
-
-import android.annotation.IntDef;
-import android.content.Context;
-import android.os.Handler;
-import android.os.ParcelFileDescriptor;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.util.Log;
-
-import java.io.IOException;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.Arrays;
-
-/**
- * The interface through which a time zone update application interacts with the Android system
- * to handle time zone rule updates.
- *
- * <p>This interface is intended for use with the default APK-based time zone rules update
- * application but it can also be used by OEMs if that mechanism is turned off using configuration.
- * All callers must possess the {@link android.Manifest.permission#UPDATE_TIME_ZONE_RULES} system
- * permission unless otherwise stated.
- *
- * <p>When using the default mechanism, when properly configured the Android system will send a
- * {@link RulesUpdaterContract#ACTION_TRIGGER_RULES_UPDATE_CHECK} intent with a
- * {@link RulesUpdaterContract#EXTRA_CHECK_TOKEN} extra to the time zone rules updater application
- * when it detects that it or the OEM's APK containing time zone rules data has been modified. The
- * updater application is then responsible for calling one of
- * {@link #requestInstall(ParcelFileDescriptor, byte[], Callback)},
- * {@link #requestUninstall(byte[], Callback)} or
- * {@link #requestNothing(byte[], boolean)}, indicating, respectively, whether a new time zone rules
- * distro should be installed, the current distro should be uninstalled, or there is nothing to do
- * (or that the correct operation could not be determined due to an error). In each case the updater
- * must pass the {@link RulesUpdaterContract#EXTRA_CHECK_TOKEN} value it received from the intent
- * back so the system in the {@code checkToken} parameter.
- *
- * <p>If OEMs want to handle their own time zone rules updates, perhaps via a server-side component
- * rather than an APK, then they should disable the default triggering mechanism in config and are
- * responsible for triggering their own update checks / installs / uninstalls. In this case the
- * "check token" parameter can be left null and there is never any need to call
- * {@link #requestNothing(byte[], boolean)}.
- *
- * <p>OEMs should not mix the default mechanism and their own as this could lead to conflicts and
- * unnecessary checks being triggered.
- *
- * <p>Applications obtain this using {@link android.app.Activity#getSystemService(String)} with
- * {@link Context#TIME_ZONE_RULES_MANAGER_SERVICE}.
- * @hide
- */
-public final class RulesManager {
- private static final String TAG = "timezone.RulesManager";
- private static final boolean DEBUG = false;
-
- /**
- * The action of the intent that the Android system will broadcast when a time zone rules update
- * operation has been successfully staged (i.e. to be applied next reboot) or unstaged.
- *
- * <p>See {@link #EXTRA_OPERATION_STAGED}
- *
- * <p>This is a protected intent that can only be sent by the system.
- */
- public static final String ACTION_RULES_UPDATE_OPERATION =
- "com.android.intent.action.timezone.RULES_UPDATE_OPERATION";
-
- /**
- * The key for a boolean extra for the {@link #ACTION_RULES_UPDATE_OPERATION} intent used to
- * indicate whether the operation was a "stage" or an "unstage".
- */
- public static final String EXTRA_OPERATION_STAGED = "staged";
-
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(prefix = { "SUCCESS", "ERROR_" }, value = {
- SUCCESS,
- ERROR_UNKNOWN_FAILURE,
- ERROR_OPERATION_IN_PROGRESS
- })
- public @interface ResultCode {}
-
- /**
- * Indicates that an operation succeeded.
- */
- public static final int SUCCESS = 0;
-
- /**
- * Indicates that an install/uninstall cannot be initiated because there is one already in
- * progress.
- */
- public static final int ERROR_OPERATION_IN_PROGRESS = 1;
-
- /**
- * Indicates an install / uninstall did not fully succeed for an unknown reason.
- */
- public static final int ERROR_UNKNOWN_FAILURE = 2;
-
- private final Context mContext;
- private final IRulesManager mIRulesManager;
-
- public RulesManager(Context context) {
- mContext = context;
- mIRulesManager = IRulesManager.Stub.asInterface(
- ServiceManager.getService(Context.TIME_ZONE_RULES_MANAGER_SERVICE));
- }
-
- /**
- * Returns information about the current time zone rules state such as the IANA version of
- * the system and any currently installed distro. This method allows clients to determine the
- * current device state, perhaps to see if it can be improved; for example by passing the
- * information to a server that may provide a new distro for download.
- *
- * <p>Callers must possess the {@link android.Manifest.permission#QUERY_TIME_ZONE_RULES} system
- * permission.
- */
- public RulesState getRulesState() {
- try {
- logDebug("mIRulesManager.getRulesState()");
- RulesState rulesState = mIRulesManager.getRulesState();
- logDebug("mIRulesManager.getRulesState() returned " + rulesState);
- return rulesState;
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Requests installation of the supplied distro. The distro must have been checked for integrity
- * by the caller or have been received via a trusted mechanism.
- *
- * @param distroFileDescriptor the file descriptor for the distro
- * @param checkToken an optional token provided if the install was triggered in response to a
- * {@link RulesUpdaterContract#ACTION_TRIGGER_RULES_UPDATE_CHECK} intent
- * @param callback the {@link Callback} to receive callbacks related to the installation
- * @return {@link #SUCCESS} if the installation will be attempted
- */
- @ResultCode
- public int requestInstall(
- ParcelFileDescriptor distroFileDescriptor, byte[] checkToken, Callback callback)
- throws IOException {
-
- ICallback iCallback = new CallbackWrapper(mContext, callback);
- try {
- logDebug("mIRulesManager.requestInstall()");
- return mIRulesManager.requestInstall(distroFileDescriptor, checkToken, iCallback);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Requests uninstallation of the currently installed distro (leaving the device with no
- * distro installed).
- *
- * @param checkToken an optional token provided if the uninstall was triggered in response to a
- * {@link RulesUpdaterContract#ACTION_TRIGGER_RULES_UPDATE_CHECK} intent
- * @param callback the {@link Callback} to receive callbacks related to the uninstall
- * @return {@link #SUCCESS} if the uninstallation will be attempted
- */
- @ResultCode
- public int requestUninstall(byte[] checkToken, Callback callback) {
- ICallback iCallback = new CallbackWrapper(mContext, callback);
- try {
- logDebug("mIRulesManager.requestUninstall()");
- return mIRulesManager.requestUninstall(checkToken, iCallback);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /*
- * We wrap incoming binder calls with a private class implementation that
- * redirects them into main-thread actions. This serializes the backup
- * progress callbacks nicely within the usual main-thread lifecycle pattern.
- */
- private class CallbackWrapper extends ICallback.Stub {
- final Handler mHandler;
- final Callback mCallback;
-
- CallbackWrapper(Context context, Callback callback) {
- mCallback = callback;
- mHandler = new Handler(context.getMainLooper());
- }
-
- // Binder calls into this object just enqueue on the main-thread handler
- @Override
- public void onFinished(int status) {
- logDebug("mCallback.onFinished(status), status=" + status);
- mHandler.post(() -> mCallback.onFinished(status));
- }
- }
-
- /**
- * Requests the system does not modify the currently installed time zone distro, if any. This
- * method records the fact that a time zone check operation triggered by the system is now
- * complete and there was nothing to do. The token passed should be the one presented when the
- * check was triggered.
- *
- * <p>Note: Passing {@code success == false} may result in more checks being triggered. Clients
- * should be careful not to pass false if the failure is unlikely to resolve by itself.
- *
- * @param checkToken an optional token provided if the install was triggered in response to a
- * {@link RulesUpdaterContract#ACTION_TRIGGER_RULES_UPDATE_CHECK} intent
- * @param succeeded true if the check was successful, false if it was not successful but may
- * succeed if it is retried
- */
- public void requestNothing(byte[] checkToken, boolean succeeded) {
- try {
- logDebug("mIRulesManager.requestNothing() with token=" + Arrays.toString(checkToken));
- mIRulesManager.requestNothing(checkToken, succeeded);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- static void logDebug(String msg) {
- if (DEBUG) {
- Log.v(TAG, msg);
- }
- }
-}
diff --git a/core/java/android/app/timezone/RulesState.java b/core/java/android/app/timezone/RulesState.java
deleted file mode 100644
index 516ad033a936..000000000000
--- a/core/java/android/app/timezone/RulesState.java
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.app.timezone;
-
-import static android.app.timezone.Utils.validateConditionalNull;
-import static android.app.timezone.Utils.validateNotNull;
-import static android.app.timezone.Utils.validateRulesVersion;
-
-import android.annotation.IntDef;
-import android.annotation.Nullable;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Description of the state of time zone rules on a device.
- *
- * <p>The following properties are included:
- * <dl>
- * <dt>baseRulesVersion</dt>
- * <dd>the IANA rules version that shipped with the OS. Always present. e.g. "2017a".</dd>
- * <dt>distroFormatVersionSupported</dt>
- * <dd>the distro format version supported by this device. Always present.</dd>
- * <dt>operationInProgress</dt>
- * <dd>{@code true} if there is an install / uninstall operation currently happening.</dd>
- * <dt>stagedOperationType</dt>
- * <dd>one of {@link #STAGED_OPERATION_UNKNOWN}, {@link #STAGED_OPERATION_NONE},
- * {@link #STAGED_OPERATION_UNINSTALL} and {@link #STAGED_OPERATION_INSTALL} indicating whether
- * there is a currently staged time zone distro operation. {@link #STAGED_OPERATION_UNKNOWN} is
- * used when {@link #isOperationInProgress()} is {@code true}. Staged operations currently
- * require a reboot to become active.</dd>
- * <dt>stagedDistroRulesVersion</dt>
- * <dd>[present if distroStagedState == STAGED_STATE_INSTALL], the rules version of the distro
- * currently staged for installation.</dd>
- * <dt>distroStatus</dt>
- * <dd>{@link #DISTRO_STATUS_INSTALLED} if there is a time zone distro installed and active,
- * {@link #DISTRO_STATUS_NONE} if there is no active installed distro.
- * {@link #DISTRO_STATUS_UNKNOWN} is used when {@link #isOperationInProgress()} is {@code true}.
- * </dd>
- * <dt>installedDistroRulesVersion</dt>
- * <dd>[present if distroStatus == {@link #DISTRO_STATUS_INSTALLED}], the rules version of the
- * installed and active distro.</dd>
- * </dl>
- *
- * @hide
- */
-public final class RulesState implements Parcelable {
-
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(prefix = { "STAGED_OPERATION_" }, value = {
- STAGED_OPERATION_UNKNOWN,
- STAGED_OPERATION_NONE,
- STAGED_OPERATION_UNINSTALL,
- STAGED_OPERATION_INSTALL
- })
- private @interface StagedOperationType {}
-
- /** Staged state could not be determined. */
- public static final int STAGED_OPERATION_UNKNOWN = 0;
- /** Nothing is staged. */
- public static final int STAGED_OPERATION_NONE = 1;
- /** An uninstall is staged. */
- public static final int STAGED_OPERATION_UNINSTALL = 2;
- /** An install is staged. */
- public static final int STAGED_OPERATION_INSTALL = 3;
-
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(prefix = { "DISTRO_STATUS_" }, value = {
- DISTRO_STATUS_UNKNOWN,
- DISTRO_STATUS_NONE,
- DISTRO_STATUS_INSTALLED
- })
- private @interface DistroStatus {}
-
- /** The current distro status could not be determined. */
- public static final int DISTRO_STATUS_UNKNOWN = 0;
- /** There is no active installed time zone distro. */
- public static final int DISTRO_STATUS_NONE = 1;
- /** The is an active, installed time zone distro. */
- public static final int DISTRO_STATUS_INSTALLED = 2;
-
- private static final byte BYTE_FALSE = 0;
- private static final byte BYTE_TRUE = 1;
-
- private final String mBaseRulesVersion;
- private final DistroFormatVersion mDistroFormatVersionSupported;
- private final boolean mOperationInProgress;
- @StagedOperationType private final int mStagedOperationType;
- @Nullable private final DistroRulesVersion mStagedDistroRulesVersion;
- @DistroStatus private final int mDistroStatus;
- @Nullable private final DistroRulesVersion mInstalledDistroRulesVersion;
-
- public RulesState(String baseRulesVersion, DistroFormatVersion distroFormatVersionSupported,
- boolean operationInProgress,
- @StagedOperationType int stagedOperationType,
- @Nullable DistroRulesVersion stagedDistroRulesVersion,
- @DistroStatus int distroStatus,
- @Nullable DistroRulesVersion installedDistroRulesVersion) {
- this.mBaseRulesVersion = validateRulesVersion("baseRulesVersion", baseRulesVersion);
- this.mDistroFormatVersionSupported =
- validateNotNull("distroFormatVersionSupported", distroFormatVersionSupported);
- this.mOperationInProgress = operationInProgress;
-
- if (operationInProgress && stagedOperationType != STAGED_OPERATION_UNKNOWN) {
- throw new IllegalArgumentException(
- "stagedOperationType != STAGED_OPERATION_UNKNOWN");
- }
- this.mStagedOperationType = validateStagedOperation(stagedOperationType);
- this.mStagedDistroRulesVersion = validateConditionalNull(
- mStagedOperationType == STAGED_OPERATION_INSTALL /* requireNotNull */,
- "stagedDistroRulesVersion", stagedDistroRulesVersion);
-
- this.mDistroStatus = validateDistroStatus(distroStatus);
- this.mInstalledDistroRulesVersion = validateConditionalNull(
- mDistroStatus == DISTRO_STATUS_INSTALLED/* requireNotNull */,
- "installedDistroRulesVersion", installedDistroRulesVersion);
- }
-
- public String getBaseRulesVersion() {
- return mBaseRulesVersion;
- }
-
- public boolean isOperationInProgress() {
- return mOperationInProgress;
- }
-
- public @StagedOperationType int getStagedOperationType() {
- return mStagedOperationType;
- }
-
- /**
- * Returns the staged rules version when {@link #getStagedOperationType()} is
- * {@link #STAGED_OPERATION_INSTALL}.
- */
- public @Nullable DistroRulesVersion getStagedDistroRulesVersion() {
- return mStagedDistroRulesVersion;
- }
-
- public @DistroStatus int getDistroStatus() {
- return mDistroStatus;
- }
-
- /**
- * Returns the installed rules version when {@link #getDistroStatus()} is
- * {@link #DISTRO_STATUS_INSTALLED}.
- */
- public @Nullable DistroRulesVersion getInstalledDistroRulesVersion() {
- return mInstalledDistroRulesVersion;
- }
-
- /**
- * Returns true if a distro in the specified format is supported on this device.
- */
- public boolean isDistroFormatVersionSupported(DistroFormatVersion distroFormatVersion) {
- return mDistroFormatVersionSupported.supports(distroFormatVersion);
- }
-
- /**
- * Returns true if the base data files contain IANA rules data that are newer than the
- * distro IANA rules version supplied, i.e. true when the version specified would be "worse"
- * than the one that is in the base data. Returns false if the base version is the
- * same or older, i.e. false when the version specified would be "better" than the one that is
- * in the base set.
- */
- public boolean isBaseVersionNewerThan(DistroRulesVersion distroRulesVersion) {
- return mBaseRulesVersion.compareTo(distroRulesVersion.getRulesVersion()) > 0;
- }
-
- public static final @android.annotation.NonNull Parcelable.Creator<RulesState> CREATOR =
- new Parcelable.Creator<RulesState>() {
- public RulesState createFromParcel(Parcel in) {
- return RulesState.createFromParcel(in);
- }
-
- public RulesState[] newArray(int size) {
- return new RulesState[size];
- }
- };
-
- private static RulesState createFromParcel(Parcel in) {
- String baseRulesVersion = in.readString();
- DistroFormatVersion distroFormatVersionSupported = in.readParcelable(null, android.app.timezone.DistroFormatVersion.class);
- boolean operationInProgress = in.readByte() == BYTE_TRUE;
- int distroStagedState = in.readByte();
- DistroRulesVersion stagedDistroRulesVersion = in.readParcelable(null, android.app.timezone.DistroRulesVersion.class);
- int installedDistroStatus = in.readByte();
- DistroRulesVersion installedDistroRulesVersion = in.readParcelable(null, android.app.timezone.DistroRulesVersion.class);
- return new RulesState(baseRulesVersion, distroFormatVersionSupported, operationInProgress,
- distroStagedState, stagedDistroRulesVersion,
- installedDistroStatus, installedDistroRulesVersion);
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel out, int flags) {
- out.writeString(mBaseRulesVersion);
- out.writeParcelable(mDistroFormatVersionSupported, 0);
- out.writeByte(mOperationInProgress ? BYTE_TRUE : BYTE_FALSE);
- out.writeByte((byte) mStagedOperationType);
- out.writeParcelable(mStagedDistroRulesVersion, 0);
- out.writeByte((byte) mDistroStatus);
- out.writeParcelable(mInstalledDistroRulesVersion, 0);
- }
-
- @Override
- public boolean equals(@Nullable Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
-
- RulesState that = (RulesState) o;
-
- if (mOperationInProgress != that.mOperationInProgress) {
- return false;
- }
- if (mStagedOperationType != that.mStagedOperationType) {
- return false;
- }
- if (mDistroStatus != that.mDistroStatus) {
- return false;
- }
- if (!mBaseRulesVersion.equals(that.mBaseRulesVersion)) {
- return false;
- }
- if (!mDistroFormatVersionSupported.equals(that.mDistroFormatVersionSupported)) {
- return false;
- }
- if (mStagedDistroRulesVersion != null ? !mStagedDistroRulesVersion
- .equals(that.mStagedDistroRulesVersion) : that.mStagedDistroRulesVersion != null) {
- return false;
- }
- return mInstalledDistroRulesVersion != null ? mInstalledDistroRulesVersion
- .equals(that.mInstalledDistroRulesVersion)
- : that.mInstalledDistroRulesVersion == null;
- }
-
- @Override
- public int hashCode() {
- int result = mBaseRulesVersion.hashCode();
- result = 31 * result + mDistroFormatVersionSupported.hashCode();
- result = 31 * result + (mOperationInProgress ? 1 : 0);
- result = 31 * result + mStagedOperationType;
- result = 31 * result + (mStagedDistroRulesVersion != null ? mStagedDistroRulesVersion
- .hashCode()
- : 0);
- result = 31 * result + mDistroStatus;
- result = 31 * result + (mInstalledDistroRulesVersion != null ? mInstalledDistroRulesVersion
- .hashCode() : 0);
- return result;
- }
-
- @Override
- public String toString() {
- return "RulesState{"
- + "mBaseRulesVersion='" + mBaseRulesVersion + '\''
- + ", mDistroFormatVersionSupported=" + mDistroFormatVersionSupported
- + ", mOperationInProgress=" + mOperationInProgress
- + ", mStagedOperationType=" + mStagedOperationType
- + ", mStagedDistroRulesVersion=" + mStagedDistroRulesVersion
- + ", mDistroStatus=" + mDistroStatus
- + ", mInstalledDistroRulesVersion=" + mInstalledDistroRulesVersion
- + '}';
- }
-
- private static int validateStagedOperation(int stagedOperationType) {
- if (stagedOperationType < STAGED_OPERATION_UNKNOWN
- || stagedOperationType > STAGED_OPERATION_INSTALL) {
- throw new IllegalArgumentException("Unknown operation type=" + stagedOperationType);
- }
- return stagedOperationType;
- }
-
- private static int validateDistroStatus(int distroStatus) {
- if (distroStatus < DISTRO_STATUS_UNKNOWN || distroStatus > DISTRO_STATUS_INSTALLED) {
- throw new IllegalArgumentException("Unknown distro status=" + distroStatus);
- }
- return distroStatus;
- }
-}
diff --git a/core/java/android/app/timezone/RulesUpdaterContract.java b/core/java/android/app/timezone/RulesUpdaterContract.java
deleted file mode 100644
index 74ed658875ab..000000000000
--- a/core/java/android/app/timezone/RulesUpdaterContract.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.app.timezone;
-
-import android.content.Context;
-import android.content.Intent;
-import android.os.ParcelFileDescriptor;
-import android.os.UserHandle;
-
-/**
- * Constants related to the contract between the Android system and the privileged time zone updater
- * application.
- *
- * @hide
- */
-public final class RulesUpdaterContract {
-
- /**
- * The system permission possessed by the Android system that allows it to trigger time zone
- * update checks. The updater should be configured to require this permission when registering
- * for {@link #ACTION_TRIGGER_RULES_UPDATE_CHECK} intents.
- */
- public static final String TRIGGER_TIME_ZONE_RULES_CHECK_PERMISSION =
- android.Manifest.permission.TRIGGER_TIME_ZONE_RULES_CHECK;
-
- /**
- * The system permission possessed by the time zone rules updater app that allows it to update
- * device time zone rules. The Android system requires this permission for calls made to
- * {@link RulesManager}.
- */
- public static final String UPDATE_TIME_ZONE_RULES_PERMISSION =
- android.Manifest.permission.UPDATE_TIME_ZONE_RULES;
-
- /**
- * The action of the intent that the Android system will broadcast. The intent will be targeted
- * at the configured updater application's package meaning the term "broadcast" only loosely
- * applies.
- */
- public static final String ACTION_TRIGGER_RULES_UPDATE_CHECK =
- "com.android.intent.action.timezone.TRIGGER_RULES_UPDATE_CHECK";
-
- /**
- * The extra containing the {@code byte[]} that should be passed to
- * {@link RulesManager#requestInstall(ParcelFileDescriptor, byte[], Callback)},
- * {@link RulesManager#requestUninstall(byte[], Callback)} and
- * {@link RulesManager#requestNothing(byte[], boolean)} methods when the
- * {@link #ACTION_TRIGGER_RULES_UPDATE_CHECK} intent has been processed.
- */
- public static final String EXTRA_CHECK_TOKEN =
- "com.android.intent.extra.timezone.CHECK_TOKEN";
-
- /**
- * Creates an intent that would trigger a time zone rules update check.
- */
- public static Intent createUpdaterIntent(String updaterPackageName) {
- Intent intent = new Intent(RulesUpdaterContract.ACTION_TRIGGER_RULES_UPDATE_CHECK);
- intent.setPackage(updaterPackageName);
- intent.setFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
- return intent;
- }
-
- /**
- * Broadcasts an {@link #ACTION_TRIGGER_RULES_UPDATE_CHECK} intent with the
- * {@link #EXTRA_CHECK_TOKEN} that triggers an update check, including the required receiver
- * permission.
- */
- public static void sendBroadcast(Context context, String updaterAppPackageName,
- byte[] checkTokenBytes) {
- Intent intent = createUpdaterIntent(updaterAppPackageName);
- intent.putExtra(EXTRA_CHECK_TOKEN, checkTokenBytes);
- context.sendBroadcastAsUser(
- intent, UserHandle.SYSTEM,
- RulesUpdaterContract.UPDATE_TIME_ZONE_RULES_PERMISSION);
- }
-}
diff --git a/core/java/android/app/timezone/Utils.java b/core/java/android/app/timezone/Utils.java
deleted file mode 100644
index 8dd3fb71aa0e..000000000000
--- a/core/java/android/app/timezone/Utils.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.app.timezone;
-
-/**
- * Shared code for android.app.timezone classes.
- */
-final class Utils {
- private Utils() {}
-
- static int validateVersion(String type, int version) {
- if (version < 0 || version > 999) {
- throw new IllegalArgumentException("Invalid " + type + " version=" + version);
- }
- return version;
- }
-
- static String validateRulesVersion(String type, String rulesVersion) {
- validateNotNull(type, rulesVersion);
-
- if (rulesVersion.isEmpty()) {
- throw new IllegalArgumentException(type + " must not be empty");
- }
- return rulesVersion;
- }
-
- /** Validates that {@code object} is not null. Always returns {@code object}. */
- static <T> T validateNotNull(String type, T object) {
- if (object == null) {
- throw new NullPointerException(type + " == null");
- }
- return object;
- }
-
- /**
- * If {@code requireNotNull} is {@code true} calls {@link #validateNotNull(String, Object)},
- * and {@link #validateNull(String, Object)} otherwise. Returns {@code object}.
- */
- static <T> T validateConditionalNull(boolean requireNotNull, String type, T object) {
- if (requireNotNull) {
- return validateNotNull(type, object);
- } else {
- return validateNull(type, object);
- }
- }
-
- /** Validates that {@code object} is null. Always returns null. */
- static <T> T validateNull(String type, T object) {
- if (object != null) {
- throw new IllegalArgumentException(type + " != null");
- }
- return null;
- }
-}
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index ae1f68958d0f..9dc38362cd27 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -3826,7 +3826,6 @@ public abstract class Context {
STORAGE_SERVICE,
STORAGE_STATS_SERVICE,
WALLPAPER_SERVICE,
- TIME_ZONE_RULES_MANAGER_SERVICE,
VIBRATOR_MANAGER_SERVICE,
VIBRATOR_SERVICE,
//@hide: STATUS_BAR_SERVICE,
@@ -5772,15 +5771,6 @@ public abstract class Context {
public static final String VR_SERVICE = "vrmanager";
/**
- * Use with {@link #getSystemService(String)} to retrieve an
- * {@link android.app.timezone.ITimeZoneRulesManager}.
- * @hide
- *
- * @see #getSystemService(String)
- */
- public static final String TIME_ZONE_RULES_MANAGER_SERVICE = "timezone";
-
- /**
* Use with {@link #getSystemService(String)} to retrieve a
* {@link android.content.pm.CrossProfileApps} for cross profile operations.
*
diff --git a/core/java/android/content/IntentFilter.java b/core/java/android/content/IntentFilter.java
index 8b6c4dd8497b..bff27d35cc23 100644
--- a/core/java/android/content/IntentFilter.java
+++ b/core/java/android/content/IntentFilter.java
@@ -23,9 +23,11 @@ import android.annotation.SystemApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.net.Uri;
import android.os.Build;
+import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.PatternMatcher;
+import android.os.PersistableBundle;
import android.text.TextUtils;
import android.util.AndroidException;
import android.util.ArraySet;
@@ -171,6 +173,13 @@ public class IntentFilter implements Parcelable {
private static final String NAME_STR = "name";
private static final String ACTION_STR = "action";
private static final String AUTO_VERIFY_STR = "autoVerify";
+ private static final String EXTRAS_STR = "extras";
+
+ private static final int[] EMPTY_INT_ARRAY = new int[0];
+ private static final long[] EMPTY_LONG_ARRAY = new long[0];
+ private static final double[] EMPTY_DOUBLE_ARRAY = new double[0];
+ private static final String[] EMPTY_STRING_ARRAY = new String[0];
+ private static final boolean[] EMPTY_BOOLEAN_ARRAY = new boolean[0];
/**
* The filter {@link #setPriority} value at which system high-priority
@@ -267,6 +276,11 @@ public class IntentFilter implements Parcelable {
* that were not in the Intent.
*/
public static final int NO_MATCH_CATEGORY = -4;
+ /**
+ * That filter didn't match due to different extras data.
+ * @hide
+ */
+ public static final int NO_MATCH_EXTRAS = -5;
/**
* HTTP scheme.
@@ -314,6 +328,7 @@ public class IntentFilter implements Parcelable {
private ArrayList<String> mMimeGroups = null;
private boolean mHasStaticPartialTypes = false;
private boolean mHasDynamicPartialTypes = false;
+ private PersistableBundle mExtras = null;
private static final int STATE_VERIFY_AUTO = 0x00000001;
private static final int STATE_NEED_VERIFY = 0x00000010;
@@ -507,6 +522,9 @@ public class IntentFilter implements Parcelable {
if (o.mMimeGroups != null) {
mMimeGroups = new ArrayList<String>(o.mMimeGroups);
}
+ if (o.mExtras != null) {
+ mExtras = new PersistableBundle(o.mExtras);
+ }
mHasStaticPartialTypes = o.mHasStaticPartialTypes;
mHasDynamicPartialTypes = o.mHasDynamicPartialTypes;
mVerifyState = o.mVerifyState;
@@ -1768,6 +1786,423 @@ public class IntentFilter implements Parcelable {
}
/**
+ * Match this filter against an Intent's extras. An intent must
+ * have all the extras specified by the filter with the same values,
+ * for the match to succeed.
+ *
+ * <p> An intent con have other extras in addition to those specified
+ * by the filter and it would not affect whether the match succeeds or not.
+ *
+ * @param extras The extras included in the intent, as returned by
+ * Intent.getExtras().
+ *
+ * @return If all extras match (success), null; else the name of the
+ * first extra that didn't match.
+ *
+ * @hide
+ */
+ private String matchExtras(@Nullable Bundle extras) {
+ if (mExtras == null) {
+ return null;
+ }
+ final Set<String> keys = mExtras.keySet();
+ for (String key : keys) {
+ if (extras == null) {
+ return key;
+ }
+ final Object value = mExtras.get(key);
+ final Object otherValue = extras.get(key);
+ if (otherValue == null || value.getClass() != otherValue.getClass()
+ || !Objects.deepEquals(value, otherValue)) {
+ return key;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Add a new extra name and value to match against. If an extra is included in the filter,
+ * then an Intent must have an extra with the same {@code name} and {@code value} for it to
+ * match.
+ *
+ * <p> Subsequent calls to this method with the same {@code name} will override any previously
+ * set {@code value}.
+ *
+ * @param name the name of the extra to match against.
+ * @param value the value of the extra to match against.
+ *
+ * @hide
+ */
+ public final void addExtra(@NonNull String name, int value) {
+ Objects.requireNonNull(name);
+ if (mExtras == null) {
+ mExtras = new PersistableBundle();
+ }
+ mExtras.putInt(name, value);
+ }
+
+ /**
+ * Return the value of the extra with {@code name} included in the filter.
+ *
+ * @return the value that was previously set using {@link #addExtra(String, int)} or
+ * {@code 0} if no value has been set.
+ * @hide
+ */
+ public final int getIntExtra(@NonNull String name) {
+ Objects.requireNonNull(name);
+ return mExtras == null ? 0 : mExtras.getInt(name);
+ }
+
+ /**
+ * Add a new extra name and value to match against. If an extra is included in the filter,
+ * then an Intent must have an extra with the same {@code name} and {@code value} for it to
+ * match.
+ *
+ * <p> Subsequent calls to this method with the same {@code name} will override any previously
+ * set {@code value}.
+ *
+ * @param name the name of the extra to match against.
+ * @param value the value of the extra to match against.
+ *
+ * @hide
+ */
+ public final void addExtra(@NonNull String name, @NonNull int[] value) {
+ Objects.requireNonNull(name);
+ Objects.requireNonNull(value);
+ if (mExtras == null) {
+ mExtras = new PersistableBundle();
+ }
+ mExtras.putIntArray(name, value);
+ }
+
+ /**
+ * Return the value of the extra with {@code name} included in the filter.
+ *
+ * @return the value that was previously set using {@link #addExtra(String, int[])} or
+ * an empty int array if no value has been set.
+ * @hide
+ */
+ @NonNull
+ public final int[] getIntArrayExtra(@NonNull String name) {
+ Objects.requireNonNull(name);
+ return mExtras == null ? EMPTY_INT_ARRAY : mExtras.getIntArray(name);
+ }
+
+ /**
+ * Add a new extra name and value to match against. If an extra is included in the filter,
+ * then an Intent must have an extra with the same {@code name} and {@code value} for it to
+ * match.
+ *
+ * <p> Subsequent calls to this method with the same {@code name} will override any previously
+ * set {@code value}.
+ *
+ * @param name the name of the extra to match against.
+ * @param value the value of the extra to match against.
+ *
+ * @hide
+ */
+ public final void addExtra(@NonNull String name, long value) {
+ Objects.requireNonNull(name);
+ if (mExtras == null) {
+ mExtras = new PersistableBundle();
+ }
+ mExtras.putLong(name, value);
+ }
+
+ /**
+ * Return the value of the extra with {@code name} included in the filter.
+ *
+ * @return the value that was previously set using {@link #addExtra(String, long)} or
+ * {@code 0L} if no value has been set.
+ * @hide
+ */
+ public final long getLongExtra(@NonNull String name) {
+ Objects.requireNonNull(name);
+ return mExtras == null ? 0L : mExtras.getLong(name);
+ }
+
+ /**
+ * Add a new extra name and value to match against. If an extra is included in the filter,
+ * then an Intent must have an extra with the same {@code name} and {@code value} for it to
+ * match.
+ *
+ * <p> Subsequent calls to this method with the same {@code name} will override any previously
+ * set {@code value}.
+ *
+ * @param name the name of the extra to match against.
+ * @param value the value of the extra to match against.
+ *
+ * @hide
+ */
+ public final void addExtra(@NonNull String name, @NonNull long[] value) {
+ Objects.requireNonNull(name);
+ Objects.requireNonNull(value);
+ if (mExtras == null) {
+ mExtras = new PersistableBundle();
+ }
+ mExtras.putLongArray(name, value);
+ }
+
+ /**
+ * Return the value of the extra with {@code name} included in the filter.
+ *
+ * @return the value that was previously set using {@link #addExtra(String, long[])} or
+ * an empty long array if no value has been set.
+ * @hide
+ */
+ @NonNull
+ public final long[] getLongArrayExtra(@NonNull String name) {
+ Objects.requireNonNull(name);
+ return mExtras == null ? EMPTY_LONG_ARRAY : mExtras.getLongArray(name);
+ }
+
+ /**
+ * Add a new extra name and value to match against. If an extra is included in the filter,
+ * then an Intent must have an extra with the same {@code name} and {@code value} for it to
+ * match.
+ *
+ * <p> Subsequent calls to this method with the same {@code name} will override any previously
+ * set {@code value}.
+ *
+ * @param name the name of the extra to match against.
+ * @param value the value of the extra to match against.
+ *
+ * @hide
+ */
+ public final void addExtra(@NonNull String name, double value) {
+ Objects.requireNonNull(name);
+ if (mExtras == null) {
+ mExtras = new PersistableBundle();
+ }
+ mExtras.putDouble(name, value);
+ }
+
+ /**
+ * Return the value of the extra with {@code name} included in the filter.
+ *
+ * @return the value that was previously set using {@link #addExtra(String, double)} or
+ * {@code 0.0} if no value has been set.
+ * @hide
+ */
+ @NonNull
+ public final double getDoubleExtra(@NonNull String name) {
+ Objects.requireNonNull(name);
+ return mExtras == null ? 0.0 : mExtras.getDouble(name);
+ }
+
+ /**
+ * Add a new extra name and value to match against. If an extra is included in the filter,
+ * then an Intent must have an extra with the same {@code name} and {@code value} for it to
+ * match.
+ *
+ * <p> Subsequent calls to this method with the same {@code name} will override any previously
+ * set {@code value}.
+ *
+ * @param name the name of the extra to match against.
+ * @param value the value of the extra to match against.
+ *
+ * @hide
+ */
+ public final void addExtra(@NonNull String name, @NonNull double[] value) {
+ Objects.requireNonNull(name);
+ Objects.requireNonNull(value);
+ if (mExtras == null) {
+ mExtras = new PersistableBundle();
+ }
+ mExtras.putDoubleArray(name, value);
+ }
+
+ /**
+ * Return the value of the extra with {@code name} included in the filter.
+ *
+ * @return the value that was previously set using {@link #addExtra(String, double[])} or
+ * an empty double array if no value has been set.
+ * @hide
+ */
+ @NonNull
+ public final double[] getDoubleArrayExtra(@NonNull String name) {
+ Objects.requireNonNull(name);
+ return mExtras == null ? EMPTY_DOUBLE_ARRAY : mExtras.getDoubleArray(name);
+ }
+
+ /**
+ * Add a new extra name and value to match against. If an extra is included in the filter,
+ * then an Intent must have an extra with the same {@code name} and {@code value} for it to
+ * match.
+ *
+ * <p> Subsequent calls to this method with the same {@code name} will override any previously
+ * set {@code value}.
+ *
+ * @param name the name of the extra to match against.
+ * @param value the value of the extra to match against.
+ *
+ * @hide
+ */
+ public final void addExtra(@NonNull String name, @NonNull String value) {
+ Objects.requireNonNull(name);
+ Objects.requireNonNull(value);
+ if (mExtras == null) {
+ mExtras = new PersistableBundle();
+ }
+ mExtras.putString(name, value);
+ }
+
+ /**
+ * Return the value of the extra with {@code name} included in the filter.
+ *
+ * @return the value that was previously set using {@link #addExtra(String, String)} or a
+ * {@code null} if no value has been set.
+ * @hide
+ */
+ @Nullable
+ public final String getStringExtra(@NonNull String name) {
+ Objects.requireNonNull(name);
+ return mExtras == null ? null : mExtras.getString(name);
+ }
+
+ /**
+ * Add a new extra name and value to match against. If an extra is included in the filter,
+ * then an Intent must have an extra with the same {@code name} and {@code value} for it to
+ * match.
+ *
+ * <p> Subsequent calls to this method with the same {@code name} will override any previously
+ * set {@code value}.
+ *
+ * @param name the name of the extra to match against.
+ * @param value the value of the extra to match against.
+ *
+ * @hide
+ */
+ public final void addExtra(@NonNull String name, @NonNull String[] value) {
+ Objects.requireNonNull(name);
+ Objects.requireNonNull(value);
+ if (mExtras == null) {
+ mExtras = new PersistableBundle();
+ }
+ mExtras.putStringArray(name, value);
+ }
+
+ /**
+ * Return the value of the extra with {@code name} included in the filter.
+ *
+ * @return the value that was previously set using {@link #addExtra(String, String[])} or
+ * an empty string array if no value has been set.
+ * @hide
+ */
+ @NonNull
+ public final String[] getStringArrayExtra(@NonNull String name) {
+ Objects.requireNonNull(name);
+ return mExtras == null ? EMPTY_STRING_ARRAY : mExtras.getStringArray(name);
+ }
+
+ /**
+ * Add a new extra name and value to match against. If an extra is included in the filter,
+ * then an Intent must have an extra with the same {@code name} and {@code value} for it to
+ * match.
+ *
+ * <p> Subsequent calls to this method with the same {@code name} will override any previously
+ * set {@code value}.
+ *
+ * @param name the name of the extra to match against.
+ * @param value the value of the extra to match against.
+ *
+ * @hide
+ */
+ public final void addExtra(@NonNull String name, boolean value) {
+ Objects.requireNonNull(name);
+ if (mExtras == null) {
+ mExtras = new PersistableBundle();
+ }
+ mExtras.putBoolean(name, value);
+ }
+
+ /**
+ * Return the value of the extra with {@code name} included in the filter.
+ *
+ * @return the value that was previously set using {@link #addExtra(String, boolean)} or
+ * {@code false} if no value has been set.
+ * @hide
+ */
+ public final boolean getBooleanExtra(@NonNull String name) {
+ Objects.requireNonNull(name);
+ return mExtras == null ? false : mExtras.getBoolean(name);
+ }
+
+ /**
+ * Add a new extra name and value to match against. If an extra is included in the filter,
+ * then an Intent must have an extra with the same {@code name} and {@code value} for it to
+ * match.
+ *
+ * <p> Subsequent calls to this method with the same {@code name} will override any previously
+ * set {@code value}.
+ *
+ * @param name the name of the extra to match against.
+ * @param value the value of the extra to match against.
+ *
+ * @hide
+ */
+ public final void addExtra(@NonNull String name, @NonNull boolean[] value) {
+ Objects.requireNonNull(name);
+ Objects.requireNonNull(value);
+ if (mExtras == null) {
+ mExtras = new PersistableBundle();
+ }
+ mExtras.putBooleanArray(name, value);
+ }
+
+ /**
+ * Return the value of the extra with {@code name} included in the filter.
+ *
+ * @return the value that was previously set using {@link #addExtra(String, boolean[])} or
+ * an empty boolean array if no value has been set.
+ * @hide
+ */
+ @NonNull
+ public final boolean[] getBooleanArrayExtra(@NonNull String name) {
+ Objects.requireNonNull(name);
+ return mExtras == null ? EMPTY_BOOLEAN_ARRAY : mExtras.getBooleanArray(name);
+ }
+
+ /**
+ * Returns whether or not an extra with {@code name} is included in the filter.
+ *
+ * @return {@code true} if an extra with {@code name} is included in the filter.
+ * Otherwise {@code false}.
+ * @hide
+ */
+ public final boolean hasExtra(@NonNull String name) {
+ Objects.requireNonNull(name);
+ return mExtras == null ? false : mExtras.containsKey(name);
+ }
+
+ /**
+ * Set the intent extras to match against. For this filter to match an
+ * intent, it must contain all the {@code extras} set.
+ *
+ * <p> Subsequent calls to this method will override any previously set extras.
+ *
+ * @param extras The intent extras to match against.
+ * @hide
+ */
+ @SystemApi
+ public final void setExtras(@NonNull PersistableBundle extras) {
+ mExtras = extras;
+ }
+
+ /**
+ * Return the intent extras included in this filter.
+ *
+ * @return the extras that were previously set using {@link #setExtras(PersistableBundle)} or
+ * an empty {@link PersistableBundle} object if no extras were set.
+ * @hide
+ */
+ @SystemApi
+ @NonNull
+ public final PersistableBundle getExtras() {
+ return mExtras == null ? new PersistableBundle() : mExtras;
+ }
+
+ /**
* Return a {@link Predicate} which tests whether this filter matches the
* given <var>intent</var>.
* <p>
@@ -1818,7 +2253,9 @@ public class IntentFilter implements Parcelable {
boolean resolve, String logTag) {
String type = resolve ? intent.resolveType(resolver) : intent.getType();
return match(intent.getAction(), type, intent.getScheme(),
- intent.getData(), intent.getCategories(), logTag);
+ intent.getData(), intent.getCategories(), logTag,
+ false /* supportWildcards */, null /* ignoreActions */,
+ intent.getExtras());
}
/**
@@ -1868,6 +2305,19 @@ public class IntentFilter implements Parcelable {
public final int match(String action, String type, String scheme,
Uri data, Set<String> categories, String logTag, boolean supportWildcards,
@Nullable Collection<String> ignoreActions) {
+ return match(action, type, scheme, data, categories, logTag, supportWildcards,
+ ignoreActions, null /* extras */);
+ }
+
+ /**
+ * Variant of {@link #match(String, String, String, Uri, Set, String, boolean, Collection)}
+ * that supports matching the extra values in the intent.
+ *
+ * @hide
+ */
+ public final int match(String action, String type, String scheme,
+ Uri data, Set<String> categories, String logTag, boolean supportWildcards,
+ @Nullable Collection<String> ignoreActions, @Nullable Bundle extras) {
if (action != null && !matchAction(action, supportWildcards, ignoreActions)) {
if (false) Log.v(
logTag, "No matching action " + action + " for " + this);
@@ -1897,6 +2347,14 @@ public class IntentFilter implements Parcelable {
return NO_MATCH_CATEGORY;
}
+ String extraMismatch = matchExtras(extras);
+ if (extraMismatch != null) {
+ if (false) {
+ Log.v(logTag, "Mismatch for extra key " + extraMismatch + " for " + this);
+ }
+ return NO_MATCH_EXTRAS;
+ }
+
// It would be nice to treat container activities as more
// important than ones that can be embedded, but this is not the way...
if (false) {
@@ -1998,6 +2456,15 @@ public class IntentFilter implements Parcelable {
}
serializer.endTag(null, PATH_STR);
}
+ if (mExtras != null) {
+ serializer.startTag(null, EXTRAS_STR);
+ try {
+ mExtras.saveToXml(serializer);
+ } catch (XmlPullParserException e) {
+ throw new IllegalStateException("Failed to write extras: " + mExtras.toString(), e);
+ }
+ serializer.endTag(null, EXTRAS_STR);
+ }
}
/**
@@ -2124,6 +2591,8 @@ public class IntentFilter implements Parcelable {
} else if ((path=parser.getAttributeValue(null, SUFFIX_STR)) != null) {
addDataPath(path, PatternMatcher.PATTERN_SUFFIX);
}
+ } else if (tagName.equals(EXTRAS_STR)) {
+ mExtras = PersistableBundle.restoreFromXml(parser);
} else {
Log.w("IntentFilter", "Unknown tag parsing IntentFilter: " + tagName);
}
@@ -2187,6 +2656,9 @@ public class IntentFilter implements Parcelable {
proto.write(IntentFilterProto.HAS_PARTIAL_TYPES, hasPartialTypes());
}
proto.write(IntentFilterProto.GET_AUTO_VERIFY, getAutoVerify());
+ if (mExtras != null) {
+ mExtras.dumpDebug(proto, IntentFilterProto.EXTRAS);
+ }
proto.end(token);
}
@@ -2297,6 +2769,11 @@ public class IntentFilter implements Parcelable {
sb.append(prefix); sb.append("AutoVerify="); sb.append(getAutoVerify());
du.println(sb.toString());
}
+ if (mExtras != null) {
+ sb.setLength(0);
+ sb.append(prefix); sb.append("mExtras="); sb.append(mExtras.toString());
+ du.println(sb.toString());
+ }
}
public static final @android.annotation.NonNull Parcelable.Creator<IntentFilter> CREATOR
@@ -2379,6 +2856,12 @@ public class IntentFilter implements Parcelable {
dest.writeInt(getAutoVerify() ? 1 : 0);
dest.writeInt(mInstantAppVisibility);
dest.writeInt(mOrder);
+ if (mExtras != null) {
+ dest.writeInt(1);
+ mExtras.writeToParcel(dest, flags);
+ } else {
+ dest.writeInt(0);
+ }
}
/**
@@ -2459,6 +2942,9 @@ public class IntentFilter implements Parcelable {
setAutoVerify(source.readInt() > 0);
setVisibilityToInstantApp(source.readInt());
mOrder = source.readInt();
+ if (source.readInt() != 0) {
+ mExtras = PersistableBundle.CREATOR.createFromParcel(source);
+ }
}
private boolean hasPartialTypes() {
diff --git a/core/java/android/credentials/ui/Entry.java b/core/java/android/credentials/ui/Entry.java
index 5c07e6e94131..5f947bb1996f 100644
--- a/core/java/android/credentials/ui/Entry.java
+++ b/core/java/android/credentials/ui/Entry.java
@@ -97,7 +97,7 @@ public class Entry implements Parcelable {
protected Entry(@NonNull Parcel in) {
String key = in.readString8();
String subkey = in.readString8();
- Slice slice = Slice.CREATOR.createFromParcel(in);
+ Slice slice = in.readTypedObject(Slice.CREATOR);
mKey = key;
AnnotationValidations.validate(NonNull.class, null, mKey);
@@ -167,9 +167,9 @@ public class Entry implements Parcelable {
public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeString8(mKey);
dest.writeString8(mSubkey);
- mSlice.writeToParcel(dest, flags);
- mPendingIntent.writeToParcel(dest, flags);
- mFrameworkExtrasIntent.writeToParcel(dest, flags);
+ dest.writeTypedObject(mSlice, flags);
+ dest.writeTypedObject(mPendingIntent, flags);
+ dest.writeTypedObject(mFrameworkExtrasIntent, flags);
}
@Override
diff --git a/core/java/android/credentials/ui/ProviderPendingIntentResponse.java b/core/java/android/credentials/ui/ProviderPendingIntentResponse.java
index 420956f69b7f..47936c48f927 100644
--- a/core/java/android/credentials/ui/ProviderPendingIntentResponse.java
+++ b/core/java/android/credentials/ui/ProviderPendingIntentResponse.java
@@ -63,7 +63,7 @@ public final class ProviderPendingIntentResponse implements Parcelable {
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
- dest.writeSerializable(mResultCode);
+ dest.writeInt(mResultCode);
dest.writeTypedObject(mResultData, flags);
}
diff --git a/core/java/android/app/timezone/RulesState.aidl b/core/java/android/hardware/OverlayProperties.aidl
index 665220dddafd..4f6631240171 100644
--- a/core/java/android/app/timezone/RulesState.aidl
+++ b/core/java/android/hardware/OverlayProperties.aidl
@@ -1,5 +1,5 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
+/**
+ * Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,6 +14,6 @@
* limitations under the License.
*/
-package android.app.timezone;
+package android.hardware;
-parcelable RulesState; \ No newline at end of file
+parcelable OverlayProperties; \ No newline at end of file
diff --git a/core/java/android/hardware/OverlayProperties.java b/core/java/android/hardware/OverlayProperties.java
index 2a0956b47a7b..1ce1361cd4e7 100644
--- a/core/java/android/hardware/OverlayProperties.java
+++ b/core/java/android/hardware/OverlayProperties.java
@@ -16,32 +16,96 @@
package android.hardware;
-import java.util.List;
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import libcore.util.NativeAllocationRegistry;
/**
- * // TODO(b/242588489): Continue work, the class needs a jni-specific constructor and DisplayInfo
- * // side constructs the object.
+ * The class provides overlay properties of the device. OverlayProperties
+ * exposes some capabilities from HWC e.g. if fp16 can be supported for HWUI.
+ *
+ * In the future, more capabilities can be added, e.g., whether or not
+ * per-layer colorspaces are supported.
*
* @hide
*/
-public final class OverlayProperties {
- private final SupportedBufferCombinations[] mCombinations = null;
- private final boolean mSupportFp16ForHdr = false;
-
- static class SupportedBufferCombinations {
- @HardwareBuffer.Format List<Integer> mHardwareBufferFormats;
- @DataSpace.NamedDataSpace List<Integer> mDataSpaces;
- SupportedBufferCombinations(@HardwareBuffer.Format List<Integer> hardwareBufferFormats,
- @DataSpace.NamedDataSpace List<Integer> dataSpaces) {
- mHardwareBufferFormats = hardwareBufferFormats;
- mDataSpaces = dataSpaces;
+public final class OverlayProperties implements Parcelable {
+
+ private static final NativeAllocationRegistry sRegistry =
+ NativeAllocationRegistry.createMalloced(OverlayProperties.class.getClassLoader(),
+ nGetDestructor());
+
+ private long mNativeObject;
+ // Invoked on destruction
+ private Runnable mCloser;
+
+ public OverlayProperties(long nativeObject) {
+ if (nativeObject != 0) {
+ mCloser = sRegistry.registerNativeAllocation(this, nativeObject);
}
+ mNativeObject = nativeObject;
}
- /***
- * @return if the device can support fp16.
+ /**
+ * @return True if the device can support fp16, false otherwise.
*/
public boolean supportFp16ForHdr() {
- return mSupportFp16ForHdr;
+ if (mNativeObject == 0) {
+ return false;
+ }
+ return nSupportFp16ForHdr(mNativeObject);
}
+
+ /**
+ * Release the local reference.
+ */
+ public void release() {
+ if (mNativeObject != 0) {
+ mCloser.run();
+ mNativeObject = 0;
+ }
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ /**
+ * Flatten this object in to a Parcel.
+ *
+ * @param dest The Parcel in which the object should be written.
+ * @param flags Additional flags about how the object should be written.
+ * May be 0 or {@link #PARCELABLE_WRITE_RETURN_VALUE}.
+ */
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ if (mNativeObject == 0) {
+ dest.writeInt(0);
+ return;
+ }
+ dest.writeInt(1);
+ nWriteOverlayPropertiesToParcel(mNativeObject, dest);
+ }
+
+ public static final @NonNull Parcelable.Creator<OverlayProperties> CREATOR =
+ new Parcelable.Creator<OverlayProperties>() {
+ public OverlayProperties createFromParcel(Parcel in) {
+ if (in.readInt() != 0) {
+ return new OverlayProperties(nReadOverlayPropertiesFromParcel(in));
+ }
+ return null;
+ }
+
+ public OverlayProperties[] newArray(int size) {
+ return new OverlayProperties[size];
+ }
+ };
+
+ private static native long nGetDestructor();
+ private static native boolean nSupportFp16ForHdr(long nativeObject);
+ private static native void nWriteOverlayPropertiesToParcel(long nativeObject, Parcel dest);
+ private static native long nReadOverlayPropertiesFromParcel(Parcel in);
}
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index f561278bb25a..1ee2423e62fd 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -3083,17 +3083,67 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
* check if it limits the maximum size for image data.</p>
* <p>For applications targeting SDK version older than 31, the following table
* describes the minimum required output stream configurations based on the
- * hardware level ({@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL android.info.supportedHardwareLevel}):
- * Format | Size | Hardware Level | Notes
- * :-------------------------------------------------:|:--------------------------------------------:|:--------------:|:--------------:
- * {@link android.graphics.ImageFormat#JPEG } | {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize} (*1) | Any |
- * {@link android.graphics.ImageFormat#JPEG } | 1920x1080 (1080p) | Any | if 1080p &lt;= activeArraySize
- * {@link android.graphics.ImageFormat#JPEG } | 1280x720 (720p) | Any | if 720p &lt;= activeArraySize
- * {@link android.graphics.ImageFormat#JPEG } | 640x480 (480p) | Any | if 480p &lt;= activeArraySize
- * {@link android.graphics.ImageFormat#JPEG } | 320x240 (240p) | Any | if 240p &lt;= activeArraySize
- * {@link android.graphics.ImageFormat#YUV_420_888 } | all output sizes available for JPEG | FULL |
- * {@link android.graphics.ImageFormat#YUV_420_888 } | all output sizes available for JPEG, up to the maximum video size | LIMITED |
- * {@link android.graphics.ImageFormat#PRIVATE } | same as YUV_420_888 | Any |</p>
+ * hardware level ({@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL android.info.supportedHardwareLevel}):</p>
+ * <table>
+ * <thead>
+ * <tr>
+ * <th style="text-align: center;">Format</th>
+ * <th style="text-align: center;">Size</th>
+ * <th style="text-align: center;">Hardware Level</th>
+ * <th style="text-align: center;">Notes</th>
+ * </tr>
+ * </thead>
+ * <tbody>
+ * <tr>
+ * <td style="text-align: center;">{@link android.graphics.ImageFormat#JPEG }</td>
+ * <td style="text-align: center;">{@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize} (*1)</td>
+ * <td style="text-align: center;">Any</td>
+ * <td style="text-align: center;"></td>
+ * </tr>
+ * <tr>
+ * <td style="text-align: center;">{@link android.graphics.ImageFormat#JPEG }</td>
+ * <td style="text-align: center;">1920x1080 (1080p)</td>
+ * <td style="text-align: center;">Any</td>
+ * <td style="text-align: center;">if 1080p &lt;= activeArraySize</td>
+ * </tr>
+ * <tr>
+ * <td style="text-align: center;">{@link android.graphics.ImageFormat#JPEG }</td>
+ * <td style="text-align: center;">1280x720 (720p)</td>
+ * <td style="text-align: center;">Any</td>
+ * <td style="text-align: center;">if 720p &lt;= activeArraySize</td>
+ * </tr>
+ * <tr>
+ * <td style="text-align: center;">{@link android.graphics.ImageFormat#JPEG }</td>
+ * <td style="text-align: center;">640x480 (480p)</td>
+ * <td style="text-align: center;">Any</td>
+ * <td style="text-align: center;">if 480p &lt;= activeArraySize</td>
+ * </tr>
+ * <tr>
+ * <td style="text-align: center;">{@link android.graphics.ImageFormat#JPEG }</td>
+ * <td style="text-align: center;">320x240 (240p)</td>
+ * <td style="text-align: center;">Any</td>
+ * <td style="text-align: center;">if 240p &lt;= activeArraySize</td>
+ * </tr>
+ * <tr>
+ * <td style="text-align: center;">{@link android.graphics.ImageFormat#YUV_420_888 }</td>
+ * <td style="text-align: center;">all output sizes available for JPEG</td>
+ * <td style="text-align: center;">FULL</td>
+ * <td style="text-align: center;"></td>
+ * </tr>
+ * <tr>
+ * <td style="text-align: center;">{@link android.graphics.ImageFormat#YUV_420_888 }</td>
+ * <td style="text-align: center;">all output sizes available for JPEG, up to the maximum video size</td>
+ * <td style="text-align: center;">LIMITED</td>
+ * <td style="text-align: center;"></td>
+ * </tr>
+ * <tr>
+ * <td style="text-align: center;">{@link android.graphics.ImageFormat#PRIVATE }</td>
+ * <td style="text-align: center;">same as YUV_420_888</td>
+ * <td style="text-align: center;">Any</td>
+ * <td style="text-align: center;"></td>
+ * </tr>
+ * </tbody>
+ * </table>
* <p>For applications targeting SDK version 31 or newer, if the mobile device declares to be
* media performance class 12 or higher by setting
* {@link android.os.Build.VERSION#MEDIA_PERFORMANCE_CLASS } to be 31 or larger,
diff --git a/core/java/android/hardware/display/DisplayManagerGlobal.java b/core/java/android/hardware/display/DisplayManagerGlobal.java
index 79223f5d2414..cc397d57d838 100644
--- a/core/java/android/hardware/display/DisplayManagerGlobal.java
+++ b/core/java/android/hardware/display/DisplayManagerGlobal.java
@@ -113,7 +113,7 @@ public final class DisplayManagerGlobal {
private final SparseArray<DisplayInfo> mDisplayInfoCache = new SparseArray<>();
private final ColorSpace mWideColorSpace;
- private final OverlayProperties mOverlayProperties = new OverlayProperties();
+ private final OverlayProperties mOverlayProperties;
private int[] mDisplayIdCache;
private int mWifiDisplayScanNestCount;
@@ -125,6 +125,7 @@ public final class DisplayManagerGlobal {
mWideColorSpace =
ColorSpace.get(
ColorSpace.Named.values()[mDm.getPreferredWideGamutColorSpaceId()]);
+ mOverlayProperties = mDm.getOverlaySupport();
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
@@ -728,7 +729,11 @@ public final class DisplayManagerGlobal {
return mWideColorSpace;
}
- /** @hide */
+ /**
+ * Gets the overlay properties for all displays.
+ *
+ * @hide
+ */
public OverlayProperties getOverlaySupport() {
return mOverlayProperties;
}
diff --git a/core/java/android/hardware/display/IDisplayManager.aidl b/core/java/android/hardware/display/IDisplayManager.aidl
index b166e215075a..6b5594b1a3dd 100644
--- a/core/java/android/hardware/display/IDisplayManager.aidl
+++ b/core/java/android/hardware/display/IDisplayManager.aidl
@@ -18,6 +18,7 @@ package android.hardware.display;
import android.content.pm.ParceledListSlice;
import android.graphics.Point;
+import android.hardware.OverlayProperties;
import android.hardware.display.BrightnessConfiguration;
import android.hardware.display.BrightnessInfo;
import android.hardware.display.Curve;
@@ -192,4 +193,7 @@ interface IDisplayManager {
// to set the layerStack after the display was created, which is not something we support in
// DMS. This should be deleted in V release.
void setDisplayIdToMirror(in IBinder token, int displayId);
+
+ // Query overlay properties of the device
+ OverlayProperties getOverlaySupport();
}
diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java
index 702b39b8cdaa..a157a8f6c6d7 100644
--- a/core/java/android/hardware/input/InputManager.java
+++ b/core/java/android/hardware/input/InputManager.java
@@ -30,6 +30,7 @@ import android.app.ActivityThread;
import android.compat.annotation.ChangeId;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
+import android.content.pm.PackageManager;
import android.hardware.BatteryState;
import android.hardware.SensorManager;
import android.hardware.lights.Light;
@@ -1850,6 +1851,31 @@ public final class InputManager {
}
/**
+ * Whether stylus has ever been used on device (false by default).
+ * @hide
+ */
+ public boolean isStylusEverUsed(@NonNull Context context) {
+ return Settings.Global.getInt(context.getContentResolver(),
+ Settings.Global.STYLUS_EVER_USED, 0) == 1;
+ }
+
+ /**
+ * Set whether stylus has ever been used on device.
+ * Should only ever be set to true once after stylus first usage.
+ * @hide
+ */
+ @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
+ public void setStylusEverUsed(@NonNull Context context, boolean stylusEverUsed) {
+ if (context.checkCallingPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("You need WRITE_SECURE_SETTINGS permission "
+ + "to set stylus ever used.");
+ }
+ Settings.Global.putInt(context.getContentResolver(),
+ Settings.Global.STYLUS_EVER_USED, stylusEverUsed ? 1 : 0);
+ }
+
+ /**
* A callback used to be notified about battery state changes for an input device. The
* {@link #onBatteryStateChanged(int, long, BatteryState)} method will be called once after the
* listener is successfully registered to provide the initial battery state of the device.
diff --git a/core/java/android/hardware/input/VirtualTouchEvent.java b/core/java/android/hardware/input/VirtualTouchEvent.java
index ad51eb894e22..9b1e6e84a022 100644
--- a/core/java/android/hardware/input/VirtualTouchEvent.java
+++ b/core/java/android/hardware/input/VirtualTouchEvent.java
@@ -33,6 +33,11 @@ import java.lang.annotation.RetentionPolicy;
* The pointer id, tool type, action, and location are required; pressure and main axis size are
* optional.
*
+ * Note: A VirtualTouchEvent with ACTION_CANCEL can only be created with TOOL_TYPE_PALM (and vice
+ * versa). Events are injected into the uinput kernel module, which has no concept of cancelling
+ * an action. The only way to state the intention that a pointer should not be handled as a pointer
+ * is to change its tool type to TOOL_TYPE_PALM.
+ *
* @hide
*/
@SystemApi
@@ -186,6 +191,10 @@ public final class VirtualTouchEvent implements Parcelable {
/**
* Creates a {@link VirtualTouchEvent} object with the current builder configuration.
+ *
+ * @throws IllegalArgumentException if one of the required arguments is missing or if
+ * ACTION_CANCEL is not set in combination with TOOL_TYPE_PALM. See
+ * {@link VirtualTouchEvent} for a detailed explanation.
*/
public @NonNull VirtualTouchEvent build() {
if (mToolType == TOOL_TYPE_UNKNOWN || mPointerId == MotionEvent.INVALID_POINTER_ID
diff --git a/core/java/android/hardware/radio/RadioManager.java b/core/java/android/hardware/radio/RadioManager.java
index 59465dbff939..9a217f9b5119 100644
--- a/core/java/android/hardware/radio/RadioManager.java
+++ b/core/java/android/hardware/radio/RadioManager.java
@@ -921,7 +921,10 @@ public class RadioManager {
@NonNull final BandDescriptor mDescriptor;
BandConfig(BandDescriptor descriptor) {
- mDescriptor = Objects.requireNonNull(descriptor);
+ Objects.requireNonNull(descriptor, "Descriptor cannot be null");
+ mDescriptor = new BandDescriptor(descriptor.getRegion(), descriptor.getType(),
+ descriptor.getLowerLimit(), descriptor.getUpperLimit(),
+ descriptor.getSpacing());
}
BandConfig(int region, int type, int lowerLimit, int upperLimit, int spacing) {
diff --git a/core/java/android/net/vcn/VcnManager.java b/core/java/android/net/vcn/VcnManager.java
index 40e4083c02db..3a7aea5d5194 100644
--- a/core/java/android/net/vcn/VcnManager.java
+++ b/core/java/android/net/vcn/VcnManager.java
@@ -104,12 +104,23 @@ public class VcnManager {
// TODO: Add separate signal strength thresholds for 2.4 GHz and 5GHz
+ /**
+ * Key for transports that need to be marked as restricted by the VCN
+ *
+ * <p>Defaults to TRANSPORT_WIFI if the config does not exist
+ *
+ * @hide
+ */
+ public static final String VCN_RESTRICTED_TRANSPORTS_INT_ARRAY_KEY =
+ "vcn_restricted_transports";
+
/** List of Carrier Config options to extract from Carrier Config bundles. @hide */
@NonNull
public static final String[] VCN_RELATED_CARRIER_CONFIG_KEYS =
new String[] {
VCN_NETWORK_SELECTION_WIFI_ENTRY_RSSI_THRESHOLD_KEY,
- VCN_NETWORK_SELECTION_WIFI_EXIT_RSSI_THRESHOLD_KEY
+ VCN_NETWORK_SELECTION_WIFI_EXIT_RSSI_THRESHOLD_KEY,
+ VCN_RESTRICTED_TRANSPORTS_INT_ARRAY_KEY
};
private static final Map<
diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java
index 8e55692bb81c..8278e89d80df 100644
--- a/core/java/android/os/Binder.java
+++ b/core/java/android/os/Binder.java
@@ -328,16 +328,28 @@ public class Binder implements IBinder {
public static final native boolean isDirectlyHandlingTransaction();
/**
+ * Returns {@code true} if the current thread has had its identity
+ * set explicitly via {@link #clearCallingIdentity()}
+ *
+ * @hide
+ */
+ @CriticalNative
+ private static native boolean hasExplicitIdentity();
+
+ /**
* Return the Linux UID assigned to the process that sent the transaction
* currently being processed.
*
* @throws IllegalStateException if the current thread is not currently
- * executing an incoming transaction.
+ * executing an incoming transaction and the calling identity has not been
+ * explicitly set with {@link #clearCallingIdentity()}
*/
public static final int getCallingUidOrThrow() {
- if (!isDirectlyHandlingTransaction()) {
+ if (!isDirectlyHandlingTransaction() && !hasExplicitIdentity()) {
throw new IllegalStateException(
- "Thread is not in a binder transcation");
+ "Thread is not in a binder transaction, "
+ + "and the calling identity has not been "
+ + "explicitly set with clearCallingIdentity");
}
return getCallingUid();
}
diff --git a/core/java/android/os/ServiceManager.java b/core/java/android/os/ServiceManager.java
index b6ff102b00b1..9ea42780981d 100644
--- a/core/java/android/os/ServiceManager.java
+++ b/core/java/android/os/ServiceManager.java
@@ -278,8 +278,6 @@ public final class ServiceManager {
* @return {@code null} only if there are permission problems or fatal errors.
* @hide
*/
- @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
- @Nullable
public static IBinder waitForService(@NonNull String name) {
return Binder.allowBlocking(waitForServiceNative(name));
}
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index 38ac98425ae6..78994205e5e7 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -2540,9 +2540,11 @@ public class StorageManager {
* called on first creation of a new file on external storage, and whenever the
* media type of the file is updated later.
*
- * This API requires MANAGE_EXTERNAL_STORAGE permission and typical implementations
+ * This API doesn't require any special permissions, though typical implementations
* will require being called from an SELinux domain that allows setting file attributes
* related to quota (eg the GID or project ID).
+ * If the calling user has MANAGE_EXTERNAL_STORAGE permissions, quota for shared profile's
+ * volumes is also updated.
*
* The default platform user of this API is the MediaProvider process, which is
* responsible for managing all of external storage.
@@ -2559,15 +2561,17 @@ public class StorageManager {
* @hide
*/
@SystemApi
- @RequiresPermission(android.Manifest.permission.MANAGE_EXTERNAL_STORAGE)
public void updateExternalStorageFileQuotaType(@NonNull File path,
@QuotaType int quotaType) throws IOException {
long projectId;
final String filePath = path.getCanonicalPath();
- // MANAGE_EXTERNAL_STORAGE permission is required as FLAG_INCLUDE_SHARED_PROFILE is being
- // set while querying getVolumeList.
- final StorageVolume[] availableVolumes = getVolumeList(mContext.getUserId(),
- FLAG_REAL_STATE | FLAG_INCLUDE_INVISIBLE | FLAG_INCLUDE_SHARED_PROFILE);
+ int volFlags = FLAG_REAL_STATE | FLAG_INCLUDE_INVISIBLE;
+ // If caller has MANAGE_EXTERNAL_STORAGE permission, results from User Profile(s) are also
+ // returned by enabling FLAG_INCLUDE_SHARED_PROFILE.
+ if (mContext.checkSelfPermission(MANAGE_EXTERNAL_STORAGE) == PERMISSION_GRANTED) {
+ volFlags |= FLAG_INCLUDE_SHARED_PROFILE;
+ }
+ final StorageVolume[] availableVolumes = getVolumeList(mContext.getUserId(), volFlags);
final StorageVolume volume = getStorageVolume(availableVolumes, path);
if (volume == null) {
Log.w(TAG, "Failed to update quota type for " + filePath);
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index b644a0b3d07d..80098d56ebbc 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -15999,6 +15999,15 @@ public final class Settings {
public static final String STYLUS_HANDWRITING_ENABLED = "stylus_handwriting_enabled";
/**
+ * Indicates whether a stylus has ever been used on the device.
+ *
+ * @hide
+ */
+ @Readable
+ @SuppressLint("NoSettingsProvider")
+ public static final String STYLUS_EVER_USED = "stylus_ever_used";
+
+ /**
* Exemptions to the hidden API blacklist.
*
* @hide
diff --git a/core/java/android/service/wallpaper/IWallpaperEngine.aidl b/core/java/android/service/wallpaper/IWallpaperEngine.aidl
index 93d4def2180e..a41401b73747 100644
--- a/core/java/android/service/wallpaper/IWallpaperEngine.aidl
+++ b/core/java/android/service/wallpaper/IWallpaperEngine.aidl
@@ -47,4 +47,5 @@ interface IWallpaperEngine {
oneway void addLocalColorsAreas(in List<RectF> regions);
SurfaceControl mirrorSurfaceControl();
oneway void applyDimming(float dimAmount);
+ oneway void setWallpaperFlags(int which);
}
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index 007478a25016..aebd91a0be2f 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -166,6 +166,7 @@ public abstract class WallpaperService extends Service {
private static final int MSG_SCALE_PREVIEW = 10110;
private static final int MSG_REPORT_SHOWN = 10150;
private static final int MSG_UPDATE_DIMMING = 10200;
+ private static final int MSG_WALLPAPER_FLAGS_CHANGED = 10210;
private static final List<Float> PROHIBITED_STEPS = Arrays.asList(0f, Float.POSITIVE_INFINITY,
Float.NEGATIVE_INFINITY);
@@ -486,6 +487,13 @@ public abstract class WallpaperService extends Service {
}
/**
+ * Returns the current wallpaper flags indicating which screen this Engine is rendering to.
+ */
+ @SetWallpaperFlags public int getWallpaperFlags() {
+ return mIWallpaperEngine.mWhich;
+ }
+
+ /**
* Convenience for {@link WallpaperManager#getDesiredMinimumWidth()
* WallpaperManager.getDesiredMinimumWidth()}, returning the width
* that the system would like this wallpaper to run in.
@@ -795,6 +803,16 @@ public abstract class WallpaperService extends Service {
}
/**
+ * Called when the current wallpaper flags change.
+ *
+ * @param which The new flag value
+ * @see #getWallpaperFlags()
+ */
+ @MainThread
+ public void onWallpaperFlagsChanged(@SetWallpaperFlags int which) {
+ }
+
+ /**
* Called when the zoom level of the wallpaper changed.
* This method will be called with the initial zoom level when the surface is created.
*
@@ -2195,11 +2213,12 @@ public abstract class WallpaperService extends Service {
private final AtomicBoolean mDetached = new AtomicBoolean();
Engine mEngine;
+ @SetWallpaperFlags int mWhich;
IWallpaperEngineWrapper(WallpaperService context,
IWallpaperConnection conn, IBinder windowToken,
int windowType, boolean isPreview, int reqWidth, int reqHeight, Rect padding,
- int displayId) {
+ int displayId, @SetWallpaperFlags int which) {
mWallpaperManager = getSystemService(WallpaperManager.class);
mCaller = new HandlerCaller(context, context.getMainLooper(), this, true);
mConnection = conn;
@@ -2210,6 +2229,7 @@ public abstract class WallpaperService extends Service {
mReqHeight = reqHeight;
mDisplayPadding.set(padding);
mDisplayId = displayId;
+ mWhich = which;
// Create a display context before onCreateEngine.
mDisplayManager = getSystemService(DisplayManager.class);
@@ -2240,6 +2260,16 @@ public abstract class WallpaperService extends Service {
}
@Override
+ public void setWallpaperFlags(@SetWallpaperFlags int which) {
+ if (which == mWhich) {
+ return;
+ }
+ mWhich = which;
+ Message msg = mCaller.obtainMessageI(MSG_WALLPAPER_FLAGS_CHANGED, which);
+ mCaller.sendMessage(msg);
+ }
+
+ @Override
public void setInAmbientMode(boolean inAmbientDisplay, long animationDuration)
throws RemoteException {
Message msg = mCaller.obtainMessageIO(DO_IN_AMBIENT_MODE, inAmbientDisplay ? 1 : 0,
@@ -2459,6 +2489,9 @@ public abstract class WallpaperService extends Service {
reportShown();
Trace.endSection();
} break;
+ case MSG_WALLPAPER_FLAGS_CHANGED: {
+ mEngine.onWallpaperFlagsChanged(message.arg1);
+ } break;
default :
Log.w(TAG, "Unknown message type " + message.what);
}
@@ -2483,7 +2516,7 @@ public abstract class WallpaperService extends Service {
int displayId, @SetWallpaperFlags int which) {
Trace.beginSection("WPMS.ServiceWrapper.attach");
mEngineWrapper = new IWallpaperEngineWrapper(mTarget, conn, windowToken,
- windowType, isPreview, reqWidth, reqHeight, padding, displayId);
+ windowType, isPreview, reqWidth, reqHeight, padding, displayId, which);
Trace.endSection();
}
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index 7199e57e7970..5933ae4f8ca4 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -1291,7 +1291,10 @@ public final class Display {
}
}
- /** @hide */
+ /**
+ * Returns null if it's virtual display.
+ * @hide
+ */
@Nullable
public OverlayProperties getOverlaySupport() {
synchronized (mLock) {
@@ -1299,7 +1302,7 @@ public final class Display {
if (mDisplayInfo.type != TYPE_VIRTUAL) {
return mGlobal.getOverlaySupport();
}
- return new OverlayProperties();
+ return null;
}
}
diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java
index b3e8fb68ee78..c8a5d8d887f9 100644
--- a/core/java/android/view/MotionEvent.java
+++ b/core/java/android/view/MotionEvent.java
@@ -22,7 +22,9 @@ import static android.view.Display.DEFAULT_DISPLAY;
import static java.lang.annotation.RetentionPolicy.SOURCE;
import android.annotation.IntDef;
+import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.SuppressLint;
import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.graphics.Matrix;
@@ -1780,19 +1782,18 @@ public final class MotionEvent extends InputEvent implements Parcelable {
* @param displayId The display ID associated with this event.
* @param flags The motion event flags.
* @param classification The classification to give this event.
- * @hide
*/
- public static MotionEvent obtain(long downTime, long eventTime,
- int action, int pointerCount, PointerProperties[] pointerProperties,
- PointerCoords[] pointerCoords, int metaState, int buttonState,
- float xPrecision, float yPrecision, int deviceId,
- int edgeFlags, int source, int displayId, int flags,
- @Classification int classification) {
+ public static @Nullable MotionEvent obtain(long downTime, long eventTime, int action,
+ int pointerCount,
+ @SuppressLint("ArrayReturn") @NonNull PointerProperties[] pointerProperties,
+ @SuppressLint("ArrayReturn") @NonNull PointerCoords[] pointerCoords, int metaState,
+ int buttonState, float xPrecision, float yPrecision, int deviceId, int edgeFlags,
+ int source, int displayId, int flags, @Classification int classification) {
MotionEvent ev = obtain();
final boolean success = ev.initialize(deviceId, source, displayId, action, flags, edgeFlags,
metaState, buttonState, classification, 0, 0, xPrecision, yPrecision,
- downTime * NS_PER_MS, eventTime * NS_PER_MS,
- pointerCount, pointerProperties, pointerCoords);
+ downTime * NS_PER_MS, eventTime * NS_PER_MS, pointerCount, pointerProperties,
+ pointerCoords);
if (!success) {
Log.e(TAG, "Could not initialize MotionEvent");
ev.recycle();
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 06851de95f82..e1ca0f139113 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -47,6 +47,7 @@ import android.graphics.Region;
import android.gui.DropInputMode;
import android.hardware.DataSpace;
import android.hardware.HardwareBuffer;
+import android.hardware.OverlayProperties;
import android.hardware.SyncFence;
import android.hardware.display.DeviceProductInfo;
import android.hardware.display.DisplayManager;
@@ -201,6 +202,7 @@ public final class SurfaceControl implements Parcelable {
private static native DisplayPrimaries nativeGetDisplayNativePrimaries(
IBinder displayToken);
private static native int[] nativeGetCompositionDataspaces();
+ private static native OverlayProperties nativeGetOverlaySupport();
private static native boolean nativeSetActiveColorMode(IBinder displayToken,
int colorMode);
private static native boolean nativeGetBootDisplayModeSupport();
@@ -2044,6 +2046,14 @@ public final class SurfaceControl implements Parcelable {
}
/**
+ * @return the overlay properties of the device
+ * @hide
+ */
+ public static OverlayProperties getOverlaySupport() {
+ return nativeGetOverlaySupport();
+ }
+
+ /**
* @hide
*/
public static boolean getBootDisplayModeSupport() {
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 720813ad81ef..ef18458d3244 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -947,112 +947,108 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
+ " left=" + (mWindowSpaceLeft != mLocation[0])
+ " top=" + (mWindowSpaceTop != mLocation[1]));
- try {
- mVisible = mRequestedVisible;
- mWindowSpaceLeft = mLocation[0];
- mWindowSpaceTop = mLocation[1];
- mSurfaceWidth = myWidth;
- mSurfaceHeight = myHeight;
- mFormat = mRequestedFormat;
- mAlpha = alpha;
- mLastWindowVisibility = mWindowVisibility;
- mTransformHint = viewRoot.getBufferTransformHint();
- mSubLayer = mRequestedSubLayer;
-
- mScreenRect.left = mWindowSpaceLeft;
- mScreenRect.top = mWindowSpaceTop;
- mScreenRect.right = mWindowSpaceLeft + getWidth();
- mScreenRect.bottom = mWindowSpaceTop + getHeight();
- if (translator != null) {
- translator.translateRectInAppWindowToScreen(mScreenRect);
- }
-
- final Rect surfaceInsets = viewRoot.mWindowAttributes.surfaceInsets;
- mScreenRect.offset(surfaceInsets.left, surfaceInsets.top);
- // Collect all geometry changes and apply these changes on the RenderThread worker
- // via the RenderNode.PositionUpdateListener.
- final Transaction surfaceUpdateTransaction = new Transaction();
- if (creating) {
- updateOpaqueFlag();
- final String name = "SurfaceView[" + viewRoot.getTitle().toString() + "]";
- createBlastSurfaceControls(viewRoot, name, surfaceUpdateTransaction);
- } else if (mSurfaceControl == null) {
- return;
- }
+ mVisible = mRequestedVisible;
+ mWindowSpaceLeft = mLocation[0];
+ mWindowSpaceTop = mLocation[1];
+ mSurfaceWidth = myWidth;
+ mSurfaceHeight = myHeight;
+ mFormat = mRequestedFormat;
+ mAlpha = alpha;
+ mLastWindowVisibility = mWindowVisibility;
+ mTransformHint = viewRoot.getBufferTransformHint();
+ mSubLayer = mRequestedSubLayer;
+
+ mScreenRect.left = mWindowSpaceLeft;
+ mScreenRect.top = mWindowSpaceTop;
+ mScreenRect.right = mWindowSpaceLeft + getWidth();
+ mScreenRect.bottom = mWindowSpaceTop + getHeight();
+ if (translator != null) {
+ translator.translateRectInAppWindowToScreen(mScreenRect);
+ }
- final boolean redrawNeeded = sizeChanged || creating || hintChanged
- || (mVisible && !mDrawFinished) || alphaChanged || relativeZChanged;
- boolean shouldSyncBuffer =
- redrawNeeded && viewRoot.wasRelayoutRequested() && viewRoot.isInLocalSync();
- SyncBufferTransactionCallback syncBufferTransactionCallback = null;
- if (shouldSyncBuffer) {
- syncBufferTransactionCallback = new SyncBufferTransactionCallback();
- mBlastBufferQueue.syncNextTransaction(
- false /* acquireSingleBuffer */,
- syncBufferTransactionCallback::onTransactionReady);
- }
+ final Rect surfaceInsets = viewRoot.mWindowAttributes.surfaceInsets;
+ mScreenRect.offset(surfaceInsets.left, surfaceInsets.top);
+ // Collect all geometry changes and apply these changes on the RenderThread worker
+ // via the RenderNode.PositionUpdateListener.
+ final Transaction surfaceUpdateTransaction = new Transaction();
+ if (creating) {
+ updateOpaqueFlag();
+ final String name = "SurfaceView[" + viewRoot.getTitle().toString() + "]";
+ createBlastSurfaceControls(viewRoot, name, surfaceUpdateTransaction);
+ } else if (mSurfaceControl == null) {
+ return;
+ }
- final boolean realSizeChanged = performSurfaceTransaction(viewRoot, translator,
- creating, sizeChanged, hintChanged, relativeZChanged,
- surfaceUpdateTransaction);
+ final boolean redrawNeeded = sizeChanged || creating || hintChanged
+ || (mVisible && !mDrawFinished) || alphaChanged || relativeZChanged;
+ boolean shouldSyncBuffer =
+ redrawNeeded && viewRoot.wasRelayoutRequested() && viewRoot.isInLocalSync();
+ SyncBufferTransactionCallback syncBufferTransactionCallback = null;
+ if (shouldSyncBuffer) {
+ syncBufferTransactionCallback = new SyncBufferTransactionCallback();
+ mBlastBufferQueue.syncNextTransaction(
+ false /* acquireSingleBuffer */,
+ syncBufferTransactionCallback::onTransactionReady);
+ }
- try {
- SurfaceHolder.Callback[] callbacks = null;
+ final boolean realSizeChanged = performSurfaceTransaction(viewRoot, translator,
+ creating, sizeChanged, hintChanged, relativeZChanged,
+ surfaceUpdateTransaction);
- final boolean surfaceChanged = creating;
- if (mSurfaceCreated && (surfaceChanged || (!mVisible && visibleChanged))) {
- mSurfaceCreated = false;
- notifySurfaceDestroyed();
- }
+ try {
+ SurfaceHolder.Callback[] callbacks = null;
- copySurface(creating /* surfaceControlCreated */, sizeChanged);
+ final boolean surfaceChanged = creating;
+ if (mSurfaceCreated && (surfaceChanged || (!mVisible && visibleChanged))) {
+ mSurfaceCreated = false;
+ notifySurfaceDestroyed();
+ }
- if (mVisible && mSurface.isValid()) {
- if (!mSurfaceCreated && (surfaceChanged || visibleChanged)) {
- mSurfaceCreated = true;
- mIsCreating = true;
- if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " "
- + "visibleChanged -- surfaceCreated");
- callbacks = getSurfaceCallbacks();
- for (SurfaceHolder.Callback c : callbacks) {
- c.surfaceCreated(mSurfaceHolder);
- }
+ copySurface(creating /* surfaceControlCreated */, sizeChanged);
+
+ if (mVisible && mSurface.isValid()) {
+ if (!mSurfaceCreated && (surfaceChanged || visibleChanged)) {
+ mSurfaceCreated = true;
+ mIsCreating = true;
+ if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " "
+ + "visibleChanged -- surfaceCreated");
+ callbacks = getSurfaceCallbacks();
+ for (SurfaceHolder.Callback c : callbacks) {
+ c.surfaceCreated(mSurfaceHolder);
}
- if (creating || formatChanged || sizeChanged || hintChanged
- || visibleChanged || realSizeChanged) {
- if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " "
- + "surfaceChanged -- format=" + mFormat
- + " w=" + myWidth + " h=" + myHeight);
- if (callbacks == null) {
- callbacks = getSurfaceCallbacks();
- }
- for (SurfaceHolder.Callback c : callbacks) {
- c.surfaceChanged(mSurfaceHolder, mFormat, myWidth, myHeight);
- }
+ }
+ if (creating || formatChanged || sizeChanged || hintChanged
+ || visibleChanged || realSizeChanged) {
+ if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " "
+ + "surfaceChanged -- format=" + mFormat
+ + " w=" + myWidth + " h=" + myHeight);
+ if (callbacks == null) {
+ callbacks = getSurfaceCallbacks();
}
- if (redrawNeeded) {
- if (DEBUG) {
- Log.i(TAG, System.identityHashCode(this) + " surfaceRedrawNeeded");
- }
- if (callbacks == null) {
- callbacks = getSurfaceCallbacks();
- }
-
- if (shouldSyncBuffer) {
- handleSyncBufferCallback(callbacks, syncBufferTransactionCallback);
- } else {
- handleSyncNoBuffer(callbacks);
- }
+ for (SurfaceHolder.Callback c : callbacks) {
+ c.surfaceChanged(mSurfaceHolder, mFormat, myWidth, myHeight);
}
}
- } finally {
- mIsCreating = false;
- if (mSurfaceControl != null && !mSurfaceCreated) {
- releaseSurfaces(false /* releaseSurfacePackage*/);
+ if (redrawNeeded) {
+ if (DEBUG) {
+ Log.i(TAG, System.identityHashCode(this) + " surfaceRedrawNeeded");
+ }
+ if (callbacks == null) {
+ callbacks = getSurfaceCallbacks();
+ }
+
+ if (shouldSyncBuffer) {
+ handleSyncBufferCallback(callbacks, syncBufferTransactionCallback);
+ } else {
+ handleSyncNoBuffer(callbacks);
+ }
}
}
- } catch (Exception ex) {
- Log.e(TAG, "Exception configuring surface", ex);
+ } finally {
+ mIsCreating = false;
+ if (mSurfaceControl != null && !mSurfaceCreated) {
+ releaseSurfaces(false /* releaseSurfacePackage*/);
+ }
}
if (DEBUG) Log.v(
TAG, "Layout: x=" + mScreenRect.left + " y=" + mScreenRect.top
diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java
index 58aee61b98be..f51d9bacc0a5 100644
--- a/core/java/android/view/ViewConfiguration.java
+++ b/core/java/android/view/ViewConfiguration.java
@@ -822,7 +822,6 @@ public class ViewConfiguration {
*
* @hide
*/
- @TestApi
public static long getSendRecurringAccessibilityEventsInterval() {
return SEND_RECURRING_ACCESSIBILITY_EVENTS_INTERVAL_MILLIS;
}
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index 88adb2e1b1f1..c067955e1114 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -127,16 +127,6 @@ public class AccessibilityNodeInfo implements Parcelable {
/** @hide */
public static final long UNDEFINED_NODE_ID = makeNodeId(UNDEFINED_ITEM_ID, UNDEFINED_ITEM_ID);
- /**
- * The default value for {@link #getMinMillisBetweenContentChanges};
- */
- public static final int UNDEFINED_MIN_MILLIS_BETWEEN_CONTENT_CHANGES = -1;
-
- /**
- * The minimum value for {@link #setMinMillisBetweenContentChanges};
- */
- public static final int MINIMUM_MIN_MILLIS_BETWEEN_CONTENT_CHANGES = 100;
-
/** @hide */
public static final long ROOT_NODE_ID = makeNodeId(ROOT_ITEM_ID,
AccessibilityNodeProvider.HOST_VIEW_ID);
@@ -820,6 +810,8 @@ public class AccessibilityNodeInfo implements Parcelable {
private static final int BOOLEAN_PROPERTY_IS_TEXT_SELECTABLE = 0x0800000;
+ private static final int BOOLEAN_PROPERTY_REQUEST_INITIAL_ACCESSIBILITY_FOCUS = 1 << 24;
+
/**
* Bits that provide the id of a virtual descendant of a view.
*/
@@ -889,8 +881,7 @@ public class AccessibilityNodeInfo implements Parcelable {
private long mTraversalBefore = UNDEFINED_NODE_ID;
private long mTraversalAfter = UNDEFINED_NODE_ID;
- private int mMinMillisBetweenContentChanges =
- UNDEFINED_MIN_MILLIS_BETWEEN_CONTENT_CHANGES;
+ private int mMinMillisBetweenContentChanges;
private int mBooleanProperties;
private final Rect mBoundsInParent = new Rect();
@@ -1799,12 +1790,6 @@ public class AccessibilityNodeInfo implements Parcelable {
* content change events in accessibility services.
*
* <p>
- * <strong>Note:</strong>
- * This value should not be smaller than {@link #MINIMUM_MIN_MILLIS_BETWEEN_CONTENT_CHANGES},
- * otherwise it would be ignored by accessibility services.
- * </p>
- *
- * <p>
* Example: An app can set MinMillisBetweenContentChanges as 1 min for a view which sends
* content change events to accessibility services one event per second.
* Accessibility service will throttle those content change events and only handle one event
@@ -1816,15 +1801,11 @@ public class AccessibilityNodeInfo implements Parcelable {
*/
public void setMinMillisBetweenContentChanges(int minMillisBetweenContentChanges) {
enforceNotSealed();
- mMinMillisBetweenContentChanges = minMillisBetweenContentChanges
- >= MINIMUM_MIN_MILLIS_BETWEEN_CONTENT_CHANGES
- ? minMillisBetweenContentChanges
- : UNDEFINED_MIN_MILLIS_BETWEEN_CONTENT_CHANGES;
+ mMinMillisBetweenContentChanges = minMillisBetweenContentChanges;
}
/**
- * Gets the minimum time duration between two content change events. This method may return
- * {@link #UNDEFINED_MIN_MILLIS_BETWEEN_CONTENT_CHANGES}
+ * Gets the minimum time duration between two content change events.
*/
public int getMinMillisBetweenContentChanges() {
return mMinMillisBetweenContentChanges;
@@ -2491,6 +2472,38 @@ public class AccessibilityNodeInfo implements Parcelable {
}
/**
+ * Gets whether the node has {@link #setRequestInitialAccessibilityFocus}.
+ *
+ * @return True if the node has requested initial accessibility focus.
+ */
+ public boolean hasRequestInitialAccessibilityFocus() {
+ return getBooleanProperty(BOOLEAN_PROPERTY_REQUEST_INITIAL_ACCESSIBILITY_FOCUS);
+ }
+
+ /**
+ * Sets whether the node has requested initial accessibility focus.
+ *
+ * <p>
+ * If the node {@link #hasRequestInitialAccessibilityFocus}, this node would be one of
+ * candidates to be accessibility focused when the window appears.
+ * </p>
+ *
+ * <p>
+ * <strong>Note:</strong> Cannot be called from an
+ * {@link android.accessibilityservice.AccessibilityService}.
+ * This class is made immutable before being delivered to an AccessibilityService.
+ * </p>
+ *
+ * @param requestInitialAccessibilityFocus True if the node requests to receive initial
+ * accessibility focus.
+ * @throws IllegalStateException If called from an AccessibilityService.
+ */
+ public void setRequestInitialAccessibilityFocus(boolean requestInitialAccessibilityFocus) {
+ setBooleanProperty(BOOLEAN_PROPERTY_REQUEST_INITIAL_ACCESSIBILITY_FOCUS,
+ requestInitialAccessibilityFocus);
+ }
+
+ /**
* Gets if the node is editable.
*
* @return True if the node is editable, false otherwise.
diff --git a/core/java/android/window/BackNavigationInfo.java b/core/java/android/window/BackNavigationInfo.java
index a25e0351df83..d7bca30209e6 100644
--- a/core/java/android/window/BackNavigationInfo.java
+++ b/core/java/android/window/BackNavigationInfo.java
@@ -19,6 +19,7 @@ package android.window;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.TestApi;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
@@ -29,6 +30,7 @@ import android.os.RemoteCallback;
*
* @hide
*/
+@TestApi
public final class BackNavigationInfo implements Parcelable {
/**
@@ -71,6 +73,7 @@ public final class BackNavigationInfo implements Parcelable {
/**
* Defines the type of back destinations a back even can lead to. This is used to define the
* type of animation that need to be run on SystemUI.
+ * @hide
*/
@IntDef(prefix = "TYPE_", value = {
TYPE_UNDEFINED,
@@ -97,7 +100,6 @@ public final class BackNavigationInfo implements Parcelable {
* @param onBackNavigationDone The callback to be called once the client is done with the
* back preview.
* @param onBackInvokedCallback The back callback registered by the current top level window.
- * @param departingWindowContainerToken The {@link WindowContainerToken} of departing window.
*/
private BackNavigationInfo(@BackTargetType int type,
@Nullable RemoteCallback onBackNavigationDone,
@@ -116,6 +118,7 @@ public final class BackNavigationInfo implements Parcelable {
mPrepareRemoteAnimation = in.readBoolean();
}
+ /** @hide */
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeInt(mType);
@@ -126,7 +129,7 @@ public final class BackNavigationInfo implements Parcelable {
/**
* Returns the type of back navigation that is about to happen.
- *
+ * @hide
* @see BackTargetType
*/
public @BackTargetType int getType() {
@@ -138,7 +141,7 @@ public final class BackNavigationInfo implements Parcelable {
* the client didn't register a callback.
* <p>
* This is never null when {@link #getType} returns {@link #TYPE_CALLBACK}.
- *
+ * @hide
* @see OnBackInvokedCallback
* @see OnBackInvokedDispatcher
*/
@@ -149,6 +152,7 @@ public final class BackNavigationInfo implements Parcelable {
/**
* Return true if the core is preparing a back gesture nimation.
+ * @hide
*/
public boolean isPrepareRemoteAnimation() {
return mPrepareRemoteAnimation;
@@ -157,7 +161,7 @@ public final class BackNavigationInfo implements Parcelable {
/**
* Callback to be called when the back preview is finished in order to notify the server that
* it can clean up the resources created for the animation.
- *
+ * @hide
* @param triggerBack Boolean indicating if back navigation has been triggered.
*/
public void onBackNavigationFinished(boolean triggerBack) {
@@ -168,11 +172,13 @@ public final class BackNavigationInfo implements Parcelable {
}
}
+ /** @hide */
@Override
public int describeContents() {
return 0;
}
+ @NonNull
public static final Creator<BackNavigationInfo> CREATOR = new Creator<BackNavigationInfo>() {
@Override
public BackNavigationInfo createFromParcel(Parcel in) {
@@ -197,6 +203,7 @@ public final class BackNavigationInfo implements Parcelable {
/**
* Translates the {@link BackNavigationInfo} integer type to its String representation
*/
+ @NonNull
public static String typeToString(@BackTargetType int type) {
switch (type) {
case TYPE_UNDEFINED:
diff --git a/core/java/com/android/internal/protolog/BaseProtoLogImpl.java b/core/java/com/android/internal/protolog/BaseProtoLogImpl.java
index 83309fc61009..cd55d3292217 100644
--- a/core/java/com/android/internal/protolog/BaseProtoLogImpl.java
+++ b/core/java/com/android/internal/protolog/BaseProtoLogImpl.java
@@ -32,6 +32,7 @@ import static com.android.internal.protolog.ProtoLogMessage.STR_PARAMS;
import android.annotation.Nullable;
import android.os.ShellCommand;
import android.os.SystemClock;
+import android.text.TextUtils;
import android.util.Slog;
import android.util.proto.ProtoOutputStream;
@@ -44,7 +45,6 @@ import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
-import java.util.IllegalFormatConversionException;
import java.util.TreeMap;
import java.util.stream.Collectors;
@@ -108,10 +108,14 @@ public class BaseProtoLogImpl {
messageString = mViewerConfig.getViewerString(messageHash);
}
if (messageString != null) {
- try {
- message = String.format(messageString, args);
- } catch (IllegalFormatConversionException ex) {
- Slog.w(TAG, "Invalid ProtoLog format string.", ex);
+ if (args != null) {
+ try {
+ message = TextUtils.formatSimple(messageString, args);
+ } catch (Exception ex) {
+ Slog.w(TAG, "Invalid ProtoLog format string.", ex);
+ }
+ } else {
+ message = messageString;
}
}
if (message == null) {
diff --git a/core/java/com/android/internal/protolog/common/LogDataType.java b/core/java/com/android/internal/protolog/common/LogDataType.java
index 651932a7ba7e..c05824a58a77 100644
--- a/core/java/com/android/internal/protolog/common/LogDataType.java
+++ b/core/java/com/android/internal/protolog/common/LogDataType.java
@@ -74,13 +74,10 @@ public class LogDataType {
types.add(LogDataType.BOOLEAN);
break;
case 'd':
- case 'o':
case 'x':
types.add(LogDataType.LONG);
break;
case 'f':
- case 'e':
- case 'g':
types.add(LogDataType.DOUBLE);
break;
case 's':
diff --git a/core/java/com/android/internal/protolog/common/ProtoLog.java b/core/java/com/android/internal/protolog/common/ProtoLog.java
index 01cc1ed37ad4..93765cdf0890 100644
--- a/core/java/com/android/internal/protolog/common/ProtoLog.java
+++ b/core/java/com/android/internal/protolog/common/ProtoLog.java
@@ -22,11 +22,12 @@ package com.android.internal.protolog.common;
* a messageString, which is a format string for the log message (has to be a string literal or
* a concatenation of string literals) and a vararg array of parameters for the formatter.
*
- * The syntax for the message string is a subset of {@code java.util.Formatter} syntax.
+ * The syntax for the message string depends on
+ * {@link android.text.TextUtils#formatSimple(String, Object...)}}.
* Supported conversions:
* %b - boolean
- * %d, %o and %x - integral type (Short, Integer or Long)
- * %f, %e and %g - floating point type (Float or Double)
+ * %d %x - integral type (Short, Integer or Long)
+ * %f - floating point type (Float or Double)
* %s - string
* %% - a literal percent character
* The width and precision modifiers are supported, argument_index and flags are not.
diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl
index edbdc86151a1..ebfc4f75fe2a 100644
--- a/core/java/com/android/internal/statusbar/IStatusBar.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl
@@ -324,4 +324,7 @@ oneway interface IStatusBar
/** Dump protos from SystemUI. The proto definition is defined there */
void dumpProto(in String[] args, in ParcelFileDescriptor pfd);
+
+ /** Shows rear display educational dialog */
+ void showRearDisplayDialog(int currentBaseState);
}
diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
index d19068130b6d..8f04cdaf8fde 100644
--- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
@@ -226,4 +226,7 @@ interface IStatusBarService
/** Unregisters a nearby media devices provider. */
void unregisterNearbyMediaDevicesProvider(in INearbyMediaDevicesProvider provider);
+
+ /** Shows rear display educational dialog */
+ void showRearDisplayDialog(int currentBaseState);
}
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index cc3d90635b32..d8b91c7dca79 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -192,6 +192,7 @@ cc_library_shared {
"android_hardware_display_DisplayManagerGlobal.cpp",
"android_hardware_display_DisplayViewport.cpp",
"android_hardware_HardwareBuffer.cpp",
+ "android_hardware_OverlayProperties.cpp",
"android_hardware_SensorManager.cpp",
"android_hardware_SerialPort.cpp",
"android_hardware_SyncFence.cpp",
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 0798110134f8..f549cd828e7d 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -82,6 +82,7 @@ extern int register_android_hardware_camera2_impl_CameraExtensionJpegProcessor(J
extern int register_android_hardware_camera2_utils_SurfaceUtils(JNIEnv* env);
extern int register_android_hardware_display_DisplayManagerGlobal(JNIEnv* env);
extern int register_android_hardware_HardwareBuffer(JNIEnv *env);
+extern int register_android_hardware_OverlayProperties(JNIEnv* env);
extern int register_android_hardware_SensorManager(JNIEnv *env);
extern int register_android_hardware_SerialPort(JNIEnv *env);
extern int register_android_hardware_SyncFence(JNIEnv* env);
@@ -1603,6 +1604,7 @@ static const RegJNIRec gRegJNI[] = {
REG_JNI(register_android_hardware_camera2_utils_SurfaceUtils),
REG_JNI(register_android_hardware_display_DisplayManagerGlobal),
REG_JNI(register_android_hardware_HardwareBuffer),
+ REG_JNI(register_android_hardware_OverlayProperties),
REG_JNI(register_android_hardware_SensorManager),
REG_JNI(register_android_hardware_SerialPort),
REG_JNI(register_android_hardware_SyncFence),
diff --git a/core/jni/OWNERS b/core/jni/OWNERS
index 9f39c32171d7..53594e1a0855 100644
--- a/core/jni/OWNERS
+++ b/core/jni/OWNERS
@@ -29,7 +29,7 @@ per-file android_content_res_* = file:/core/java/android/content/res/OWNERS
per-file android_util_AssetManager* = file:/core/java/android/content/res/OWNERS
per-file android_util_StringBlock* = file:/core/java/android/content/res/OWNERS
per-file android_util_XmlBlock* = file:/core/java/android/content/res/OWNERS
-per-file com_android_internal_content_om_OverlayConfig* = file:/core/java/android/content/res/OWNERS
+per-file com_android_internal_content_om_Overlay* = file:/core/java/android/content/res/OWNERS
# Binder related things
per-file android_os_Parcel* = file:platform/frameworks/native:/libs/binder/OWNERS
diff --git a/core/jni/android_hardware_OverlayProperties.cpp b/core/jni/android_hardware_OverlayProperties.cpp
new file mode 100644
index 000000000000..a96af8628e62
--- /dev/null
+++ b/core/jni/android_hardware_OverlayProperties.cpp
@@ -0,0 +1,147 @@
+/**
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "OverlayProperties"
+// #define LOG_NDEBUG 0
+
+#include <android/gui/OverlayProperties.h>
+#include <binder/Parcel.h>
+#include <gui/SurfaceComposerClient.h>
+#include <nativehelper/JNIHelp.h>
+
+#include "android_os_Parcel.h"
+#include "core_jni_helpers.h"
+#include "jni.h"
+
+using namespace android;
+
+// ----------------------------------------------------------------------------
+// Types
+// ----------------------------------------------------------------------------
+static struct {
+ jclass clazz;
+ jmethodID ctor;
+} gOverlayPropertiesClassInfo;
+
+// ----------------------------------------------------------------------------
+// OverlayProperties lifecycle
+// ----------------------------------------------------------------------------
+
+static void destroyOverlayProperties(gui::OverlayProperties* overlayProperties) {
+ delete overlayProperties;
+}
+
+static jlong android_hardware_OverlayProperties_getDestructor(JNIEnv*, jclass) {
+ return static_cast<jlong>(reinterpret_cast<uintptr_t>(&destroyOverlayProperties));
+}
+
+//----------------------------------------------------------------------------
+// Accessors
+// ----------------------------------------------------------------------------
+
+static jboolean android_hardware_OverlayProperties_supportFp16ForHdr(JNIEnv* env, jobject thiz,
+ jlong nativeObject) {
+ gui::OverlayProperties* properties = reinterpret_cast<gui::OverlayProperties*>(nativeObject);
+ if (properties != nullptr) {
+ for (const auto& i : properties->combinations) {
+ if (std::find(i.pixelFormats.begin(), i.pixelFormats.end(),
+ static_cast<int32_t>(HAL_PIXEL_FORMAT_RGBA_FP16)) !=
+ i.pixelFormats.end() &&
+ std::find(i.dataspaces.begin(), i.dataspaces.end(),
+ static_cast<int32_t>(HAL_DATASPACE_BT2020_PQ)) != i.dataspaces.end()) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+// ----------------------------------------------------------------------------
+// Serialization
+// ----------------------------------------------------------------------------
+
+static void android_hardware_OverlayProperties_write(JNIEnv* env, jclass, jlong nativeObject,
+ jobject dest) {
+ Parcel* parcel = parcelForJavaObject(env, dest);
+ if (parcel == nullptr) {
+ jniThrowNullPointerException(env, nullptr);
+ return;
+ }
+ gui::OverlayProperties* overlayProperties =
+ reinterpret_cast<gui::OverlayProperties*>(nativeObject);
+ if (overlayProperties != nullptr) {
+ overlayProperties->writeToParcel(parcel);
+ }
+}
+
+static long android_hardware_OverlayProperties_read(JNIEnv* env, jclass, jobject in) {
+ Parcel* parcel = parcelForJavaObject(env, in);
+ if (parcel == nullptr) {
+ jniThrowNullPointerException(env, nullptr);
+ return 0;
+ }
+ gui::OverlayProperties* overlayProperties = new gui::OverlayProperties;
+ if (overlayProperties->readFromParcel(parcel) != NO_ERROR) {
+ delete overlayProperties;
+ return 0;
+ }
+ return reinterpret_cast<jlong>(overlayProperties);
+}
+
+// ----------------------------------------------------------------------------
+// Public functions
+// ----------------------------------------------------------------------------
+
+namespace android {
+
+jobject android_hardware_OverlayProperties_convertToJavaObject(
+ JNIEnv* env, gui::OverlayProperties* overlayProperties) {
+ jobject overlayPropertiesObj =
+ env->NewObject(gOverlayPropertiesClassInfo.clazz, gOverlayPropertiesClassInfo.ctor,
+ reinterpret_cast<jlong>(overlayProperties));
+ return overlayPropertiesObj;
+}
+
+}; // namespace android
+
+// ----------------------------------------------------------------------------
+// JNI Glue
+// ----------------------------------------------------------------------------
+
+const char* const kClassPathName = "android/hardware/OverlayProperties";
+
+// clang-format off
+static const JNINativeMethod gMethods[] = {
+ { "nGetDestructor", "()J", (void*) android_hardware_OverlayProperties_getDestructor },
+ { "nSupportFp16ForHdr", "(J)Z",
+ (void*) android_hardware_OverlayProperties_supportFp16ForHdr },
+ { "nWriteOverlayPropertiesToParcel", "(JLandroid/os/Parcel;)V",
+ (void*) android_hardware_OverlayProperties_write },
+ { "nReadOverlayPropertiesFromParcel", "(Landroid/os/Parcel;)J",
+ (void*) android_hardware_OverlayProperties_read },
+};
+// clang-format on
+
+int register_android_hardware_OverlayProperties(JNIEnv* env) {
+ int err = RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods));
+
+ jclass clazz = FindClassOrDie(env, "android/hardware/OverlayProperties");
+ gOverlayPropertiesClassInfo.clazz = MakeGlobalRefOrDie(env, clazz);
+ gOverlayPropertiesClassInfo.ctor =
+ GetMethodIDOrDie(env, gOverlayPropertiesClassInfo.clazz, "<init>", "(J)V");
+
+ return err;
+}
diff --git a/core/jni/android_media_AudioFormat.h b/core/jni/android_media_AudioFormat.h
index 0e6b587db945..962b50147f3d 100644
--- a/core/jni/android_media_AudioFormat.h
+++ b/core/jni/android_media_AudioFormat.h
@@ -45,8 +45,10 @@
#define ENCODING_MPEGH_BL_L4 24
#define ENCODING_MPEGH_LC_L3 25
#define ENCODING_MPEGH_LC_L4 26
-#define ENCODING_DTS_UHD 27
+#define ENCODING_DTS_UHD_P1 27
#define ENCODING_DRA 28
+#define ENCODING_DTS_HD_MA 29
+#define ENCODING_DTS_UHD_P2 30
#define ENCODING_INVALID 0
#define ENCODING_DEFAULT 1
@@ -112,10 +114,14 @@ static inline audio_format_t audioFormatToNative(int audioFormat)
return AUDIO_FORMAT_MPEGH_LC_L3;
case ENCODING_MPEGH_LC_L4:
return AUDIO_FORMAT_MPEGH_LC_L4;
- case ENCODING_DTS_UHD:
+ case ENCODING_DTS_UHD_P1:
return AUDIO_FORMAT_DTS_UHD;
case ENCODING_DRA:
return AUDIO_FORMAT_DRA;
+ case ENCODING_DTS_HD_MA:
+ return AUDIO_FORMAT_DTS_HD_MA;
+ case ENCODING_DTS_UHD_P2:
+ return AUDIO_FORMAT_DTS_UHD_P2;
default:
return AUDIO_FORMAT_INVALID;
}
@@ -186,9 +192,13 @@ static inline int audioFormatFromNative(audio_format_t nativeFormat)
case AUDIO_FORMAT_MPEGH_LC_L4:
return ENCODING_MPEGH_LC_L4;
case AUDIO_FORMAT_DTS_UHD:
- return ENCODING_DTS_UHD;
+ return ENCODING_DTS_UHD_P1;
case AUDIO_FORMAT_DRA:
return ENCODING_DRA;
+ case AUDIO_FORMAT_DTS_HD_MA:
+ return ENCODING_DTS_HD_MA;
+ case AUDIO_FORMAT_DTS_UHD_P2:
+ return ENCODING_DTS_UHD_P2;
case AUDIO_FORMAT_DEFAULT:
return ENCODING_DEFAULT;
default:
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index 01837f483f10..a7c7d0ba35bc 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -983,6 +983,10 @@ static void android_os_Binder_restoreCallingIdentity(jlong token)
IPCThreadState::self()->restoreCallingIdentity(token);
}
+static jboolean android_os_Binder_hasExplicitIdentity() {
+ return IPCThreadState::self()->hasExplicitIdentity();
+}
+
static void android_os_Binder_setThreadStrictModePolicy(jint policyMask)
{
IPCThreadState::self()->setStrictModePolicy(policyMask);
@@ -1079,6 +1083,8 @@ static const JNINativeMethod gBinderMethods[] = {
// @CriticalNative
{ "restoreCallingIdentity", "(J)V", (void*)android_os_Binder_restoreCallingIdentity },
// @CriticalNative
+ { "hasExplicitIdentity", "()Z", (void*)android_os_Binder_hasExplicitIdentity },
+ // @CriticalNative
{ "setThreadStrictModePolicy", "(I)V", (void*)android_os_Binder_setThreadStrictModePolicy },
// @CriticalNative
{ "getThreadStrictModePolicy", "()I", (void*)android_os_Binder_getThreadStrictModePolicy },
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index eaec58bee646..5a0a84b9a4ba 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -27,6 +27,7 @@
#include <android_runtime/AndroidRuntime.h>
#include <android_runtime/android_graphics_GraphicBuffer.h>
#include <android_runtime/android_hardware_HardwareBuffer.h>
+#include <android_runtime/android_hardware_OverlayProperties.h>
#include <android_runtime/android_view_Surface.h>
#include <android_runtime/android_view_SurfaceControl.h>
#include <android_runtime/android_view_SurfaceSession.h>
@@ -1346,6 +1347,15 @@ static jintArray nativeGetCompositionDataspaces(JNIEnv* env, jclass) {
return array;
}
+static jobject nativeGetOverlaySupport(JNIEnv* env, jclass) {
+ gui::OverlayProperties* overlayProperties = new gui::OverlayProperties;
+ if (SurfaceComposerClient::getOverlaySupport(overlayProperties) != NO_ERROR) {
+ delete overlayProperties;
+ return nullptr;
+ }
+ return android_hardware_OverlayProperties_convertToJavaObject(env, overlayProperties);
+}
+
static jboolean nativeSetActiveColorMode(JNIEnv* env, jclass,
jobject tokenObj, jint colorMode) {
sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
@@ -2025,6 +2035,8 @@ static const JNINativeMethod sSurfaceControlMethods[] = {
(void*)nativeSetGameContentType },
{"nativeGetCompositionDataspaces", "()[I",
(void*)nativeGetCompositionDataspaces},
+ {"nativeGetOverlaySupport", "()Landroid/hardware/OverlayProperties;",
+ (void*) nativeGetOverlaySupport},
{"nativeClearContentFrameStats", "(J)Z",
(void*)nativeClearContentFrameStats },
{"nativeGetContentFrameStats", "(JLandroid/view/WindowContentFrameStats;)Z",
diff --git a/core/jni/include/android_runtime/android_hardware_OverlayProperties.h b/core/jni/include/android_runtime/android_hardware_OverlayProperties.h
new file mode 100644
index 000000000000..372cca9456ab
--- /dev/null
+++ b/core/jni/include/android_runtime/android_hardware_OverlayProperties.h
@@ -0,0 +1,31 @@
+/**
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _ANDROID_HARDWARE_OVERLAYPROPERTIES_H
+#define _ANDROID_HARDWARE_OVERLAYPROPERTIES_H
+
+#include <android/gui/OverlayProperties.h>
+
+#include "jni.h"
+
+namespace android {
+
+extern jobject android_hardware_OverlayProperties_convertToJavaObject(
+ JNIEnv* env, gui::OverlayProperties* overlayProperties);
+
+}; // namespace android
+
+#endif // _ANDROID_HARDWARE_OVERLAYPROPERTIES_H
diff --git a/core/proto/android/content/intent.proto b/core/proto/android/content/intent.proto
index 26e7dbb8cc6f..75e29082508b 100644
--- a/core/proto/android/content/intent.proto
+++ b/core/proto/android/content/intent.proto
@@ -21,6 +21,7 @@ option java_multiple_files = true;
import "frameworks/base/core/proto/android/content/component_name.proto";
import "frameworks/base/core/proto/android/os/patternmatcher.proto";
+import "frameworks/base/core/proto/android/os/persistablebundle.proto";
import "frameworks/base/core/proto/android/privacy.proto";
// Next Tag: 14
@@ -87,6 +88,7 @@ message IntentFilterProto {
optional bool has_partial_types = 9;
optional bool get_auto_verify = 10;
repeated string mime_groups = 11;
+ optional android.os.PersistableBundleProto extras = 12;
}
message AuthorityEntryProto {
diff --git a/core/proto/android/server/windowmanagerservice.proto b/core/proto/android/server/windowmanagerservice.proto
index 537efc0f7ebc..82e1777ab7cb 100644
--- a/core/proto/android/server/windowmanagerservice.proto
+++ b/core/proto/android/server/windowmanagerservice.proto
@@ -54,6 +54,7 @@ message WindowManagerServiceDumpProto {
optional int32 focused_display_id = 9;
optional bool hard_keyboard_available = 10;
optional bool window_frames_valid = 11;
+ optional BackNavigationProto back_navigation = 12;
}
/* represents RootWindowContainer object */
@@ -595,3 +596,11 @@ message ImeInsetsSourceProviderProto {
optional WindowStateProto ime_target_from_ime = 2;
optional bool is_ime_layout_drawn = 3;
}
+
+message BackNavigationProto {
+ option (.android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ optional bool animation_in_progress = 1;
+ optional int32 last_back_type = 2;
+ optional bool show_wallpaper = 3;
+} \ No newline at end of file
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index ec43ae3b43cb..f14ffc8225e5 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -669,10 +669,6 @@
<protected-broadcast android:name="android.media.tv.action.WATCH_NEXT_PROGRAM_BROWSABLE_DISABLED" />
<protected-broadcast android:name="android.media.tv.action.CHANNEL_BROWSABLE_REQUESTED" />
- <!-- Time zone rules update intents fired by the system server -->
- <protected-broadcast android:name="com.android.intent.action.timezone.RULES_UPDATE_OPERATION" />
- <protected-broadcast android:name="com.android.intent.action.timezone.TRIGGER_RULES_UPDATE_CHECK" />
-
<!-- Made protected in P (was introduced in JB-MR2) -->
<protected-broadcast android:name="android.intent.action.GET_RESTRICTION_ENTRIES" />
<protected-broadcast android:name="android.telephony.euicc.action.OTA_STATUS_CHANGED" />
@@ -3781,7 +3777,8 @@
<!-- Allows an application to query the current time zone rules state
on device.
- @SystemApi @hide -->
+ @SystemApi @hide
+ @deprecated Vestigial permission declaration. No longer used. -->
<permission android:name="android.permission.QUERY_TIME_ZONE_RULES"
android:protectionLevel="signature|privileged" />
@@ -3790,17 +3787,11 @@
<p>An application requesting this permission is responsible for
verifying the source and integrity of the update before passing
it off to the installer components.
- @SystemApi @hide -->
+ @SystemApi @hide
+ @deprecated Vestigial permission declaration. No longer used. -->
<permission android:name="android.permission.UPDATE_TIME_ZONE_RULES"
android:protectionLevel="signature|privileged" />
- <!-- Must be required by a time zone rule updater application,
- to ensure that only the system can trigger it.
- @hide -->
- <permission android:name="android.permission.TRIGGER_TIME_ZONE_RULES_CHECK"
- android:protectionLevel="signature" />
- <uses-permission android:name="android.permission.TRIGGER_TIME_ZONE_RULES_CHECK"/>
-
<!-- Allows the system to reset throttling in shortcut manager.
@hide -->
<permission android:name="android.permission.RESET_SHORTCUT_MANAGER_THROTTLING"
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 7714082dcfc4..d0372eae2ae7 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -46,6 +46,9 @@
<!-- Displayed when the user dialed an MMI code whose function
could not be performed. This will be displayed in a toast. -->
<string name="mmiError">Connection problem or invalid MMI code.</string>
+ <!-- Displayed when the user dialed an MMI code whose function could not be performed because
+ the feature is not supported on the current mobile network. -->
+ <string name="mmiErrorNotSupported">Feature not supported.</string>
<!-- Displayed when the user dialed an MMI code whose function
could not be performed because FDN is enabled. This will be displayed in a toast. -->
<string name="mmiFdnError">Operation is restricted to fixed dialing numbers only.</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 1b74e4b3f099..691d48e19a0e 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -838,6 +838,7 @@
<java-symbol type="string" name="mismatchPin" />
<java-symbol type="string" name="mmiComplete" />
<java-symbol type="string" name="mmiError" />
+ <java-symbol type="string" name="mmiErrorNotSupported" />
<java-symbol type="string" name="mmiFdnError" />
<java-symbol type="string" name="mmiErrorWhileRoaming" />
<java-symbol type="string" name="month_day_year" />
diff --git a/core/tests/BroadcastRadioTests/src/android/hardware/radio/tests/unittests/RadioManagerTest.java b/core/tests/BroadcastRadioTests/src/android/hardware/radio/tests/unittests/RadioManagerTest.java
index 365b901beb61..44aa6d19cb0a 100644
--- a/core/tests/BroadcastRadioTests/src/android/hardware/radio/tests/unittests/RadioManagerTest.java
+++ b/core/tests/BroadcastRadioTests/src/android/hardware/radio/tests/unittests/RadioManagerTest.java
@@ -187,6 +187,20 @@ public final class RadioManagerTest {
}
@Test
+ public void writeToParcel_forBandDescriptor() {
+ Parcel parcel = Parcel.obtain();
+ RadioManager.BandDescriptor bandDescriptor = createFmBandDescriptor();
+
+ bandDescriptor.writeToParcel(parcel, /* flags= */ 0);
+ parcel.setDataPosition(0);
+
+ RadioManager.BandDescriptor bandDescriptorFromParcel =
+ RadioManager.BandDescriptor.CREATOR.createFromParcel(parcel);
+ assertWithMessage("Band Descriptor created from parcel")
+ .that(bandDescriptorFromParcel).isEqualTo(bandDescriptor);
+ }
+
+ @Test
public void newArray_forBandDescriptorCreator() {
RadioManager.BandDescriptor[] bandDescriptors =
RadioManager.BandDescriptor.CREATOR.newArray(CREATOR_ARRAY_SIZE);
@@ -421,6 +435,20 @@ public final class RadioManagerTest {
}
@Test
+ public void writeToParcel_forBandConfig() {
+ Parcel parcel = Parcel.obtain();
+ RadioManager.BandConfig bandConfig = createAmBandConfig();
+
+ bandConfig.writeToParcel(parcel, /* flags= */ 0);
+ parcel.setDataPosition(0);
+
+ RadioManager.BandConfig bandConfigFromParcel =
+ RadioManager.BandConfig.CREATOR.createFromParcel(parcel);
+ assertWithMessage("Band Config created from parcel")
+ .that(bandConfigFromParcel).isEqualTo(bandConfig);
+ }
+
+ @Test
public void newArray_forBandConfigCreator() {
RadioManager.BandConfig[] bandConfigs =
RadioManager.BandConfig.CREATOR.newArray(CREATOR_ARRAY_SIZE);
@@ -520,7 +548,9 @@ public final class RadioManagerTest {
@Test
public void equals_withSameFmBandConfigs_returnsTrue() {
- RadioManager.FmBandConfig fmBandConfigCompared = createFmBandConfig();
+ RadioManager.FmBandConfig.Builder builder =
+ new RadioManager.FmBandConfig.Builder(FM_BAND_CONFIG);
+ RadioManager.FmBandConfig fmBandConfigCompared = builder.build();
assertWithMessage("The same FM Band Config")
.that(FM_BAND_CONFIG).isEqualTo(fmBandConfigCompared);
@@ -545,7 +575,9 @@ public final class RadioManagerTest {
@Test
public void equals_withSameAmBandConfigs_returnsTrue() {
- RadioManager.AmBandConfig amBandConfigCompared = createAmBandConfig();
+ RadioManager.AmBandConfig.Builder builder =
+ new RadioManager.AmBandConfig.Builder(AM_BAND_CONFIG);
+ RadioManager.AmBandConfig amBandConfigCompared = builder.build();
assertWithMessage("The same AM Band Config")
.that(AM_BAND_CONFIG).isEqualTo(amBandConfigCompared);
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImplTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImplTest.java
index 635d1e792715..93214e5a6944 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImplTest.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImplTest.java
@@ -39,6 +39,7 @@ import android.os.ServiceManager;
import com.android.dx.mockito.inline.extended.StaticMockitoSessionBuilder;
import com.android.server.broadcastradio.ExtendedRadioMockitoTestCase;
+import com.android.server.broadcastradio.RadioServiceUserController;
import org.junit.Test;
import org.mockito.Mock;
@@ -81,7 +82,8 @@ public final class BroadcastRadioServiceImplTest extends ExtendedRadioMockitoTes
@Override
protected void initializeSession(StaticMockitoSessionBuilder builder) {
builder.spyStatic(ServiceManager.class)
- .spyStatic(RadioModule.class);
+ .spyStatic(RadioModule.class)
+ .spyStatic(RadioServiceUserController.class);
}
@Test
@@ -150,6 +152,7 @@ public final class BroadcastRadioServiceImplTest extends ExtendedRadioMockitoTes
}
private void createBroadcastRadioService() throws RemoteException {
+ doReturn(true).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
mockServiceManager();
mBroadcastRadioService = new BroadcastRadioServiceImpl(SERVICE_LIST);
}
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/TunerSessionTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/TunerSessionTest.java
index 3bf993c07aed..a29e9c5c9bb1 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/TunerSessionTest.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/TunerSessionTest.java
@@ -16,6 +16,8 @@
package com.android.server.broadcastradio.aidl;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
+
import static com.google.common.truth.Truth.assertWithMessage;
import static org.junit.Assert.assertThrows;
@@ -44,12 +46,14 @@ import android.os.ServiceSpecificException;
import android.util.ArrayMap;
import android.util.ArraySet;
+import com.android.dx.mockito.inline.extended.StaticMockitoSessionBuilder;
+import com.android.server.broadcastradio.ExtendedRadioMockitoTestCase;
+import com.android.server.broadcastradio.RadioServiceUserController;
+
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
-import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
import org.mockito.verification.VerificationWithTimeout;
import java.util.ArrayList;
@@ -59,8 +63,7 @@ import java.util.Map;
/**
* Tests for AIDL HAL TunerSession.
*/
-@RunWith(MockitoJUnitRunner.class)
-public final class TunerSessionTest {
+public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
private static final VerificationWithTimeout CALLBACK_TIMEOUT =
timeout(/* millis= */ 200);
@@ -91,8 +94,15 @@ public final class TunerSessionTest {
private TunerSession[] mTunerSessions;
+ @Override
+ protected void initializeSession(StaticMockitoSessionBuilder builder) {
+ builder.spyStatic(RadioServiceUserController.class);
+ }
+
@Before
public void setup() throws Exception {
+ doReturn(true).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
+
mRadioModule = new RadioModule(mBroadcastRadioMock,
AidlTestUtils.makeDefaultModuleProperties(), mLock);
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/BroadcastRadioServiceHidlTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/BroadcastRadioServiceHidlTest.java
index 4d0b753b0acc..99e70436ac95 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/BroadcastRadioServiceHidlTest.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/BroadcastRadioServiceHidlTest.java
@@ -43,6 +43,7 @@ import android.os.RemoteException;
import com.android.dx.mockito.inline.extended.StaticMockitoSessionBuilder;
import com.android.server.broadcastradio.ExtendedRadioMockitoTestCase;
+import com.android.server.broadcastradio.RadioServiceUserController;
import org.junit.Test;
import org.mockito.Mock;
@@ -92,7 +93,8 @@ public final class BroadcastRadioServiceHidlTest extends ExtendedRadioMockitoTes
@Override
protected void initializeSession(StaticMockitoSessionBuilder builder) {
- builder.spyStatic(RadioModule.class);
+ builder.spyStatic(RadioModule.class)
+ .spyStatic(RadioServiceUserController.class);
}
@Test
@@ -181,6 +183,8 @@ public final class BroadcastRadioServiceHidlTest extends ExtendedRadioMockitoTes
}
private void createBroadcastRadioService() throws RemoteException {
+ doReturn(true).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
+
mockServiceManager();
mBroadcastRadioService = new BroadcastRadioService(/* nextModuleId= */ FM_RADIO_MODULE_ID,
mLock, mServiceManagerMock);
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/ProgramInfoCacheTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/ProgramInfoCacheTest.java
index eadf226b01ce..ec55ddbe1a4a 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/ProgramInfoCacheTest.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/ProgramInfoCacheTest.java
@@ -25,6 +25,8 @@ import android.test.suitebuilder.annotation.MediumTest;
import androidx.test.runner.AndroidJUnit4;
+import com.android.server.broadcastradio.ExtendedRadioMockitoTestCase;
+
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -37,7 +39,7 @@ import java.util.Set;
*/
@RunWith(AndroidJUnit4.class)
@MediumTest
-public class ProgramInfoCacheTest {
+public class ProgramInfoCacheTest extends ExtendedRadioMockitoTestCase {
private static final String TAG = "BroadcastRadioTests.ProgramInfoCache";
private final ProgramSelector.Identifier mAmFmIdentifier =
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/StartProgramListUpdatesFanoutTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/StartProgramListUpdatesFanoutTest.java
index d1043595535a..e3c9faa601e7 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/StartProgramListUpdatesFanoutTest.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/StartProgramListUpdatesFanoutTest.java
@@ -15,6 +15,8 @@
*/
package com.android.server.broadcastradio.hal2;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
+
import static org.junit.Assert.*;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.doAnswer;
@@ -34,15 +36,14 @@ import android.hardware.radio.ProgramList;
import android.hardware.radio.ProgramSelector;
import android.hardware.radio.RadioManager;
import android.os.RemoteException;
-import android.test.suitebuilder.annotation.MediumTest;
-import androidx.test.runner.AndroidJUnit4;
+import com.android.dx.mockito.inline.extended.StaticMockitoSessionBuilder;
+import com.android.server.broadcastradio.ExtendedRadioMockitoTestCase;
+import com.android.server.broadcastradio.RadioServiceUserController;
import org.junit.Before;
import org.junit.Test;
-import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
import org.mockito.stubbing.Answer;
import org.mockito.verification.VerificationWithTimeout;
@@ -53,9 +54,7 @@ import java.util.List;
/**
* Tests for v2 HAL RadioModule.
*/
-@RunWith(AndroidJUnit4.class)
-@MediumTest
-public class StartProgramListUpdatesFanoutTest {
+public class StartProgramListUpdatesFanoutTest extends ExtendedRadioMockitoTestCase {
private static final String TAG = "BroadcastRadioTests.hal2.StartProgramListUpdatesFanout";
private static final VerificationWithTimeout CB_TIMEOUT = timeout(500);
@@ -91,9 +90,14 @@ public class StartProgramListUpdatesFanoutTest {
private final RadioManager.ProgramInfo mDabEnsembleInfo = TestUtils.makeProgramInfo(
ProgramSelector.PROGRAM_TYPE_DAB, mDabEnsembleIdentifier, 0);
+ @Override
+ protected void initializeSession(StaticMockitoSessionBuilder builder) {
+ builder.spyStatic(RadioServiceUserController.class);
+ }
+
@Before
public void setup() throws RemoteException {
- MockitoAnnotations.initMocks(this);
+ doReturn(true).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
mRadioModule = new RadioModule(mBroadcastRadioMock,
TestUtils.makeDefaultModuleProperties(), mLock);
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/TunerSessionHidlTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/TunerSessionHidlTest.java
index 936e606fcb76..8884053bb58c 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/TunerSessionHidlTest.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/TunerSessionHidlTest.java
@@ -16,6 +16,8 @@
package com.android.server.broadcastradio.hal2;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
+
import static com.google.common.truth.Truth.assertWithMessage;
import static org.junit.Assert.assertThrows;
@@ -45,6 +47,10 @@ import android.hardware.radio.RadioTuner;
import android.util.ArrayMap;
import android.util.ArraySet;
+import com.android.dx.mockito.inline.extended.StaticMockitoSessionBuilder;
+import com.android.server.broadcastradio.ExtendedRadioMockitoTestCase;
+import com.android.server.broadcastradio.RadioServiceUserController;
+
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -61,7 +67,7 @@ import java.util.Map;
* Tests for HIDL HAL TunerSession.
*/
@RunWith(MockitoJUnitRunner.class)
-public final class TunerSessionHidlTest {
+public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase {
private static final VerificationWithTimeout CALLBACK_TIMEOUT =
timeout(/* millis= */ 200);
@@ -88,8 +94,15 @@ public final class TunerSessionHidlTest {
@Mock ITunerSession mHalTunerSessionMock;
private android.hardware.radio.ITunerCallback[] mAidlTunerCallbackMocks;
+ @Override
+ protected void initializeSession(StaticMockitoSessionBuilder builder) {
+ builder.spyStatic(RadioServiceUserController.class);
+ }
+
@Before
public void setup() throws Exception {
+ doReturn(true).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
+
mRadioModule = new RadioModule(mBroadcastRadioMock,
TestUtils.makeDefaultModuleProperties(), mLock);
diff --git a/core/tests/GameManagerTests/src/android/app/GameManagerTests.java b/core/tests/GameManagerTests/src/android/app/GameManagerTests.java
index baecc8c4650e..fac3a0ecdec2 100644
--- a/core/tests/GameManagerTests/src/android/app/GameManagerTests.java
+++ b/core/tests/GameManagerTests/src/android/app/GameManagerTests.java
@@ -19,6 +19,8 @@ package android.app;
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertNull;
import android.content.Context;
import android.platform.test.annotations.Presubmit;
@@ -48,34 +50,60 @@ public final class GameManagerTests {
mPackageName = mContext.getPackageName();
// Reset the Game Mode for the test app, since it persists across invocations.
- mGameManager.setGameMode(mPackageName, GameManager.GAME_MODE_UNSUPPORTED);
+ mGameManager.setGameMode(mPackageName, GameManager.GAME_MODE_STANDARD);
}
@Test
public void testPublicApiGameModeGetterSetter() {
- assertEquals(GameManager.GAME_MODE_UNSUPPORTED,
- mGameManager.getGameMode());
-
- mGameManager.setGameMode(mPackageName, GameManager.GAME_MODE_STANDARD);
assertEquals(GameManager.GAME_MODE_STANDARD,
mGameManager.getGameMode());
mGameManager.setGameMode(mPackageName, GameManager.GAME_MODE_PERFORMANCE);
assertEquals(GameManager.GAME_MODE_PERFORMANCE,
mGameManager.getGameMode());
+
+ mGameManager.setGameMode(mPackageName, GameManager.GAME_MODE_CUSTOM);
+ assertEquals(GameManager.GAME_MODE_CUSTOM,
+ mGameManager.getGameMode());
}
@Test
public void testPrivilegedGameModeGetterSetter() {
- assertEquals(GameManager.GAME_MODE_UNSUPPORTED,
- mGameManager.getGameMode(mPackageName));
-
- mGameManager.setGameMode(mPackageName, GameManager.GAME_MODE_STANDARD);
assertEquals(GameManager.GAME_MODE_STANDARD,
mGameManager.getGameMode(mPackageName));
mGameManager.setGameMode(mPackageName, GameManager.GAME_MODE_PERFORMANCE);
assertEquals(GameManager.GAME_MODE_PERFORMANCE,
mGameManager.getGameMode(mPackageName));
+
+ mGameManager.setGameMode(mPackageName, GameManager.GAME_MODE_CUSTOM);
+ assertEquals(GameManager.GAME_MODE_CUSTOM,
+ mGameManager.getGameMode(mPackageName));
+ }
+
+ @Test
+ public void testUpdateCustomGameModeConfiguration() {
+ GameModeInfo gameModeInfo = mGameManager.getGameModeInfo(mPackageName);
+ assertNotNull(gameModeInfo);
+ assertNull(gameModeInfo.getGameModeConfiguration(GameManager.GAME_MODE_CUSTOM));
+ GameModeConfiguration unsupportedFpsConfig =
+ new GameModeConfiguration.Builder().setFpsOverride(
+ 70).setScalingFactor(0.5f).build();
+ mGameManager.updateCustomGameModeConfiguration(mPackageName, unsupportedFpsConfig);
+ gameModeInfo = mGameManager.getGameModeInfo(mPackageName);
+ assertNotNull(gameModeInfo);
+ // TODO(b/243448953): update to non-zero FPS when matching is implemented
+ assertEquals(new GameModeConfiguration.Builder().setFpsOverride(
+ GameModeConfiguration.FPS_OVERRIDE_NONE).setScalingFactor(0.5f).build(),
+ gameModeInfo.getGameModeConfiguration(GameManager.GAME_MODE_CUSTOM));
+
+ GameModeConfiguration supportedFpsConfig =
+ new GameModeConfiguration.Builder().setFpsOverride(
+ 60).setScalingFactor(0.5f).build();
+ mGameManager.updateCustomGameModeConfiguration(mPackageName, supportedFpsConfig);
+ gameModeInfo = mGameManager.getGameModeInfo(mPackageName);
+ assertNotNull(gameModeInfo);
+ assertEquals(supportedFpsConfig,
+ gameModeInfo.getGameModeConfiguration(GameManager.GAME_MODE_CUSTOM));
}
}
diff --git a/core/tests/GameManagerTests/src/android/app/GameModeConfigurationTest.java b/core/tests/GameManagerTests/src/android/app/GameModeConfigurationTest.java
new file mode 100644
index 000000000000..7462bcf67480
--- /dev/null
+++ b/core/tests/GameManagerTests/src/android/app/GameModeConfigurationTest.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app;
+
+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 android.platform.test.annotations.Presubmit;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class GameModeConfigurationTest {
+ @Test
+ public void testEqualsAndHashCode() {
+ GameModeConfiguration config = new GameModeConfiguration.Builder()
+ .setScalingFactor(0.5f).setFpsOverride(10).build();
+ assertTrue(config.equals(config));
+
+ GameModeConfiguration config1 = new GameModeConfiguration.Builder()
+ .setScalingFactor(0.5f).setFpsOverride(10).build();
+ assertTrue(config.equals(config1));
+ assertEquals(config.hashCode(), config1.hashCode());
+
+ GameModeConfiguration config2 = new GameModeConfiguration.Builder()
+ .setScalingFactor(0.5f).build();
+ assertFalse(config.equals(config2));
+ assertNotEquals(config.hashCode(), config2.hashCode());
+
+ GameModeConfiguration config3 = new GameModeConfiguration.Builder()
+ .setFpsOverride(10).build();
+ assertFalse(config.equals(config3));
+ assertNotEquals(config.hashCode(), config3.hashCode());
+ assertFalse(config2.equals(config3));
+ assertNotEquals(config2.hashCode(), config3.hashCode());
+
+ GameModeConfiguration config4 = new GameModeConfiguration.Builder()
+ .setScalingFactor(0.2f).setFpsOverride(10).build();
+ assertFalse(config.equals(config4));
+ assertNotEquals(config.hashCode(), config4.hashCode());
+
+ GameModeConfiguration config5 = new GameModeConfiguration.Builder()
+ .setScalingFactor(0.5f).setFpsOverride(30).build();
+ assertFalse(config.equals(config5));
+ assertNotEquals(config.hashCode(), config5.hashCode());
+
+ GameModeConfiguration config6 = new GameModeConfiguration.Builder()
+ .build();
+ assertFalse(config.equals(config6));
+ assertNotEquals(config.hashCode(), config6.hashCode());
+ assertFalse(config2.equals(config6));
+ assertNotEquals(config2.hashCode(), config6.hashCode());
+ assertFalse(config3.equals(config6));
+ assertNotEquals(config3.hashCode(), config6.hashCode());
+ }
+
+ @Test
+ public void testToBuilder() {
+ GameModeConfiguration config = new GameModeConfiguration
+ .Builder().setFpsOverride(40).setScalingFactor(0.5f).build();
+ GameModeConfiguration newConfig = config.toBuilder().build();
+ assertEquals(config, newConfig);
+ }
+
+ @Test
+ public void testGetters() {
+ GameModeConfiguration config = new GameModeConfiguration.Builder()
+ .setScalingFactor(0.5f).setFpsOverride(10).build();
+ assertEquals(0.5f, config.getScalingFactor(), 0.01f);
+ assertEquals(10, config.getFpsOverride());
+ }
+}
diff --git a/core/tests/GameManagerTests/src/android/app/GameModeInfoTest.java b/core/tests/GameManagerTests/src/android/app/GameModeInfoTest.java
new file mode 100644
index 000000000000..ecd9b6b8143a
--- /dev/null
+++ b/core/tests/GameManagerTests/src/android/app/GameModeInfoTest.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app;
+
+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 android.os.Parcel;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Unit tests for {@link android.app.GameModeInfo}.
+ */
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class GameModeInfoTest {
+ @Test
+ public void testParcelable() {
+ int activeGameMode = GameManager.GAME_MODE_PERFORMANCE;
+ int[] availableGameModes =
+ new int[]{GameManager.GAME_MODE_STANDARD, GameManager.GAME_MODE_PERFORMANCE,
+ GameManager.GAME_MODE_BATTERY, GameManager.GAME_MODE_CUSTOM};
+ int[] optedInGameModes = new int[]{GameManager.GAME_MODE_PERFORMANCE};
+ GameModeConfiguration batteryConfig = new GameModeConfiguration
+ .Builder().setFpsOverride(40).setScalingFactor(0.5f).build();
+ GameModeConfiguration performanceConfig = new GameModeConfiguration
+ .Builder().setFpsOverride(90).setScalingFactor(0.9f).build();
+ GameModeInfo gameModeInfo = new GameModeInfo.Builder()
+ .setActiveGameMode(activeGameMode)
+ .setAvailableGameModes(availableGameModes)
+ .setOptedInGameModes(optedInGameModes)
+ .setDownscalingAllowed(true)
+ .setFpsOverrideAllowed(false)
+ .setGameModeConfiguration(GameManager.GAME_MODE_BATTERY, batteryConfig)
+ .setGameModeConfiguration(GameManager.GAME_MODE_PERFORMANCE, performanceConfig)
+ .build();
+
+ assertArrayEquals(availableGameModes, gameModeInfo.getAvailableGameModes());
+ assertArrayEquals(optedInGameModes, gameModeInfo.getOptedInGameModes());
+ assertEquals(activeGameMode, gameModeInfo.getActiveGameMode());
+ assertTrue(gameModeInfo.isDownscalingAllowed());
+ assertFalse(gameModeInfo.isFpsOverrideAllowed());
+ assertEquals(performanceConfig,
+ gameModeInfo.getGameModeConfiguration(GameManager.GAME_MODE_PERFORMANCE));
+ assertEquals(batteryConfig,
+ gameModeInfo.getGameModeConfiguration(GameManager.GAME_MODE_BATTERY));
+
+ Parcel parcel = Parcel.obtain();
+ gameModeInfo.writeToParcel(parcel, 0);
+ parcel.setDataPosition(0);
+ GameModeInfo newGameModeInfo = new GameModeInfo(parcel);
+ assertEquals(gameModeInfo.getActiveGameMode(), newGameModeInfo.getActiveGameMode());
+ assertArrayEquals(gameModeInfo.getAvailableGameModes(),
+ newGameModeInfo.getAvailableGameModes());
+ assertArrayEquals(gameModeInfo.getOptedInGameModes(),
+ newGameModeInfo.getOptedInGameModes());
+ assertTrue(newGameModeInfo.isDownscalingAllowed());
+ assertFalse(newGameModeInfo.isFpsOverrideAllowed());
+ assertEquals(performanceConfig,
+ newGameModeInfo.getGameModeConfiguration(GameManager.GAME_MODE_PERFORMANCE));
+ assertEquals(batteryConfig,
+ newGameModeInfo.getGameModeConfiguration(GameManager.GAME_MODE_BATTERY));
+ }
+}
diff --git a/core/tests/coretests/src/android/app/timezone/DistroFormatVersionTest.java b/core/tests/coretests/src/android/app/timezone/DistroFormatVersionTest.java
deleted file mode 100644
index 0efc0ab89a73..000000000000
--- a/core/tests/coretests/src/android/app/timezone/DistroFormatVersionTest.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.app.timezone;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import android.os.Parcel;
-
-import androidx.test.filters.LargeTest;
-
-import org.junit.Test;
-
-/**
- * Tests for {@link DistroFormatVersion}.
- */
-@LargeTest
-public class DistroFormatVersionTest {
-
- @Test
- public void equalsAndHashCode() {
- DistroFormatVersion one = new DistroFormatVersion(1, 2);
- assertEqualsContract(one, one);
-
- DistroFormatVersion two = new DistroFormatVersion(1, 2);
- assertEqualsContract(one, two);
-
- DistroFormatVersion three = new DistroFormatVersion(2, 1);
- assertFalse(one.equals(three));
- }
-
- @Test
- public void parcelable() {
- DistroFormatVersion version = new DistroFormatVersion(2, 3);
-
- Parcel parcel = Parcel.obtain();
- version.writeToParcel(parcel, 0 /* flags */);
- parcel.setDataPosition(0);
-
- DistroFormatVersion newVersion = DistroFormatVersion.CREATOR.createFromParcel(parcel);
-
- assertEquals(version, newVersion);
- }
-
- @Test
- public void supportsVersion() {
- DistroFormatVersion deviceVersion = new DistroFormatVersion(2, 2);
- assertTrue(deviceVersion.supports(deviceVersion));
-
- DistroFormatVersion sameVersion = new DistroFormatVersion(2, 2);
- assertTrue(deviceVersion.supports(sameVersion));
-
- // Minor versions are backwards compatible.
- DistroFormatVersion sameMajorNewerMinor = new DistroFormatVersion(2, 3);
- assertTrue(deviceVersion.supports(sameMajorNewerMinor));
- DistroFormatVersion sameMajorOlderMinor = new DistroFormatVersion(2, 1);
- assertFalse(deviceVersion.supports(sameMajorOlderMinor));
-
- // Major versions are not backwards compatible.
- DistroFormatVersion newerMajor = new DistroFormatVersion(1, 2);
- assertFalse(deviceVersion.supports(newerMajor));
- DistroFormatVersion olderMajor = new DistroFormatVersion(3, 2);
- assertFalse(deviceVersion.supports(olderMajor));
- }
-
- private static void assertEqualsContract(DistroFormatVersion one, DistroFormatVersion two) {
- assertEquals(one, two);
- assertEquals(one.hashCode(), two.hashCode());
- }
-}
diff --git a/core/tests/coretests/src/android/app/timezone/DistroRulesVersionTest.java b/core/tests/coretests/src/android/app/timezone/DistroRulesVersionTest.java
deleted file mode 100644
index b519bf8b13f7..000000000000
--- a/core/tests/coretests/src/android/app/timezone/DistroRulesVersionTest.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.app.timezone;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import android.os.Parcel;
-
-import androidx.test.filters.LargeTest;
-
-import org.junit.Test;
-
-/**
- * Tests for {@link DistroRulesVersion}.
- */
-@LargeTest
-public class DistroRulesVersionTest {
-
- @Test
- public void equalsAndHashCode() {
- DistroRulesVersion one = new DistroRulesVersion("2016a", 2);
- assertEqualsContract(one, one);
-
- DistroRulesVersion two = new DistroRulesVersion("2016a", 2);
- assertEqualsContract(one, two);
-
- DistroRulesVersion three = new DistroRulesVersion("2016b", 1);
- assertFalse(one.equals(three));
- }
-
- @Test
- public void parcelable() {
- DistroRulesVersion version = new DistroRulesVersion("2016a", 2);
-
- Parcel parcel = Parcel.obtain();
- version.writeToParcel(parcel, 0 /* flags */);
- parcel.setDataPosition(0);
-
- DistroRulesVersion newVersion = DistroRulesVersion.CREATOR.createFromParcel(parcel);
-
- assertEquals(version, newVersion);
- }
-
- @Test
- public void isOlderThan() {
- DistroRulesVersion deviceVersion = new DistroRulesVersion("2016b", 2);
- assertFalse(deviceVersion.isOlderThan(deviceVersion));
-
- DistroRulesVersion sameVersion = new DistroRulesVersion("2016b", 2);
- assertFalse(deviceVersion.isOlderThan(sameVersion));
-
- DistroRulesVersion sameRulesNewerRevision = new DistroRulesVersion("2016b", 3);
- assertTrue(deviceVersion.isOlderThan(sameRulesNewerRevision));
-
- DistroRulesVersion sameRulesOlderRevision = new DistroRulesVersion("2016b", 1);
- assertFalse(deviceVersion.isOlderThan(sameRulesOlderRevision));
-
- DistroRulesVersion newerRules = new DistroRulesVersion("2016c", 2);
- assertTrue(deviceVersion.isOlderThan(newerRules));
-
- DistroRulesVersion olderRules = new DistroRulesVersion("2016a", 2);
- assertFalse(deviceVersion.isOlderThan(olderRules));
- }
-
- private static void assertEqualsContract(DistroRulesVersion one, DistroRulesVersion two) {
- assertEquals(one, two);
- assertEquals(one.hashCode(), two.hashCode());
- }
-}
diff --git a/core/tests/coretests/src/android/app/timezone/OWNERS b/core/tests/coretests/src/android/app/timezone/OWNERS
deleted file mode 100644
index 381ecf1abda5..000000000000
--- a/core/tests/coretests/src/android/app/timezone/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 24949
-include /core/java/android/app/timezone/OWNERS
diff --git a/core/tests/coretests/src/android/app/timezone/RulesStateTest.java b/core/tests/coretests/src/android/app/timezone/RulesStateTest.java
deleted file mode 100644
index 30cc7ffc5366..000000000000
--- a/core/tests/coretests/src/android/app/timezone/RulesStateTest.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.app.timezone;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import android.os.Parcel;
-
-import androidx.test.filters.LargeTest;
-
-import org.junit.Test;
-
-/**
- * Tests for {@link RulesState}.
- */
-@LargeTest
-public class RulesStateTest {
-
- @Test
- public void equalsAndHashCode() {
- RulesState one = new RulesState(
- "2016a", formatVersion(1, 2), false /* operationInProgress */,
- RulesState.STAGED_OPERATION_INSTALL, rulesVersion("2016a", 3),
- RulesState.DISTRO_STATUS_INSTALLED, rulesVersion("2016b", 2));
- assertEqualsContract(one, one);
-
- RulesState two = new RulesState(
- "2016a", formatVersion(1, 2), false /* operationInProgress */,
- RulesState.STAGED_OPERATION_INSTALL, rulesVersion("2016a", 3),
- RulesState.DISTRO_STATUS_INSTALLED, rulesVersion("2016b", 2));
- assertEqualsContract(one, two);
-
- RulesState differentBaseRules = new RulesState(
- "2016b", formatVersion(1, 2), false /* operationInProgress */,
- RulesState.STAGED_OPERATION_INSTALL, rulesVersion("2016a", 3),
- RulesState.DISTRO_STATUS_INSTALLED, rulesVersion("2016b", 2));
- assertFalse(one.equals(differentBaseRules));
-
- RulesState differentFormatVersion = new RulesState(
- "2016a", formatVersion(1, 1), false /* operationInProgress */,
- RulesState.STAGED_OPERATION_INSTALL, rulesVersion("2016a", 3),
- RulesState.DISTRO_STATUS_INSTALLED, rulesVersion("2016b", 2));
- assertFalse(one.equals(differentFormatVersion));
-
- RulesState differentOperationInProgress = new RulesState(
- "2016a", formatVersion(1, 1), true /* operationInProgress */,
- RulesState.STAGED_OPERATION_UNKNOWN, null /* stagedDistroRulesVersion */,
- RulesState.DISTRO_STATUS_UNKNOWN, null /* installedDistroRulesVersion */);
- assertFalse(one.equals(differentOperationInProgress));
-
- RulesState differentStagedOperation = new RulesState(
- "2016a", formatVersion(1, 1), false /* operationInProgress */,
- RulesState.STAGED_OPERATION_UNINSTALL, null /* stagedDistroRulesVersion */,
- RulesState.DISTRO_STATUS_INSTALLED, rulesVersion("2016b", 2));
- assertFalse(one.equals(differentStagedOperation));
-
- RulesState differentStagedInstallVersion = new RulesState(
- "2016a", formatVersion(1, 1), false /* operationInProgress */,
- RulesState.STAGED_OPERATION_INSTALL, rulesVersion("2016a", 4),
- RulesState.DISTRO_STATUS_INSTALLED, rulesVersion("2016b", 2));
- assertFalse(one.equals(differentStagedInstallVersion));
-
- RulesState differentInstalled = new RulesState(
- "2016a", formatVersion(1, 1), false /* operationInProgress */,
- RulesState.STAGED_OPERATION_INSTALL, rulesVersion("2016a", 3),
- RulesState.DISTRO_STATUS_NONE, null /* installedDistroRulesVersion */);
- assertFalse(one.equals(differentInstalled));
-
- RulesState differentInstalledVersion = new RulesState(
- "2016a", formatVersion(1, 1), false /* operationInProgress */,
- RulesState.STAGED_OPERATION_INSTALL, rulesVersion("2016a", 3),
- RulesState.DISTRO_STATUS_INSTALLED, rulesVersion("2016b", 3));
- assertFalse(one.equals(differentInstalledVersion));
- }
-
- @Test
- public void parcelable() {
- RulesState rulesState1 = new RulesState(
- "2016a", formatVersion(1, 1), false /* operationInProgress */,
- RulesState.STAGED_OPERATION_INSTALL, rulesVersion("2016b", 2),
- RulesState.DISTRO_STATUS_INSTALLED, rulesVersion("2016b", 3));
- checkParcelableRoundTrip(rulesState1);
-
- RulesState rulesStateWithNulls = new RulesState(
- "2016a", formatVersion(1, 1), false /* operationInProgress */,
- RulesState.STAGED_OPERATION_NONE, null /* stagedDistroRulesVersion */,
- RulesState.DISTRO_STATUS_NONE, null /* installedDistroRulesVersion */);
- checkParcelableRoundTrip(rulesStateWithNulls);
-
- RulesState rulesStateWithUnknowns = new RulesState(
- "2016a", formatVersion(1, 1), true /* operationInProgress */,
- RulesState.STAGED_OPERATION_UNKNOWN, null /* stagedDistroRulesVersion */,
- RulesState.DISTRO_STATUS_UNKNOWN, null /* installedDistroRulesVersion */);
- checkParcelableRoundTrip(rulesStateWithUnknowns);
- }
-
- private static void checkParcelableRoundTrip(RulesState rulesState) {
- Parcel parcel = Parcel.obtain();
- rulesState.writeToParcel(parcel, 0 /* flags */);
- parcel.setDataPosition(0);
-
- RulesState newVersion = RulesState.CREATOR.createFromParcel(parcel);
-
- assertEquals(rulesState, newVersion);
- }
-
- @Test
- public void isBaseVersionNewerThan() {
- RulesState rulesState = new RulesState(
- "2016b", formatVersion(1, 1), false /* operationInProgress */,
- RulesState.STAGED_OPERATION_NONE, null /* stagedDistroRulesVersion */,
- RulesState.DISTRO_STATUS_INSTALLED, rulesVersion("2016b", 3));
- assertTrue(rulesState.isBaseVersionNewerThan(rulesVersion("2016a", 1)));
- assertFalse(rulesState.isBaseVersionNewerThan(rulesVersion("2016b", 1)));
- assertFalse(rulesState.isBaseVersionNewerThan(rulesVersion("2016c", 1)));
- }
-
- private static void assertEqualsContract(RulesState one, RulesState two) {
- assertEquals(one, two);
- assertEquals(one.hashCode(), two.hashCode());
- }
-
- private static DistroRulesVersion rulesVersion(String rulesVersion, int revision) {
- return new DistroRulesVersion(rulesVersion, revision);
- }
-
- private static DistroFormatVersion formatVersion(int majorVersion, int minorVersion) {
- return new DistroFormatVersion(majorVersion, minorVersion);
- }
-}
diff --git a/core/tests/coretests/src/android/app/timezone/RulesUpdaterContractTest.java b/core/tests/coretests/src/android/app/timezone/RulesUpdaterContractTest.java
deleted file mode 100644
index df9ddea53c91..000000000000
--- a/core/tests/coretests/src/android/app/timezone/RulesUpdaterContractTest.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.app.timezone;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.hamcrest.MockitoHamcrest.argThat;
-
-import android.content.Context;
-import android.content.Intent;
-import android.os.UserHandle;
-
-import androidx.test.filters.LargeTest;
-
-import org.hamcrest.BaseMatcher;
-import org.hamcrest.Description;
-import org.hamcrest.Matcher;
-import org.junit.Test;
-
-/**
- * Tests for {@link RulesUpdaterContract}.
- */
-@LargeTest
-public class RulesUpdaterContractTest {
-
- @Test
- public void createUpdaterIntent() throws Exception {
- String packageName = "foobar";
- Intent intent = RulesUpdaterContract.createUpdaterIntent(packageName);
-
- assertEquals(RulesUpdaterContract.ACTION_TRIGGER_RULES_UPDATE_CHECK, intent.getAction());
- assertEquals(packageName, intent.getPackage());
- assertEquals(Intent.FLAG_INCLUDE_STOPPED_PACKAGES, intent.getFlags());
- }
-
- @Test
- public void sendBroadcast() throws Exception {
- String packageName = "foobar";
- byte[] tokenBytes = new byte[] { 1, 2, 3, 4, 5 };
-
- Intent expectedIntent = RulesUpdaterContract.createUpdaterIntent(packageName);
- expectedIntent.putExtra(RulesUpdaterContract.EXTRA_CHECK_TOKEN, tokenBytes);
-
- Context mockContext = mock(Context.class);
-
- RulesUpdaterContract.sendBroadcast(mockContext, packageName, tokenBytes);
-
- verify(mockContext).sendBroadcastAsUser(
- filterEquals(expectedIntent),
- eq(UserHandle.SYSTEM),
- eq(RulesUpdaterContract.UPDATE_TIME_ZONE_RULES_PERMISSION));
- }
-
- /**
- * Registers a mockito parameter matcher that uses {@link Intent#filterEquals(Intent)}. to
- * check the parameter against the intent supplied.
- */
- private static Intent filterEquals(final Intent expected) {
- final Matcher<Intent> m = new BaseMatcher<Intent>() {
- @Override
- public boolean matches(Object actual) {
- return actual != null && expected.filterEquals((Intent) actual);
- }
- @Override
- public void describeTo(Description description) {
- description.appendText(expected.toString());
- }
- };
- return argThat(m);
- }
-}
diff --git a/core/tests/coretests/src/android/hardware/input/VirtualTouchEventTest.java b/core/tests/coretests/src/android/hardware/input/VirtualTouchEventTest.java
index 3f504a00773c..100aba5ab362 100644
--- a/core/tests/coretests/src/android/hardware/input/VirtualTouchEventTest.java
+++ b/core/tests/coretests/src/android/hardware/input/VirtualTouchEventTest.java
@@ -136,6 +136,12 @@ public class VirtualTouchEventTest {
.build());
}
+ /**
+ * The combination of TOOL_TYPE_PALM with anything else than ACTION_CANCEL should throw an
+ * exception. This is due to an underlying implementation detail. See documentation of {@link
+ * VirtualTouchEvent}
+ * for details.
+ */
@Test
public void touchEvent_palmUsedImproperly() {
assertThrows(IllegalArgumentException.class, () -> new VirtualTouchEvent.Builder()
diff --git a/core/tests/coretests/src/android/os/BinderTest.java b/core/tests/coretests/src/android/os/BinderTest.java
index 99dbe6445662..02f87901318d 100644
--- a/core/tests/coretests/src/android/os/BinderTest.java
+++ b/core/tests/coretests/src/android/os/BinderTest.java
@@ -20,6 +20,8 @@ import androidx.test.filters.SmallTest;
import junit.framework.TestCase;
+import static org.testng.Assert.assertThrows;
+
public class BinderTest extends TestCase {
private static final int UID = 100;
@@ -45,12 +47,8 @@ public class BinderTest extends TestCase {
}
@SmallTest
- public void testGetCallingUidOrThrow() throws Exception {
- try {
- Binder.getCallingUidOrThrow();
- throw new AssertionError("IllegalStateException expected");
- } catch (IllegalStateException expected) {
- }
+ public void testGetCallingUidOrThrow_throws() throws Exception {
+ assertThrows(IllegalStateException.class, () -> Binder.getCallingUidOrThrow());
}
@SmallTest
diff --git a/core/tests/coretests/src/android/view/accessibility/AccessibilityNodeInfoTest.java b/core/tests/coretests/src/android/view/accessibility/AccessibilityNodeInfoTest.java
index cc02bbb3e7d1..248420f16b80 100644
--- a/core/tests/coretests/src/android/view/accessibility/AccessibilityNodeInfoTest.java
+++ b/core/tests/coretests/src/android/view/accessibility/AccessibilityNodeInfoTest.java
@@ -58,7 +58,7 @@ public class AccessibilityNodeInfoTest {
// The number of flags held in boolean properties. Their values should also be double-checked
// in the methods above.
- private static final int NUM_BOOLEAN_PROPERTIES = 24;
+ private static final int NUM_BOOLEAN_PROPERTIES = 25;
@Test
public void testStandardActions_serializationFlagIsValid() {
diff --git a/data/etc/Android.bp b/data/etc/Android.bp
index df51871c57d9..d0c3e5f6a91e 100644
--- a/data/etc/Android.bp
+++ b/data/etc/Android.bp
@@ -171,12 +171,6 @@ prebuilt_etc {
filename_from_src: true,
}
-prebuilt_etc {
- name: "com.android.timezone.updater.xml",
- sub_dir: "permissions",
- src: "com.android.timezone.updater.xml",
-}
-
filegroup {
name: "services.core.protolog.json",
srcs: ["services.core.protolog.json"],
diff --git a/graphics/java/android/graphics/HardwareRenderer.java b/graphics/java/android/graphics/HardwareRenderer.java
index a7fb7428bc98..c7c97e0b82b9 100644
--- a/graphics/java/android/graphics/HardwareRenderer.java
+++ b/graphics/java/android/graphics/HardwareRenderer.java
@@ -25,6 +25,7 @@ import android.app.ActivityManager;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
+import android.hardware.OverlayProperties;
import android.hardware.display.DisplayManager;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
@@ -1330,6 +1331,9 @@ public class HardwareRenderer {
// memory policy in play will interpret these values differently.
int largestWidth = activeMode.getPhysicalWidth();
int largestHeight = activeMode.getPhysicalHeight();
+ final OverlayProperties overlayProperties = defaultDisplay.getOverlaySupport();
+ boolean supportFp16ForHdr = overlayProperties != null
+ ? overlayProperties.supportFp16ForHdr() : false;
for (int i = 0; i < allDisplays.length; i++) {
final Display display = allDisplays[i];
@@ -1357,7 +1361,7 @@ public class HardwareRenderer {
nInitDisplayInfo(largestWidth, largestHeight, defaultDisplay.getRefreshRate(),
wideColorDataspace, defaultDisplay.getAppVsyncOffsetNanos(),
defaultDisplay.getPresentationDeadlineNanos(),
- defaultDisplay.getOverlaySupport().supportFp16ForHdr());
+ supportFp16ForHdr);
mDisplayInitialized = true;
}
diff --git a/libs/WindowManager/Shell/res/values/strings.xml b/libs/WindowManager/Shell/res/values/strings.xml
index 097a567c6b43..9490ddc73488 100644
--- a/libs/WindowManager/Shell/res/values/strings.xml
+++ b/libs/WindowManager/Shell/res/values/strings.xml
@@ -69,8 +69,10 @@
<!-- Multi-Window strings -->
<!-- Text that gets shown on top of current activity to inform the user that the system force-resized the current activity to be displayed in split-screen and that things might crash/not work properly [CHAR LIMIT=NONE] -->
<string name="dock_forced_resizable">App may not work with split-screen.</string>
- <!-- Warning message when we try to dock a non-resizeable task and launch it in fullscreen instead. -->
+ <!-- Warning message when we try to dock a non-resizeable task and launch it in fullscreen instead [CHAR LIMIT=NONE] -->
<string name="dock_non_resizeble_failed_to_dock_text">App does not support split-screen.</string>
+ <!-- Warning message when we try to dock an app not supporting multiple instances split into multiple sides [CHAR LIMIT=NONE] -->
+ <string name="dock_multi_instances_not_supported_text">This app can only be opened in 1 window.</string>
<!-- Text that gets shown on top of current activity to inform the user that the system force-resized the current activity to be displayed on a secondary display and that things might crash/not work properly [CHAR LIMIT=NONE] -->
<string name="forced_resizable_secondary_display">App may not work on a secondary display.</string>
<!-- Warning message when we try to launch a non-resizeable activity on a secondary display and launch it on the primary instead. -->
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationAdapter.java b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationAdapter.java
index 215308d9e96e..00b9fcede4ca 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationAdapter.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationAdapter.java
@@ -30,6 +30,8 @@ import android.window.TransitionInfo;
import androidx.annotation.NonNull;
+import com.android.wm.shell.transition.Transitions;
+
/**
* Wrapper to handle the ActivityEmbedding animation update in one
* {@link SurfaceControl.Transaction}.
@@ -50,6 +52,16 @@ class ActivityEmbeddingAnimationAdapter {
/** Area in absolute coordinate that the animation surface shouldn't go beyond. */
@NonNull
private final Rect mWholeAnimationBounds = new Rect();
+ /**
+ * Area in absolute coordinate that should represent all the content to show for this window.
+ * This should be the end bounds for opening window, and start bounds for closing window in case
+ * the window is resizing during the open/close transition.
+ */
+ @NonNull
+ private final Rect mContentBounds = new Rect();
+ /** Offset relative to the window parent surface for {@link #mContentBounds}. */
+ @NonNull
+ private final Point mContentRelOffset = new Point();
@NonNull
final Transformation mTransformation = new Transformation();
@@ -80,6 +92,21 @@ class ActivityEmbeddingAnimationAdapter {
mChange = change;
mLeash = leash;
mWholeAnimationBounds.set(wholeAnimationBounds);
+ if (Transitions.isClosingType(change.getMode())) {
+ // When it is closing, we want to show the content at the start position in case the
+ // window is resizing as well. For example, when the activities is changing from split
+ // to stack, the bottom TaskFragment will be resized to fullscreen when hiding.
+ final Rect startBounds = change.getStartAbsBounds();
+ final Rect endBounds = change.getEndAbsBounds();
+ mContentBounds.set(startBounds);
+ mContentRelOffset.set(change.getEndRelOffset());
+ mContentRelOffset.offset(
+ startBounds.left - endBounds.left,
+ startBounds.top - endBounds.top);
+ } else {
+ mContentBounds.set(change.getEndAbsBounds());
+ mContentRelOffset.set(change.getEndRelOffset());
+ }
}
/**
@@ -110,8 +137,7 @@ class ActivityEmbeddingAnimationAdapter {
/** To be overridden by subclasses to adjust the animation surface change. */
void onAnimationUpdateInner(@NonNull SurfaceControl.Transaction t) {
// Update the surface position and alpha.
- final Point offset = mChange.getEndRelOffset();
- mTransformation.getMatrix().postTranslate(offset.x, offset.y);
+ mTransformation.getMatrix().postTranslate(mContentRelOffset.x, mContentRelOffset.y);
t.setMatrix(mLeash, mTransformation.getMatrix(), mMatrix);
t.setAlpha(mLeash, mTransformation.getAlpha());
@@ -119,8 +145,8 @@ class ActivityEmbeddingAnimationAdapter {
// positionX/Y are in local coordinate, so minus the local offset to get the slide amount.
final int positionX = Math.round(mMatrix[MTRANS_X]);
final int positionY = Math.round(mMatrix[MTRANS_Y]);
- final Rect cropRect = new Rect(mChange.getEndAbsBounds());
- cropRect.offset(positionX - offset.x, positionY - offset.y);
+ final Rect cropRect = new Rect(mContentBounds);
+ cropRect.offset(positionX - mContentRelOffset.x, positionY - mContentRelOffset.y);
// Store the current offset of the surface top left from (0,0) in absolute coordinate.
final int offsetX = cropRect.left;
@@ -133,7 +159,7 @@ class ActivityEmbeddingAnimationAdapter {
} else if (mAnimation.hasExtension()) {
// Allow the surface to be shown in its original bounds in case we want to use edge
// extensions.
- cropRect.union(mChange.getEndAbsBounds());
+ cropRect.union(mContentBounds);
}
// cropRect is in absolute coordinate, so we need to translate it to surface top left.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java
index 921861ae0913..c0a6456a2df0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java
@@ -304,6 +304,7 @@ class ActivityEmbeddingAnimationRunner {
// This is because the TaskFragment surface/change won't contain the Activity's before its
// reparent.
Animation changeAnimation = null;
+ Rect parentBounds = new Rect();
for (TransitionInfo.Change change : info.getChanges()) {
if (change.getMode() != TRANSIT_CHANGE
|| change.getStartAbsBounds().equals(change.getEndAbsBounds())) {
@@ -326,10 +327,15 @@ class ActivityEmbeddingAnimationRunner {
}
}
+ // The TaskFragment may be enter/exit split, so we take the union of both as the parent
+ // size.
+ parentBounds.union(boundsAnimationChange.getStartAbsBounds());
+ parentBounds.union(boundsAnimationChange.getEndAbsBounds());
+
// There are two animations in the array. The first one is for the start leash
// (snapshot), and the second one is for the end leash (TaskFragment).
final Animation[] animations = mAnimationSpec.createChangeBoundsChangeAnimations(change,
- boundsAnimationChange.getEndAbsBounds());
+ parentBounds);
// Keep track as we might need to add background color for the animation.
// Although there may be multiple change animation, record one of them is sufficient
// because the background color will be added to the root leash for the whole animation.
@@ -352,6 +358,11 @@ class ActivityEmbeddingAnimationRunner {
animations[1], boundsAnimationChange));
}
+ if (parentBounds.isEmpty()) {
+ throw new IllegalStateException(
+ "There should be at least one changing window to play the change animation");
+ }
+
// If there is no corresponding open/close window with the change, we should show background
// color to cover the empty part of the screen.
boolean shouldShouldBackgroundColor = true;
@@ -368,10 +379,10 @@ class ActivityEmbeddingAnimationRunner {
// No-op if it will be covered by the changing parent window.
animation = ActivityEmbeddingAnimationSpec.createNoopAnimation(change);
} else if (Transitions.isClosingType(change.getMode())) {
- animation = mAnimationSpec.createChangeBoundsCloseAnimation(change);
+ animation = mAnimationSpec.createChangeBoundsCloseAnimation(change, parentBounds);
shouldShouldBackgroundColor = false;
} else {
- animation = mAnimationSpec.createChangeBoundsOpenAnimation(change);
+ animation = mAnimationSpec.createChangeBoundsOpenAnimation(change, parentBounds);
shouldShouldBackgroundColor = false;
}
adapters.add(new ActivityEmbeddingAnimationAdapter(animation, change));
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java
index 2bb73692b457..65a7d09dafa3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java
@@ -21,7 +21,6 @@ import static com.android.internal.policy.TransitionAnimation.WALLPAPER_TRANSITI
import static com.android.wm.shell.transition.TransitionAnimationHelper.loadAttributeAnimation;
import android.content.Context;
-import android.graphics.Point;
import android.graphics.Rect;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
@@ -80,15 +79,25 @@ class ActivityEmbeddingAnimationSpec {
/** Animation for window that is opening in a change transition. */
@NonNull
- Animation createChangeBoundsOpenAnimation(@NonNull TransitionInfo.Change change) {
+ Animation createChangeBoundsOpenAnimation(@NonNull TransitionInfo.Change change,
+ @NonNull Rect parentBounds) {
+ // Use end bounds for opening.
final Rect bounds = change.getEndAbsBounds();
- final Point offset = change.getEndRelOffset();
- // The window will be animated in from left or right depends on its position.
- final int startLeft = offset.x == 0 ? -bounds.width() : bounds.width();
+ final int startLeft;
+ final int startTop;
+ if (parentBounds.top == bounds.top && parentBounds.bottom == bounds.bottom) {
+ // The window will be animated in from left or right depends on its position.
+ startTop = 0;
+ startLeft = parentBounds.left == bounds.left ? -bounds.width() : bounds.width();
+ } else {
+ // The window will be animated in from top or bottom depends on its position.
+ startTop = parentBounds.top == bounds.top ? -bounds.height() : bounds.height();
+ startLeft = 0;
+ }
// The position should be 0-based as we will post translate in
// ActivityEmbeddingAnimationAdapter#onAnimationUpdate
- final Animation animation = new TranslateAnimation(startLeft, 0, 0, 0);
+ final Animation animation = new TranslateAnimation(startLeft, 0, startTop, 0);
animation.setInterpolator(mFastOutExtraSlowInInterpolator);
animation.setDuration(CHANGE_ANIMATION_DURATION);
animation.initialize(bounds.width(), bounds.height(), bounds.width(), bounds.height());
@@ -98,15 +107,25 @@ class ActivityEmbeddingAnimationSpec {
/** Animation for window that is closing in a change transition. */
@NonNull
- Animation createChangeBoundsCloseAnimation(@NonNull TransitionInfo.Change change) {
- final Rect bounds = change.getEndAbsBounds();
- final Point offset = change.getEndRelOffset();
- // The window will be animated out to left or right depends on its position.
- final int endLeft = offset.x == 0 ? -bounds.width() : bounds.width();
+ Animation createChangeBoundsCloseAnimation(@NonNull TransitionInfo.Change change,
+ @NonNull Rect parentBounds) {
+ // Use start bounds for closing.
+ final Rect bounds = change.getStartAbsBounds();
+ final int endTop;
+ final int endLeft;
+ if (parentBounds.top == bounds.top && parentBounds.bottom == bounds.bottom) {
+ // The window will be animated out to left or right depends on its position.
+ endTop = 0;
+ endLeft = parentBounds.left == bounds.left ? -bounds.width() : bounds.width();
+ } else {
+ // The window will be animated out to top or bottom depends on its position.
+ endTop = parentBounds.top == bounds.top ? -bounds.height() : bounds.height();
+ endLeft = 0;
+ }
// The position should be 0-based as we will post translate in
// ActivityEmbeddingAnimationAdapter#onAnimationUpdate
- final Animation animation = new TranslateAnimation(0, endLeft, 0, 0);
+ final Animation animation = new TranslateAnimation(0, endLeft, 0, endTop);
animation.setInterpolator(mFastOutExtraSlowInInterpolator);
animation.setDuration(CHANGE_ANIMATION_DURATION);
animation.initialize(bounds.width(), bounds.height(), bounds.width(), bounds.height());
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java
index 1474754fc7f7..e8b0f0265394 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java
@@ -76,6 +76,7 @@ public class DividerView extends FrameLayout implements View.OnTouchListener {
private GestureDetector mDoubleTapDetector;
private boolean mInteractive;
private boolean mSetTouchRegion = true;
+ private int mLastDraggingPosition;
/**
* Tracks divider bar visible bounds in screen-based coordination. Used to calculate with
@@ -298,6 +299,7 @@ public class DividerView extends FrameLayout implements View.OnTouchListener {
}
if (mMoving) {
final int position = mSplitLayout.getDividePosition() + touchPos - mStartPos;
+ mLastDraggingPosition = position;
mSplitLayout.updateDivideBounds(position);
}
break;
@@ -372,6 +374,15 @@ public class DividerView extends FrameLayout implements View.OnTouchListener {
"Set divider bar %s from %s", interactive ? "interactive" : "non-interactive",
from);
mInteractive = interactive;
+ if (!mInteractive && mMoving) {
+ final int position = mSplitLayout.getDividePosition();
+ mSplitLayout.flingDividePosition(
+ mLastDraggingPosition,
+ position,
+ mSplitLayout.FLING_RESIZE_DURATION,
+ () -> mSplitLayout.setDividePosition(position, true /* applyLayoutChange */));
+ mMoving = false;
+ }
releaseTouching();
mHandle.setVisibility(mInteractive ? View.VISIBLE : View.INVISIBLE);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
index ec9e6f7573bf..ae496165028f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
@@ -81,7 +81,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
public static final int PARALLAX_DISMISSING = 1;
public static final int PARALLAX_ALIGN_CENTER = 2;
- private static final int FLING_RESIZE_DURATION = 250;
+ public static final int FLING_RESIZE_DURATION = 250;
private static final int FLING_SWITCH_DURATION = 350;
private static final int FLING_ENTER_DURATION = 450;
private static final int FLING_EXIT_DURATION = 450;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
index 1774dd5e3b6f..a79ac45228ca 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
@@ -58,6 +58,7 @@ import android.view.RemoteAnimationTarget;
import android.view.SurfaceControl;
import android.view.SurfaceSession;
import android.view.WindowManager;
+import android.widget.Toast;
import android.window.RemoteTransition;
import android.window.WindowContainerTransaction;
@@ -597,6 +598,10 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
} else if (isSplitScreenVisible()) {
mStageCoordinator.switchSplitPosition("startIntent");
return;
+ } else {
+ Toast.makeText(mContext, R.string.dock_multi_instances_not_supported_text,
+ Toast.LENGTH_SHORT).show();
+ return;
}
}
diff --git a/location/java/android/location/GnssMeasurementsEvent.java b/location/java/android/location/GnssMeasurementsEvent.java
index 0397740d104e..a8b0dc235b43 100644
--- a/location/java/android/location/GnssMeasurementsEvent.java
+++ b/location/java/android/location/GnssMeasurementsEvent.java
@@ -40,6 +40,7 @@ public final class GnssMeasurementsEvent implements Parcelable {
private final GnssClock mClock;
private final List<GnssMeasurement> mMeasurements;
private final List<GnssAutomaticGainControl> mGnssAgcs;
+ private final boolean mIsFullTracking;
/**
* Used for receiving GNSS satellite measurements from the GNSS engine.
@@ -124,10 +125,12 @@ public final class GnssMeasurementsEvent implements Parcelable {
*/
private GnssMeasurementsEvent(@NonNull GnssClock clock,
@NonNull List<GnssMeasurement> measurements,
- @NonNull List<GnssAutomaticGainControl> agcs) {
+ @NonNull List<GnssAutomaticGainControl> agcs,
+ boolean isFullTracking) {
mMeasurements = measurements;
mGnssAgcs = agcs;
mClock = clock;
+ mIsFullTracking = isFullTracking;
}
/**
@@ -156,15 +159,31 @@ public final class GnssMeasurementsEvent implements Parcelable {
return mGnssAgcs;
}
+ /**
+ * True indicates that this event was produced while the chipset was in full tracking mode, ie,
+ * the GNSS chipset switched off duty cycling. In this mode, no clock discontinuities are
+ * expected and, when supported, carrier phase should be continuous in good signal conditions.
+ * All non-blocklisted, healthy constellations, satellites and frequency bands must be tracked
+ * and reported in this mode.
+ *
+ * False indicates that the GNSS chipset may optimize power via duty cycling, constellations and
+ * frequency limits, etc.
+ */
+ public boolean getIsFullTracking() {
+ return mIsFullTracking;
+ }
+
public static final @android.annotation.NonNull Creator<GnssMeasurementsEvent> CREATOR =
new Creator<GnssMeasurementsEvent>() {
@Override
public GnssMeasurementsEvent createFromParcel(Parcel in) {
- GnssClock clock = in.readParcelable(getClass().getClassLoader(), android.location.GnssClock.class);
+ GnssClock clock = in.readParcelable(getClass().getClassLoader(),
+ android.location.GnssClock.class);
List<GnssMeasurement> measurements = in.createTypedArrayList(GnssMeasurement.CREATOR);
List<GnssAutomaticGainControl> agcs = in.createTypedArrayList(
GnssAutomaticGainControl.CREATOR);
- return new GnssMeasurementsEvent(clock, measurements, agcs);
+ boolean isFullTracking = in.readBoolean();
+ return new GnssMeasurementsEvent(clock, measurements, agcs, isFullTracking);
}
@Override
@@ -183,6 +202,7 @@ public final class GnssMeasurementsEvent implements Parcelable {
parcel.writeParcelable(mClock, flags);
parcel.writeTypedList(mMeasurements);
parcel.writeTypedList(mGnssAgcs);
+ parcel.writeBoolean(mIsFullTracking);
}
@Override
@@ -191,6 +211,7 @@ public final class GnssMeasurementsEvent implements Parcelable {
builder.append(mClock);
builder.append(' ').append(mMeasurements.toString());
builder.append(' ').append(mGnssAgcs.toString());
+ builder.append(" isFullTracking=").append(mIsFullTracking);
builder.append("]");
return builder.toString();
}
@@ -200,6 +221,7 @@ public final class GnssMeasurementsEvent implements Parcelable {
private GnssClock mClock;
private List<GnssMeasurement> mMeasurements;
private List<GnssAutomaticGainControl> mGnssAgcs;
+ private boolean mIsFullTracking;
/**
* Constructs a {@link GnssMeasurementsEvent.Builder} instance.
@@ -218,6 +240,7 @@ public final class GnssMeasurementsEvent implements Parcelable {
mClock = event.getClock();
mMeasurements = (List<GnssMeasurement>) event.getMeasurements();
mGnssAgcs = (List<GnssAutomaticGainControl>) event.getGnssAutomaticGainControls();
+ mIsFullTracking = event.getIsFullTracking();
}
/**
@@ -276,10 +299,29 @@ public final class GnssMeasurementsEvent implements Parcelable {
return this;
}
+ /**
+ * Sets whether the GNSS chipset was in the full tracking mode at the time this event was
+ * produced.
+ *
+ * True indicates that this event was produced while the chipset was in full tracking
+ * mode, ie, the GNSS chipset switched off duty cycling. In this mode, no clock
+ * discontinuities are expected and, when supported, carrier phase should be continuous in
+ * good signal conditions. All non-blocklisted, healthy constellations, satellites and
+ * frequency bands must be tracked and reported in this mode.
+ *
+ * False indicates that the GNSS chipset may optimize power via duty cycling, constellations
+ * and frequency limits, etc.
+ */
+ @NonNull
+ public Builder setIsFullTracking(boolean isFullTracking) {
+ mIsFullTracking = isFullTracking;
+ return this;
+ }
+
/** Builds a {@link GnssMeasurementsEvent} instance as specified by this builder. */
@NonNull
public GnssMeasurementsEvent build() {
- return new GnssMeasurementsEvent(mClock, mMeasurements, mGnssAgcs);
+ return new GnssMeasurementsEvent(mClock, mMeasurements, mGnssAgcs, mIsFullTracking);
}
}
}
diff --git a/media/java/android/media/AudioDeviceInfo.java b/media/java/android/media/AudioDeviceInfo.java
index 3d08959901b1..3b30b1d89268 100644
--- a/media/java/android/media/AudioDeviceInfo.java
+++ b/media/java/android/media/AudioDeviceInfo.java
@@ -89,6 +89,7 @@ public final class AudioDeviceInfo {
public static final int TYPE_USB_ACCESSORY = 12;
/**
* A device type describing the audio device associated with a dock.
+ * @see #TYPE_DOCK_ANALOG
*/
public static final int TYPE_DOCK = 13;
/**
@@ -182,6 +183,11 @@ public final class AudioDeviceInfo {
*/
public static final int TYPE_BLE_BROADCAST = 30;
+ /**
+ * A device type describing the audio device associated with a dock using an analog connection.
+ */
+ public static final int TYPE_DOCK_ANALOG = 31;
+
/** @hide */
@IntDef(flag = false, prefix = "TYPE", value = {
TYPE_BUILTIN_EARPIECE,
@@ -213,7 +219,8 @@ public final class AudioDeviceInfo {
TYPE_BLE_HEADSET,
TYPE_BLE_SPEAKER,
TYPE_ECHO_REFERENCE,
- TYPE_BLE_BROADCAST}
+ TYPE_BLE_BROADCAST,
+ TYPE_DOCK_ANALOG}
)
@Retention(RetentionPolicy.SOURCE)
public @interface AudioDeviceType {}
@@ -240,7 +247,8 @@ public final class AudioDeviceInfo {
TYPE_BLE_HEADSET,
TYPE_HDMI_ARC,
TYPE_HDMI_EARC,
- TYPE_ECHO_REFERENCE}
+ TYPE_ECHO_REFERENCE,
+ TYPE_DOCK_ANALOG}
)
@Retention(RetentionPolicy.SOURCE)
public @interface AudioDeviceTypeIn {}
@@ -271,7 +279,8 @@ public final class AudioDeviceInfo {
TYPE_BUILTIN_SPEAKER_SAFE,
TYPE_BLE_HEADSET,
TYPE_BLE_SPEAKER,
- TYPE_BLE_BROADCAST}
+ TYPE_BLE_BROADCAST,
+ TYPE_DOCK_ANALOG}
)
@Retention(RetentionPolicy.SOURCE)
public @interface AudioDeviceTypeOut {}
@@ -304,6 +313,7 @@ public final class AudioDeviceInfo {
case TYPE_BLE_HEADSET:
case TYPE_BLE_SPEAKER:
case TYPE_BLE_BROADCAST:
+ case TYPE_DOCK_ANALOG:
return true;
default:
return false;
@@ -334,6 +344,7 @@ public final class AudioDeviceInfo {
case TYPE_HDMI_ARC:
case TYPE_HDMI_EARC:
case TYPE_ECHO_REFERENCE:
+ case TYPE_DOCK_ANALOG:
return true;
default:
return false;
@@ -573,7 +584,7 @@ public final class AudioDeviceInfo {
/**
* @return The device type identifier of the audio device (i.e. TYPE_BUILTIN_SPEAKER).
*/
- public int getType() {
+ public @AudioDeviceType int getType() {
return INT_TO_EXT_DEVICE_MAPPING.get(mPort.type(), TYPE_UNKNOWN);
}
@@ -624,7 +635,7 @@ public final class AudioDeviceInfo {
INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES, TYPE_BLUETOOTH_A2DP);
INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER, TYPE_BLUETOOTH_A2DP);
INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_HDMI, TYPE_HDMI);
- INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET, TYPE_DOCK);
+ INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET, TYPE_DOCK_ANALOG);
INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET, TYPE_DOCK);
INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_USB_ACCESSORY, TYPE_USB_ACCESSORY);
INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_USB_DEVICE, TYPE_USB_DEVICE);
@@ -652,7 +663,7 @@ public final class AudioDeviceInfo {
INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_HDMI, TYPE_HDMI);
INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_TELEPHONY_RX, TYPE_TELEPHONY);
INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_BACK_MIC, TYPE_BUILTIN_MIC);
- INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_ANLG_DOCK_HEADSET, TYPE_DOCK);
+ INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_ANLG_DOCK_HEADSET, TYPE_DOCK_ANALOG);
INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_DGTL_DOCK_HEADSET, TYPE_DOCK);
INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_USB_ACCESSORY, TYPE_USB_ACCESSORY);
INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_USB_DEVICE, TYPE_USB_DEVICE);
@@ -687,7 +698,8 @@ public final class AudioDeviceInfo {
EXT_TO_INT_DEVICE_MAPPING.put(TYPE_USB_DEVICE, AudioSystem.DEVICE_OUT_USB_DEVICE);
EXT_TO_INT_DEVICE_MAPPING.put(TYPE_USB_HEADSET, AudioSystem.DEVICE_OUT_USB_HEADSET);
EXT_TO_INT_DEVICE_MAPPING.put(TYPE_USB_ACCESSORY, AudioSystem.DEVICE_OUT_USB_ACCESSORY);
- EXT_TO_INT_DEVICE_MAPPING.put(TYPE_DOCK, AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET);
+ EXT_TO_INT_DEVICE_MAPPING.put(TYPE_DOCK, AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET);
+ EXT_TO_INT_DEVICE_MAPPING.put(TYPE_DOCK_ANALOG, AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET);
EXT_TO_INT_DEVICE_MAPPING.put(TYPE_FM, AudioSystem.DEVICE_OUT_FM);
EXT_TO_INT_DEVICE_MAPPING.put(TYPE_TELEPHONY, AudioSystem.DEVICE_OUT_TELEPHONY_TX);
EXT_TO_INT_DEVICE_MAPPING.put(TYPE_AUX_LINE, AudioSystem.DEVICE_OUT_AUX_LINE);
@@ -710,7 +722,9 @@ public final class AudioDeviceInfo {
TYPE_WIRED_HEADSET, AudioSystem.DEVICE_IN_WIRED_HEADSET);
EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_HDMI, AudioSystem.DEVICE_IN_HDMI);
EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_TELEPHONY, AudioSystem.DEVICE_IN_TELEPHONY_RX);
- EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_DOCK, AudioSystem.DEVICE_IN_ANLG_DOCK_HEADSET);
+ EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_DOCK, AudioSystem.DEVICE_IN_DGTL_DOCK_HEADSET);
+ EXT_TO_INT_INPUT_DEVICE_MAPPING.put(
+ TYPE_DOCK_ANALOG, AudioSystem.DEVICE_IN_ANLG_DOCK_HEADSET);
EXT_TO_INT_INPUT_DEVICE_MAPPING.put(
TYPE_USB_ACCESSORY, AudioSystem.DEVICE_IN_USB_ACCESSORY);
EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_USB_DEVICE, AudioSystem.DEVICE_IN_USB_DEVICE);
diff --git a/media/java/android/media/AudioFormat.java b/media/java/android/media/AudioFormat.java
index 980accae733b..ccd4ed09fa94 100644
--- a/media/java/android/media/AudioFormat.java
+++ b/media/java/android/media/AudioFormat.java
@@ -350,10 +350,29 @@ public final class AudioFormat implements Parcelable {
public static final int ENCODING_MPEGH_LC_L3 = 25;
/** Audio data format: MPEG-H low complexity profile, level 4 */
public static final int ENCODING_MPEGH_LC_L4 = 26;
- /** Audio data format: DTS UHD compressed */
- public static final int ENCODING_DTS_UHD = 27;
+ /** Audio data format: DTS UHD Profile-1 compressed (aka DTS:X Profile 1)
+ * Has the same meaning and value as ENCODING_DTS_UHD_P1.
+ * @deprecated Use {@link #ENCODING_DTS_UHD_P1} instead. */
+ @Deprecated public static final int ENCODING_DTS_UHD = 27;
/** Audio data format: DRA compressed */
public static final int ENCODING_DRA = 28;
+ /** Audio data format: DTS HD Master Audio compressed
+ * DTS HD Master Audio stream is variable bit rate and contains lossless audio.
+ * Use {@link #ENCODING_DTS_HD_MA} for lossless audio content (DTS-HD MA Lossless)
+ * and use {@link #ENCODING_DTS_HD} for other DTS bitstreams with extension substream
+ * (DTS 8Ch Discrete, DTS Hi Res, DTS Express). */
+ public static final int ENCODING_DTS_HD_MA = 29;
+ /** Audio data format: DTS UHD Profile-1 compressed (aka DTS:X Profile 1)
+ * Has the same meaning and value as the deprecated {@link #ENCODING_DTS_UHD}.*/
+ public static final int ENCODING_DTS_UHD_P1 = 27;
+ /** Audio data format: DTS UHD Profile-2 compressed
+ * DTS-UHD Profile-2 supports delivery of Channel-Based Audio, Object-Based Audio
+ * and High Order Ambisonic presentations up to the fourth order.
+ * Use {@link #ENCODING_DTS_UHD_P1} to transmit DTS UHD Profile 1 (aka DTS:X Profile 1)
+ * bitstream.
+ * Use {@link #ENCODING_DTS_UHD_P2} to transmit DTS UHD Profile 2 (aka DTS:X Profile 2)
+ * bitstream. */
+ public static final int ENCODING_DTS_UHD_P2 = 30;
/** @hide */
public static String toLogFriendlyEncoding(int enc) {
@@ -410,10 +429,14 @@ public final class AudioFormat implements Parcelable {
return "ENCODING_MPEGH_LC_L3";
case ENCODING_MPEGH_LC_L4:
return "ENCODING_MPEGH_LC_L4";
- case ENCODING_DTS_UHD:
- return "ENCODING_DTS_UHD";
+ case ENCODING_DTS_UHD_P1:
+ return "ENCODING_DTS_UHD_P1";
case ENCODING_DRA:
return "ENCODING_DRA";
+ case ENCODING_DTS_HD_MA:
+ return "ENCODING_DTS_HD_MA";
+ case ENCODING_DTS_UHD_P2:
+ return "ENCODING_DTS_UHD_P2";
default :
return "invalid encoding " + enc;
}
@@ -771,8 +794,10 @@ public final class AudioFormat implements Parcelable {
case ENCODING_MPEGH_BL_L4:
case ENCODING_MPEGH_LC_L3:
case ENCODING_MPEGH_LC_L4:
- case ENCODING_DTS_UHD:
+ case ENCODING_DTS_UHD_P1:
case ENCODING_DRA:
+ case ENCODING_DTS_HD_MA:
+ case ENCODING_DTS_UHD_P2:
return true;
default:
return false;
@@ -808,8 +833,10 @@ public final class AudioFormat implements Parcelable {
case ENCODING_MPEGH_BL_L4:
case ENCODING_MPEGH_LC_L3:
case ENCODING_MPEGH_LC_L4:
- case ENCODING_DTS_UHD:
+ case ENCODING_DTS_UHD_P1:
case ENCODING_DRA:
+ case ENCODING_DTS_HD_MA:
+ case ENCODING_DTS_UHD_P2:
return true;
default:
return false;
@@ -848,8 +875,10 @@ public final class AudioFormat implements Parcelable {
case ENCODING_MPEGH_BL_L4:
case ENCODING_MPEGH_LC_L3:
case ENCODING_MPEGH_LC_L4:
- case ENCODING_DTS_UHD:
+ case ENCODING_DTS_UHD_P1:
case ENCODING_DRA:
+ case ENCODING_DTS_HD_MA:
+ case ENCODING_DTS_UHD_P2:
return false;
case ENCODING_INVALID:
default:
@@ -888,8 +917,10 @@ public final class AudioFormat implements Parcelable {
case ENCODING_MPEGH_BL_L4:
case ENCODING_MPEGH_LC_L3:
case ENCODING_MPEGH_LC_L4:
- case ENCODING_DTS_UHD:
+ case ENCODING_DTS_UHD_P1:
case ENCODING_DRA:
+ case ENCODING_DTS_HD_MA:
+ case ENCODING_DTS_UHD_P2:
return false;
case ENCODING_INVALID:
default:
@@ -1176,8 +1207,10 @@ public final class AudioFormat implements Parcelable {
case ENCODING_MPEGH_BL_L4:
case ENCODING_MPEGH_LC_L3:
case ENCODING_MPEGH_LC_L4:
- case ENCODING_DTS_UHD:
+ case ENCODING_DTS_UHD_P1:
case ENCODING_DRA:
+ case ENCODING_DTS_HD_MA:
+ case ENCODING_DTS_UHD_P2:
mEncoding = encoding;
break;
case ENCODING_INVALID:
@@ -1405,8 +1438,10 @@ public final class AudioFormat implements Parcelable {
ENCODING_MPEGH_BL_L4,
ENCODING_MPEGH_LC_L3,
ENCODING_MPEGH_LC_L4,
- ENCODING_DTS_UHD,
- ENCODING_DRA }
+ ENCODING_DTS_UHD_P1,
+ ENCODING_DRA,
+ ENCODING_DTS_HD_MA,
+ ENCODING_DTS_UHD_P2 }
)
@Retention(RetentionPolicy.SOURCE)
public @interface Encoding {}
@@ -1426,8 +1461,10 @@ public final class AudioFormat implements Parcelable {
ENCODING_MPEGH_BL_L4,
ENCODING_MPEGH_LC_L3,
ENCODING_MPEGH_LC_L4,
- ENCODING_DTS_UHD,
- ENCODING_DRA
+ ENCODING_DTS_UHD_P1,
+ ENCODING_DRA,
+ ENCODING_DTS_HD_MA,
+ ENCODING_DTS_UHD_P2
};
/** @hide */
@@ -1445,8 +1482,10 @@ public final class AudioFormat implements Parcelable {
ENCODING_MPEGH_BL_L4,
ENCODING_MPEGH_LC_L3,
ENCODING_MPEGH_LC_L4,
- ENCODING_DTS_UHD,
- ENCODING_DRA }
+ ENCODING_DTS_UHD_P1,
+ ENCODING_DRA,
+ ENCODING_DTS_HD_MA,
+ ENCODING_DTS_UHD_P2 }
)
@Retention(RetentionPolicy.SOURCE)
public @interface SurroundSoundEncoding {}
@@ -1488,10 +1527,14 @@ public final class AudioFormat implements Parcelable {
return "MPEG-H 3D Audio low complexity profile level 3";
case ENCODING_MPEGH_LC_L4:
return "MPEG-H 3D Audio low complexity profile level 4";
- case ENCODING_DTS_UHD:
- return "DTS UHD";
+ case ENCODING_DTS_UHD_P1:
+ return "DTS UHD Profile 1";
case ENCODING_DRA:
return "DRA";
+ case ENCODING_DTS_HD_MA:
+ return "DTS HD Master Audio";
+ case ENCODING_DTS_UHD_P2:
+ return "DTS UHD Profile 2";
default:
return "Unknown surround sound format";
}
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index ad6aceaf237d..a48edac8e080 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -450,6 +450,10 @@ public class AudioSystem
return "AUDIO_FORMAT_APTX_ADAPTIVE_QLEA";
case /* AUDIO_FORMAT_APTX_ADAPTIVE_R4 */ 0x31000000:
return "AUDIO_FORMAT_APTX_ADAPTIVE_R4";
+ case /* AUDIO_FORMAT_DTS_HD_MA */ 0x32000000:
+ return "AUDIO_FORMAT_DTS_HD_MA";
+ case /* AUDIO_FORMAT_DTS_UHD_P2 */ 0x33000000:
+ return "AUDIO_FORMAT_DTS_UHD_P2";
/* Aliases */
case /* AUDIO_FORMAT_PCM_16_BIT */ 0x1:
diff --git a/media/java/android/media/ExifInterface.java b/media/java/android/media/ExifInterface.java
index 524bde4e7d15..23f87abaffed 100644
--- a/media/java/android/media/ExifInterface.java
+++ b/media/java/android/media/ExifInterface.java
@@ -3754,6 +3754,11 @@ public class ExifInterface {
// Skip input stream to the end of the EXIF chunk
totalInputStream.skipBytes(WEBP_CHUNK_TYPE_BYTE_LENGTH);
int exifChunkLength = totalInputStream.readInt();
+ // RIFF chunks have a single padding byte at the end if the declared chunk size is
+ // odd.
+ if (exifChunkLength % 2 != 0) {
+ exifChunkLength++;
+ }
totalInputStream.skipBytes(exifChunkLength);
// Write new EXIF chunk to output stream
@@ -3824,7 +3829,7 @@ public class ExifInterface {
int widthAndHeight = 0;
int width = 0;
int height = 0;
- int alpha = 0;
+ boolean alpha = false;
// Save VP8 frame data for later
byte[] vp8Frame = new byte[3];
@@ -3859,7 +3864,7 @@ public class ExifInterface {
width = ((widthAndHeight << 18) >> 18) + 1;
height = ((widthAndHeight << 4) >> 18) + 1;
// Retrieve alpha bit
- alpha = widthAndHeight & (1 << 3);
+ alpha = (widthAndHeight & (1 << 28)) != 0;
bytesToRead -= (1 /* VP8L signature */ + 4);
}
@@ -3867,10 +3872,12 @@ public class ExifInterface {
nonHeaderOutputStream.write(WEBP_CHUNK_TYPE_VP8X);
nonHeaderOutputStream.writeInt(WEBP_CHUNK_TYPE_VP8X_DEFAULT_LENGTH);
byte[] data = new byte[WEBP_CHUNK_TYPE_VP8X_DEFAULT_LENGTH];
+ // ALPHA flag
+ if (alpha) {
+ data[0] = (byte) (data[0] | (1 << 4));
+ }
// EXIF flag
data[0] = (byte) (data[0] | (1 << 3));
- // ALPHA flag
- data[0] = (byte) (data[0] | (alpha << 4));
// VP8X stores Width - 1 and Height - 1 values
width -= 1;
height -= 1;
diff --git a/media/java/android/media/MediaRouter2.java b/media/java/android/media/MediaRouter2.java
index 161ea255dfb4..a28ea32bf3ce 100644
--- a/media/java/android/media/MediaRouter2.java
+++ b/media/java/android/media/MediaRouter2.java
@@ -305,7 +305,7 @@ public final class MediaRouter2 {
currentSystemRoutes = mMediaRouterService.getSystemRoutes();
currentSystemSessionInfo = mMediaRouterService.getSystemSessionInfo();
} catch (RemoteException ex) {
- Log.e(TAG, "Unable to get current system's routes / session info", ex);
+ ex.rethrowFromSystemServer();
}
if (currentSystemRoutes == null || currentSystemRoutes.isEmpty()) {
@@ -407,14 +407,14 @@ public final class MediaRouter2 {
mMediaRouterService.registerRouter2(stub, mPackageName);
mStub = stub;
} catch (RemoteException ex) {
- Log.e(TAG, "registerRouteCallback: Unable to register MediaRouter2.", ex);
+ ex.rethrowFromSystemServer();
}
}
if (mStub != null && updateDiscoveryPreferenceIfNeededLocked()) {
try {
mMediaRouterService.setDiscoveryRequestWithRouter2(mStub, mDiscoveryPreference);
} catch (RemoteException ex) {
- Log.e(TAG, "registerRouteCallback: Unable to set discovery request.", ex);
+ ex.rethrowFromSystemServer();
}
}
}
@@ -454,7 +454,7 @@ public final class MediaRouter2 {
try {
mMediaRouterService.unregisterRouter2(mStub);
} catch (RemoteException ex) {
- Log.e(TAG, "Unable to unregister media router.", ex);
+ ex.rethrowFromSystemServer();
}
mStub = null;
}
@@ -1769,7 +1769,7 @@ public final class MediaRouter2 {
try {
mMediaRouterService.releaseSessionWithRouter2(mStub, getId());
} catch (RemoteException ex) {
- Log.e(TAG, "Unable to release session", ex);
+ ex.rethrowFromSystemServer();
}
}
@@ -1787,7 +1787,7 @@ public final class MediaRouter2 {
try {
mMediaRouterService.unregisterRouter2(mStub);
} catch (RemoteException ex) {
- Log.e(TAG, "releaseInternal: Unable to unregister media router.", ex);
+ ex.rethrowFromSystemServer();
}
mStub = null;
}
diff --git a/media/java/android/media/audio/common/AidlConversion.java b/media/java/android/media/audio/common/AidlConversion.java
index 87634aa37fea..4cf3b3e95bf0 100644
--- a/media/java/android/media/audio/common/AidlConversion.java
+++ b/media/java/android/media/audio/common/AidlConversion.java
@@ -509,7 +509,7 @@ public class AidlConversion {
} else if (MediaFormat.MIMETYPE_AUDIO_MPEGH_LC_L4.equals(aidl.encoding)) {
return AudioFormat.ENCODING_MPEGH_LC_L4;
} else if (MediaFormat.MIMETYPE_AUDIO_DTS_UHD.equals(aidl.encoding)) {
- return AudioFormat.ENCODING_DTS_UHD;
+ return AudioFormat.ENCODING_DTS_UHD_P1;
} else if (MediaFormat.MIMETYPE_AUDIO_DRA.equals(aidl.encoding)) {
return AudioFormat.ENCODING_DRA;
} else {
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/ExifInterfaceTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/ExifInterfaceTest.java
index 195df78290f4..006f4e9bc0d5 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/ExifInterfaceTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/ExifInterfaceTest.java
@@ -23,6 +23,7 @@ import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.ExifInterface;
import android.os.Environment;
+import android.os.FileUtils;
import android.test.AndroidTestCase;
import android.util.Log;
import android.system.ErrnoException;
@@ -37,6 +38,8 @@ import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Objects;
import libcore.io.IoUtils;
import libcore.io.Streams;
@@ -353,20 +356,23 @@ public class ExifInterfaceTest extends AndroidTestCase {
}
}
- private void testSaveAttributes_withFileName(File imageFile, ExpectedValue expectedValue)
+ private void testSaveAttributes_withFileName(File srcFile, ExpectedValue expectedValue)
throws IOException {
+ File imageFile = clone(srcFile);
String verboseTag = imageFile.getName();
ExifInterface exifInterface = new ExifInterface(imageFile.getAbsolutePath());
exifInterface.saveAttributes();
exifInterface = new ExifInterface(imageFile.getAbsolutePath());
compareWithExpectedValue(exifInterface, expectedValue, verboseTag);
+ assertBitmapsEquivalent(srcFile, imageFile);
+ assertSecondSaveProducesSameSizeFile(imageFile);
// Test for modifying one attribute.
+ exifInterface = new ExifInterface(imageFile.getAbsolutePath());
String backupValue = exifInterface.getAttribute(ExifInterface.TAG_MAKE);
exifInterface.setAttribute(ExifInterface.TAG_MAKE, "abc");
exifInterface.saveAttributes();
- exifInterface = new ExifInterface(imageFile.getAbsolutePath());
assertEquals("abc", exifInterface.getAttribute(ExifInterface.TAG_MAKE));
// Restore the backup value.
exifInterface.setAttribute(ExifInterface.TAG_MAKE, backupValue);
@@ -481,4 +487,56 @@ public class ExifInterfaceTest extends AndroidTestCase {
// Test if it is possible to parse the volantis generated JPEG smoothly.
testExifInterfaceForJpeg(VOLANTIS_JPEG, R.array.volantis_jpg);
}
+
+ /**
+ * Asserts that {@code expectedImageFile} and {@code actualImageFile} can be decoded by
+ * {@link BitmapFactory} and the results have the same width, height and MIME type.
+ *
+ * <p>This does not check the image itself for similarity/equality.
+ */
+ private void assertBitmapsEquivalent(File expectedImageFile, File actualImageFile) {
+ BitmapFactory.Options expectedOptions = new BitmapFactory.Options();
+ Bitmap expectedBitmap = Objects.requireNonNull(
+ BitmapFactory.decodeFile(expectedImageFile.getAbsolutePath(), expectedOptions));
+ BitmapFactory.Options actualOptions = new BitmapFactory.Options();
+ Bitmap actualBitmap = Objects.requireNonNull(
+ BitmapFactory.decodeFile(actualImageFile.getAbsolutePath(), actualOptions));
+
+ assertEquals(expectedOptions.outWidth, actualOptions.outWidth);
+ assertEquals(expectedOptions.outHeight, actualOptions.outHeight);
+ assertEquals(expectedOptions.outMimeType, actualOptions.outMimeType);
+ assertEquals(expectedBitmap.getWidth(), actualBitmap.getWidth());
+ assertEquals(expectedBitmap.getHeight(), actualBitmap.getHeight());
+ }
+
+ /**
+ * Asserts that saving the file the second time (without modifying any attributes) produces
+ * exactly the same length file as the first save. The first save (with no modifications) is
+ * expected to (possibly) change the file length because {@link ExifInterface} may move/reformat
+ * the Exif block within the file, but the second save should not make further modifications.
+ */
+ private void assertSecondSaveProducesSameSizeFile(File imageFileAfterOneSave)
+ throws IOException {
+ File imageFileAfterTwoSaves = clone(imageFileAfterOneSave);
+ ExifInterface exifInterface = new ExifInterface(imageFileAfterTwoSaves.getAbsolutePath());
+ exifInterface.saveAttributes();
+ if (imageFileAfterOneSave.getAbsolutePath().endsWith(".png")
+ || imageFileAfterOneSave.getAbsolutePath().endsWith(".webp")) {
+ // PNG and (some) WebP files are (surprisingly) modified between the first and second
+ // save (b/249097443), so we check the difference between second and third save instead.
+ File imageFileAfterThreeSaves = clone(imageFileAfterTwoSaves);
+ exifInterface = new ExifInterface(imageFileAfterThreeSaves.getAbsolutePath());
+ exifInterface.saveAttributes();
+ assertEquals(imageFileAfterTwoSaves.length(), imageFileAfterThreeSaves.length());
+ } else {
+ assertEquals(imageFileAfterOneSave.length(), imageFileAfterTwoSaves.length());
+ }
+ }
+
+ private static File clone(File original) throws IOException {
+ final File cloned =
+ File.createTempFile("tmp_", +System.nanoTime() + "_" + original.getName());
+ FileUtils.copyFileOrThrow(original, cloned);
+ return cloned;
+ }
}
diff --git a/media/tests/MediaRouter/AndroidTest.xml b/media/tests/MediaRouter/AndroidTest.xml
index d350e05ecc33..3b8c846ab6e9 100644
--- a/media/tests/MediaRouter/AndroidTest.xml
+++ b/media/tests/MediaRouter/AndroidTest.xml
@@ -6,6 +6,8 @@
<target_preparer class="com.android.tradefed.targetprep.PushFilePreparer"/>
<target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer"/>
<option name="test-suite-tag" value="apct"/>
+ <option name="test-suite-tag" value="apct-instrumentation" />
+
<option name="test-tag" value="MediaRouterTest"/>
<test class="com.android.tradefed.testtype.AndroidJUnitTest">
diff --git a/packages/CompanionDeviceManager/Android.bp b/packages/CompanionDeviceManager/Android.bp
index 9f5bfd40e7e3..f6458c26f309 100644
--- a/packages/CompanionDeviceManager/Android.bp
+++ b/packages/CompanionDeviceManager/Android.bp
@@ -41,6 +41,7 @@ android_app {
"androidx.lifecycle_lifecycle-livedata",
"androidx.lifecycle_lifecycle-extensions",
"androidx.recyclerview_recyclerview",
+ "androidx-constraintlayout_constraintlayout",
"androidx.appcompat_appcompat",
],
diff --git a/packages/CompanionDeviceManager/res/drawable-night/ic_apps.xml b/packages/CompanionDeviceManager/res/drawable-night/ic_permission_app_streaming.xml
index 8d7fa26acff4..8d7fa26acff4 100644
--- a/packages/CompanionDeviceManager/res/drawable-night/ic_apps.xml
+++ b/packages/CompanionDeviceManager/res/drawable-night/ic_permission_app_streaming.xml
diff --git a/packages/CompanionDeviceManager/res/drawable-night/ic_permission_calendar.xml b/packages/CompanionDeviceManager/res/drawable-night/ic_permission_calendar.xml
new file mode 100644
index 000000000000..d7ea3a21fb00
--- /dev/null
+++ b/packages/CompanionDeviceManager/res/drawable-night/ic_permission_calendar.xml
@@ -0,0 +1,25 @@
+<!--
+ ~ Copyright (C) 2022 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24"
+ android:tint="@android:color/system_accent1_200">
+ <path android:fillColor="@android:color/white"
+ android:pathData="M5,22Q4.175,22 3.587,21.413Q3,20.825 3,20V6Q3,5.175 3.587,4.588Q4.175,4 5,4H6V2H8V4H16V2H18V4H19Q19.825,4 20.413,4.588Q21,5.175 21,6V20Q21,20.825 20.413,21.413Q19.825,22 19,22ZM5,20H19Q19,20 19,20Q19,20 19,20V10H5V20Q5,20 5,20Q5,20 5,20Z"/>
+</vector> \ No newline at end of file
diff --git a/packages/CompanionDeviceManager/res/drawable-night/ic_permission_contacts.xml b/packages/CompanionDeviceManager/res/drawable-night/ic_permission_contacts.xml
new file mode 100644
index 000000000000..41e404468b15
--- /dev/null
+++ b/packages/CompanionDeviceManager/res/drawable-night/ic_permission_contacts.xml
@@ -0,0 +1,25 @@
+<!--
+ ~ Copyright (C) 2022 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24"
+ android:tint="@android:color/system_accent1_200">
+ <path android:fillColor="@android:color/white"
+ android:pathData="M4,23V21H20V23ZM4,3V1H20V3ZM12,13Q13.25,13 14.125,12.125Q15,11.25 15,10Q15,8.75 14.125,7.875Q13.25,7 12,7Q10.75,7 9.875,7.875Q9,8.75 9,10Q9,11.25 9.875,12.125Q10.75,13 12,13ZM4,20Q3.175,20 2.588,19.413Q2,18.825 2,18V6Q2,5.175 2.588,4.588Q3.175,4 4,4H20Q20.825,4 21.413,4.588Q22,5.175 22,6V18Q22,18.825 21.413,19.413Q20.825,20 20,20ZM5.75,18Q6.875,16.6 8.475,15.8Q10.075,15 12,15Q13.925,15 15.525,15.8Q17.125,16.6 18.25,18H20Q20,18 20,18Q20,18 20,18V6Q20,6 20,6Q20,6 20,6H4Q4,6 4,6Q4,6 4,6V18Q4,18 4,18Q4,18 4,18ZM8.7,18H15.3Q14.575,17.5 13.738,17.25Q12.9,17 12,17Q11.1,17 10.263,17.25Q9.425,17.5 8.7,18ZM12,11Q11.575,11 11.288,10.712Q11,10.425 11,10Q11,9.575 11.288,9.287Q11.575,9 12,9Q12.425,9 12.713,9.287Q13,9.575 13,10Q13,10.425 12.713,10.712Q12.425,11 12,11ZM12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Z"/>
+</vector> \ No newline at end of file
diff --git a/packages/CompanionDeviceManager/res/drawable-night/ic_permission_nearby_devices.xml b/packages/CompanionDeviceManager/res/drawable-night/ic_permission_nearby_devices.xml
new file mode 100644
index 000000000000..161186155340
--- /dev/null
+++ b/packages/CompanionDeviceManager/res/drawable-night/ic_permission_nearby_devices.xml
@@ -0,0 +1,25 @@
+<!--
+ ~ Copyright (C) 2022 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24"
+ android:tint="?attr/colorControlNormal">
+ <path android:fillColor="@android:color/system_accent1_200"
+ android:pathData="M12,16.4 L7.6,12 12,7.6 16.4,12ZM13.4,21.375Q13.125,21.65 12.75,21.8Q12.375,21.95 12,21.95Q11.625,21.95 11.25,21.8Q10.875,21.65 10.6,21.375L2.625,13.4Q2.35,13.125 2.2,12.75Q2.05,12.375 2.05,12Q2.05,11.625 2.2,11.25Q2.35,10.875 2.625,10.6L10.575,2.65Q10.875,2.35 11.238,2.2Q11.6,2.05 12,2.05Q12.4,2.05 12.762,2.2Q13.125,2.35 13.425,2.65L21.375,10.6Q21.65,10.875 21.8,11.25Q21.95,11.625 21.95,12Q21.95,12.375 21.8,12.75Q21.65,13.125 21.375,13.4ZM12,19.2 L19.2,12Q19.2,12 19.2,12Q19.2,12 19.2,12L12,4.8Q12,4.8 12,4.8Q12,4.8 12,4.8L4.8,12Q4.8,12 4.8,12Q4.8,12 4.8,12L12,19.2Q12,19.2 12,19.2Q12,19.2 12,19.2Z"/>
+</vector> \ No newline at end of file
diff --git a/packages/CompanionDeviceManager/res/drawable-night/ic_notifications.xml b/packages/CompanionDeviceManager/res/drawable-night/ic_permission_notifications.xml
index 06bfad5b8efd..06bfad5b8efd 100644
--- a/packages/CompanionDeviceManager/res/drawable-night/ic_notifications.xml
+++ b/packages/CompanionDeviceManager/res/drawable-night/ic_permission_notifications.xml
diff --git a/packages/CompanionDeviceManager/res/drawable-night/ic_permission_phone.xml b/packages/CompanionDeviceManager/res/drawable-night/ic_permission_phone.xml
new file mode 100644
index 000000000000..49467edc7b26
--- /dev/null
+++ b/packages/CompanionDeviceManager/res/drawable-night/ic_permission_phone.xml
@@ -0,0 +1,25 @@
+<!--
+ ~ Copyright (C) 2022 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24"
+ android:tint="@android:color/system_accent1_200">
+ <path android:fillColor="@android:color/white"
+ android:pathData="M19.95,21Q16.725,21 13.663,19.562Q10.6,18.125 8.238,15.762Q5.875,13.4 4.438,10.337Q3,7.275 3,4.05Q3,3.6 3.3,3.3Q3.6,3 4.05,3H8.1Q8.45,3 8.725,3.225Q9,3.45 9.05,3.8L9.7,7.3Q9.75,7.65 9.688,7.937Q9.625,8.225 9.4,8.45L7,10.9Q8.05,12.7 9.625,14.275Q11.2,15.85 13.1,17L15.45,14.65Q15.675,14.425 16.038,14.312Q16.4,14.2 16.75,14.25L20.2,14.95Q20.55,15.025 20.775,15.287Q21,15.55 21,15.9V19.95Q21,20.4 20.7,20.7Q20.4,21 19.95,21Z"/>
+</vector> \ No newline at end of file
diff --git a/packages/CompanionDeviceManager/res/drawable-night/ic_permission_sms.xml b/packages/CompanionDeviceManager/res/drawable-night/ic_permission_sms.xml
new file mode 100644
index 000000000000..859c06fa63f5
--- /dev/null
+++ b/packages/CompanionDeviceManager/res/drawable-night/ic_permission_sms.xml
@@ -0,0 +1,25 @@
+<!--
+ ~ Copyright (C) 2022 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24"
+ android:tint="@android:color/system_accent1_200">
+ <path android:fillColor="@android:color/white"
+ android:pathData="M8,11Q8.425,11 8.713,10.712Q9,10.425 9,10Q9,9.575 8.713,9.287Q8.425,9 8,9Q7.575,9 7.287,9.287Q7,9.575 7,10Q7,10.425 7.287,10.712Q7.575,11 8,11ZM12,11Q12.425,11 12.713,10.712Q13,10.425 13,10Q13,9.575 12.713,9.287Q12.425,9 12,9Q11.575,9 11.288,9.287Q11,9.575 11,10Q11,10.425 11.288,10.712Q11.575,11 12,11ZM16,11Q16.425,11 16.712,10.712Q17,10.425 17,10Q17,9.575 16.712,9.287Q16.425,9 16,9Q15.575,9 15.288,9.287Q15,9.575 15,10Q15,10.425 15.288,10.712Q15.575,11 16,11ZM2,22V4Q2,3.175 2.588,2.587Q3.175,2 4,2H20Q20.825,2 21.413,2.587Q22,3.175 22,4V16Q22,16.825 21.413,17.413Q20.825,18 20,18H6ZM4,16H20Q20,16 20,16Q20,16 20,16V4Q20,4 20,4Q20,4 20,4H4Q4,4 4,4Q4,4 4,4V16ZM4,16V4Q4,4 4,4Q4,4 4,4Q4,4 4,4Q4,4 4,4V16Q4,16 4,16Q4,16 4,16Z"/>
+</vector> \ No newline at end of file
diff --git a/packages/CompanionDeviceManager/res/drawable-night/ic_storage.xml b/packages/CompanionDeviceManager/res/drawable-night/ic_permission_storage.xml
index f8aef33c88ea..f8aef33c88ea 100644
--- a/packages/CompanionDeviceManager/res/drawable-night/ic_storage.xml
+++ b/packages/CompanionDeviceManager/res/drawable-night/ic_permission_storage.xml
diff --git a/packages/CompanionDeviceManager/res/drawable/btn_expand_less.xml b/packages/CompanionDeviceManager/res/drawable/btn_expand_less.xml
new file mode 100644
index 000000000000..99db560975ee
--- /dev/null
+++ b/packages/CompanionDeviceManager/res/drawable/btn_expand_less.xml
@@ -0,0 +1,24 @@
+<!--
+ ~ Copyright (C) 2022 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24"
+ android:tint="@android:color/system_neutral1_500">
+ <path android:fillColor="@android:color/white" android:pathData="M7.4,15.05 L6.35,13.975 12,8.325 17.65,13.975 16.6,15.05 12,10.45Z"/>
+</vector> \ No newline at end of file
diff --git a/packages/CompanionDeviceManager/res/drawable/btn_expand_more.xml b/packages/CompanionDeviceManager/res/drawable/btn_expand_more.xml
new file mode 100644
index 000000000000..8518cfa2377a
--- /dev/null
+++ b/packages/CompanionDeviceManager/res/drawable/btn_expand_more.xml
@@ -0,0 +1,24 @@
+<!--
+ ~ Copyright (C) 2022 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24"
+ android:tint="@android:color/system_neutral1_500">
+ <path android:fillColor="@android:color/white" android:pathData="M12,15.05 L6.35,9.375 7.4,8.325 12,12.925 16.6,8.325 17.65,9.375Z"/>
+</vector> \ No newline at end of file
diff --git a/packages/CompanionDeviceManager/res/drawable/ic_device_other.xml b/packages/CompanionDeviceManager/res/drawable/ic_device_other.xml
index 2a8eb24bcf1f..15f6987bb551 100644
--- a/packages/CompanionDeviceManager/res/drawable/ic_device_other.xml
+++ b/packages/CompanionDeviceManager/res/drawable/ic_device_other.xml
@@ -15,7 +15,8 @@
~ limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24dp" android:height="24dp"
+ android:width="24dp"
+ android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
diff --git a/packages/CompanionDeviceManager/res/drawable/ic_apps.xml b/packages/CompanionDeviceManager/res/drawable/ic_permission_app_streaming.xml
index 7295e78b16cb..7295e78b16cb 100644
--- a/packages/CompanionDeviceManager/res/drawable/ic_apps.xml
+++ b/packages/CompanionDeviceManager/res/drawable/ic_permission_app_streaming.xml
diff --git a/packages/CompanionDeviceManager/res/drawable/ic_permission_calendar.xml b/packages/CompanionDeviceManager/res/drawable/ic_permission_calendar.xml
new file mode 100644
index 000000000000..3dc53e7df8cd
--- /dev/null
+++ b/packages/CompanionDeviceManager/res/drawable/ic_permission_calendar.xml
@@ -0,0 +1,24 @@
+<!--
+ ~ Copyright (C) 2022 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24"
+ android:tint="@android:color/system_accent1_600">
+ <path android:fillColor="@android:color/white" android:pathData="M5,22Q4.175,22 3.587,21.413Q3,20.825 3,20V6Q3,5.175 3.587,4.588Q4.175,4 5,4H6V2H8V4H16V2H18V4H19Q19.825,4 20.413,4.588Q21,5.175 21,6V20Q21,20.825 20.413,21.413Q19.825,22 19,22ZM5,20H19Q19,20 19,20Q19,20 19,20V10H5V20Q5,20 5,20Q5,20 5,20Z"/>
+</vector> \ No newline at end of file
diff --git a/packages/CompanionDeviceManager/res/drawable/ic_permission_contacts.xml b/packages/CompanionDeviceManager/res/drawable/ic_permission_contacts.xml
new file mode 100644
index 000000000000..2dfda8d4cc95
--- /dev/null
+++ b/packages/CompanionDeviceManager/res/drawable/ic_permission_contacts.xml
@@ -0,0 +1,25 @@
+<!--
+ ~ Copyright (C) 2022 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24"
+ android:tint="@android:color/system_accent1_600">
+ <path android:fillColor="@android:color/white"
+ android:pathData="M4,23V21H20V23ZM4,3V1H20V3ZM12,13Q13.25,13 14.125,12.125Q15,11.25 15,10Q15,8.75 14.125,7.875Q13.25,7 12,7Q10.75,7 9.875,7.875Q9,8.75 9,10Q9,11.25 9.875,12.125Q10.75,13 12,13ZM4,20Q3.175,20 2.588,19.413Q2,18.825 2,18V6Q2,5.175 2.588,4.588Q3.175,4 4,4H20Q20.825,4 21.413,4.588Q22,5.175 22,6V18Q22,18.825 21.413,19.413Q20.825,20 20,20ZM5.75,18Q6.875,16.6 8.475,15.8Q10.075,15 12,15Q13.925,15 15.525,15.8Q17.125,16.6 18.25,18H20Q20,18 20,18Q20,18 20,18V6Q20,6 20,6Q20,6 20,6H4Q4,6 4,6Q4,6 4,6V18Q4,18 4,18Q4,18 4,18ZM8.7,18H15.3Q14.575,17.5 13.738,17.25Q12.9,17 12,17Q11.1,17 10.263,17.25Q9.425,17.5 8.7,18ZM12,11Q11.575,11 11.288,10.712Q11,10.425 11,10Q11,9.575 11.288,9.287Q11.575,9 12,9Q12.425,9 12.713,9.287Q13,9.575 13,10Q13,10.425 12.713,10.712Q12.425,11 12,11ZM12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Z"/>
+</vector> \ No newline at end of file
diff --git a/packages/CompanionDeviceManager/res/drawable/ic_permission_nearby_devices.xml b/packages/CompanionDeviceManager/res/drawable/ic_permission_nearby_devices.xml
new file mode 100644
index 000000000000..49a6fe37d6d7
--- /dev/null
+++ b/packages/CompanionDeviceManager/res/drawable/ic_permission_nearby_devices.xml
@@ -0,0 +1,25 @@
+<!--
+ ~ Copyright (C) 2022 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24"
+ android:tint="?attr/colorControlNormal">
+ <path android:fillColor="@android:color/system_accent1_600"
+ android:pathData="M12,16.4 L7.6,12 12,7.6 16.4,12ZM13.4,21.375Q13.125,21.65 12.75,21.8Q12.375,21.95 12,21.95Q11.625,21.95 11.25,21.8Q10.875,21.65 10.6,21.375L2.625,13.4Q2.35,13.125 2.2,12.75Q2.05,12.375 2.05,12Q2.05,11.625 2.2,11.25Q2.35,10.875 2.625,10.6L10.575,2.65Q10.875,2.35 11.238,2.2Q11.6,2.05 12,2.05Q12.4,2.05 12.762,2.2Q13.125,2.35 13.425,2.65L21.375,10.6Q21.65,10.875 21.8,11.25Q21.95,11.625 21.95,12Q21.95,12.375 21.8,12.75Q21.65,13.125 21.375,13.4ZM12,19.2 L19.2,12Q19.2,12 19.2,12Q19.2,12 19.2,12L12,4.8Q12,4.8 12,4.8Q12,4.8 12,4.8L4.8,12Q4.8,12 4.8,12Q4.8,12 4.8,12L12,19.2Q12,19.2 12,19.2Q12,19.2 12,19.2Z"/>
+</vector> \ No newline at end of file
diff --git a/packages/CompanionDeviceManager/res/drawable/ic_notifications.xml b/packages/CompanionDeviceManager/res/drawable/ic_permission_notifications.xml
index 7b1ef85ae5fd..7b1ef85ae5fd 100644
--- a/packages/CompanionDeviceManager/res/drawable/ic_notifications.xml
+++ b/packages/CompanionDeviceManager/res/drawable/ic_permission_notifications.xml
diff --git a/packages/CompanionDeviceManager/res/drawable/ic_permission_phone.xml b/packages/CompanionDeviceManager/res/drawable/ic_permission_phone.xml
new file mode 100644
index 000000000000..cc1c5b56c447
--- /dev/null
+++ b/packages/CompanionDeviceManager/res/drawable/ic_permission_phone.xml
@@ -0,0 +1,24 @@
+<!--
+ ~ Copyright (C) 2022 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24"
+ android:tint="@android:color/system_accent1_600">
+ <path android:fillColor="@android:color/white" android:pathData="M19.95,21Q16.725,21 13.663,19.562Q10.6,18.125 8.238,15.762Q5.875,13.4 4.438,10.337Q3,7.275 3,4.05Q3,3.6 3.3,3.3Q3.6,3 4.05,3H8.1Q8.45,3 8.725,3.225Q9,3.45 9.05,3.8L9.7,7.3Q9.75,7.65 9.688,7.937Q9.625,8.225 9.4,8.45L7,10.9Q8.05,12.7 9.625,14.275Q11.2,15.85 13.1,17L15.45,14.65Q15.675,14.425 16.038,14.312Q16.4,14.2 16.75,14.25L20.2,14.95Q20.55,15.025 20.775,15.287Q21,15.55 21,15.9V19.95Q21,20.4 20.7,20.7Q20.4,21 19.95,21Z"/>
+</vector> \ No newline at end of file
diff --git a/packages/CompanionDeviceManager/res/drawable/ic_permission_sms.xml b/packages/CompanionDeviceManager/res/drawable/ic_permission_sms.xml
new file mode 100644
index 000000000000..7f76a60000de
--- /dev/null
+++ b/packages/CompanionDeviceManager/res/drawable/ic_permission_sms.xml
@@ -0,0 +1,25 @@
+<!--
+ ~ Copyright (C) 2022 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24"
+ android:tint="@android:color/system_accent1_600">
+ <path android:fillColor="@android:color/white"
+ android:pathData="M8,11Q8.425,11 8.713,10.712Q9,10.425 9,10Q9,9.575 8.713,9.287Q8.425,9 8,9Q7.575,9 7.287,9.287Q7,9.575 7,10Q7,10.425 7.287,10.712Q7.575,11 8,11ZM12,11Q12.425,11 12.713,10.712Q13,10.425 13,10Q13,9.575 12.713,9.287Q12.425,9 12,9Q11.575,9 11.288,9.287Q11,9.575 11,10Q11,10.425 11.288,10.712Q11.575,11 12,11ZM16,11Q16.425,11 16.712,10.712Q17,10.425 17,10Q17,9.575 16.712,9.287Q16.425,9 16,9Q15.575,9 15.288,9.287Q15,9.575 15,10Q15,10.425 15.288,10.712Q15.575,11 16,11ZM2,22V4Q2,3.175 2.588,2.587Q3.175,2 4,2H20Q20.825,2 21.413,2.587Q22,3.175 22,4V16Q22,16.825 21.413,17.413Q20.825,18 20,18H6ZM4,16H20Q20,16 20,16Q20,16 20,16V4Q20,4 20,4Q20,4 20,4H4Q4,4 4,4Q4,4 4,4V16ZM4,16V4Q4,4 4,4Q4,4 4,4Q4,4 4,4Q4,4 4,4V16Q4,16 4,16Q4,16 4,16Z"/>
+</vector> \ No newline at end of file
diff --git a/packages/CompanionDeviceManager/res/drawable/ic_storage.xml b/packages/CompanionDeviceManager/res/drawable/ic_permission_storage.xml
index 3e033d372e72..3e033d372e72 100644
--- a/packages/CompanionDeviceManager/res/drawable/ic_storage.xml
+++ b/packages/CompanionDeviceManager/res/drawable/ic_permission_storage.xml
diff --git a/packages/CompanionDeviceManager/res/drawable/ic_permission_watch.xml b/packages/CompanionDeviceManager/res/drawable/ic_permission_watch.xml
new file mode 100644
index 000000000000..dd247ee3b7f3
--- /dev/null
+++ b/packages/CompanionDeviceManager/res/drawable/ic_permission_watch.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2022 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24"
+ android:tint="?attr/colorControlNormal">
+ <path android:fillColor="@android:color/white" android:pathData="M9,22 L7.65,17.45Q6.45,16.5 5.725,15.075Q5,13.65 5,12Q5,10.35 5.725,8.925Q6.45,7.5 7.65,6.55L9,2H15L16.35,6.55Q17.55,7.5 18.275,8.925Q19,10.35 19,12Q19,13.65 18.275,15.075Q17.55,16.5 16.35,17.45L15,22ZM12,17Q14.075,17 15.538,15.537Q17,14.075 17,12Q17,9.925 15.538,8.462Q14.075,7 12,7Q9.925,7 8.463,8.462Q7,9.925 7,12Q7,14.075 8.463,15.537Q9.925,17 12,17Z"/>
+</vector> \ No newline at end of file
diff --git a/packages/CompanionDeviceManager/res/layout/activity_confirmation.xml b/packages/CompanionDeviceManager/res/layout/activity_confirmation.xml
index 520ade892f51..22805f62c449 100644
--- a/packages/CompanionDeviceManager/res/layout/activity_confirmation.xml
+++ b/packages/CompanionDeviceManager/res/layout/activity_confirmation.xml
@@ -57,36 +57,39 @@
android:layout_height="0dp"
android:layout_weight="1">
- <LinearLayout
- android:id="@+id/multiple_device_list"
+ <androidx.constraintlayout.widget.ConstraintLayout
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:id="@+id/constraint_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginTop="12dp"
- android:layout_marginBottom="12dp"
- android:orientation="vertical"
android:visibility="gone">
- <View
- android:id="@+id/border_top"
- style="@style/DeviceListBorder" />
-
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/device_list"
android:layout_width="match_parent"
+ android:layout_height="200dp"
+ android:scrollbars="vertical"
+ android:visibility="gone" />
+
+ <androidx.recyclerview.widget.RecyclerView
+ android:id="@+id/permission_list"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
android:scrollbars="vertical"
- android:layout_marginBottom="12dp"
- android:layout_height="200dp" />
+ android:fadeScrollbars="false"
+ app:layout_constraintHeight_max="220dp"
+ android:visibility="gone" />
<View
- android:id="@+id/border_bottom"
+ android:id="@+id/border_top"
style="@style/DeviceListBorder" />
- </LinearLayout>
+ <View
+ android:id="@+id/border_bottom"
+ app:layout_constraintBottom_toBottomOf="parent"
+ style="@style/DeviceListBorder" />
- <androidx.recyclerview.widget.RecyclerView
- android:id="@+id/permission_list"
- android:layout_width="match_parent"
- android:layout_height="wrap_content" />
+ </androidx.constraintlayout.widget.ConstraintLayout>
<ProgressBar
android:id="@+id/spinner_multiple_device"
@@ -132,6 +135,8 @@
style="@style/NegativeButtonMultipleDevices"
android:textColor="?android:textColorPrimary"
android:visibility="gone"
+ android:layout_marginTop="12dp"
+ android:layout_marginBottom="12dp"
android:text="@string/consent_no" />
</LinearLayout>
diff --git a/packages/CompanionDeviceManager/res/layout/helper_confirmation.xml b/packages/CompanionDeviceManager/res/layout/helper_confirmation.xml
index 1f922b97bfc4..ddff2cb6ab13 100644
--- a/packages/CompanionDeviceManager/res/layout/helper_confirmation.xml
+++ b/packages/CompanionDeviceManager/res/layout/helper_confirmation.xml
@@ -46,6 +46,7 @@
android:layout_height="wrap_content"
android:gravity="center"
android:textColor="?android:attr/textColorPrimary"
+ style="@style/TextAppearance"
android:textSize="22sp" />
<TextView
@@ -58,6 +59,7 @@
android:layout_marginBottom="32dp"
android:gravity="center"
android:textColor="?android:attr/textColorSecondary"
+ style="@style/TextAppearance"
android:textSize="14sp" />
<LinearLayout
@@ -70,6 +72,7 @@
<Button
android:id="@+id/btn_back"
style="@style/VendorHelperBackButton"
+ android:textAppearance="@android:style/TextAppearance.DeviceDefault.Medium"
android:text="@string/consent_back" />
</LinearLayout>
diff --git a/packages/CompanionDeviceManager/res/layout/list_item_device.xml b/packages/CompanionDeviceManager/res/layout/list_item_device.xml
index d4439f9e7e64..ac5294ad373a 100644
--- a/packages/CompanionDeviceManager/res/layout/list_item_device.xml
+++ b/packages/CompanionDeviceManager/res/layout/list_item_device.xml
@@ -39,6 +39,6 @@
android:layout_height="wrap_content"
android:paddingStart="24dp"
android:paddingEnd="24dp"
- android:textAppearance="?android:attr/textAppearanceListItemSmall"/>
+ style="@style/TextAppearance"/>
</LinearLayout>
diff --git a/packages/CompanionDeviceManager/res/layout/list_item_permission.xml b/packages/CompanionDeviceManager/res/layout/list_item_permission.xml
index a3d71b953be0..ab2d815063eb 100644
--- a/packages/CompanionDeviceManager/res/layout/list_item_permission.xml
+++ b/packages/CompanionDeviceManager/res/layout/list_item_permission.xml
@@ -34,26 +34,43 @@
android:contentDescription="@null"/>
<LinearLayout
- android:layout_width="match_parent"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center_vertical"
- android:padding="6dp">
+ android:padding="6dp"
+ android:layout_weight="1">
<TextView
android:id="@+id/permission_name"
- android:layout_width="match_parent"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"
- android:textAppearance="?android:attr/textAppearanceListItemSmall"/>
+ android:layout_marginTop="2dp"
+ style="@style/TextAppearance"
+ android:textColor="?android:attr/textColorPrimary"/>
<TextView
android:id="@+id/permission_summary"
- android:layout_width="match_parent"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="14sp"
+ android:layout_marginTop="2dp"
+ style="@style/TextAppearance"
android:textColor="?android:attr/textColorSecondary"/>
</LinearLayout>
+ <ImageButton
+ android:id="@+id/permission_expand_button"
+ android:layout_width="24dp"
+ android:layout_height="24dp"
+ android:src="@drawable/btn_expand_more"
+ android:layout_marginTop="8dp"
+ android:layout_marginStart="24dp"
+ android:background="@android:color/transparent"
+ android:clickable="false"
+ android:importantForAccessibility="no"
+ android:contentDescription="@null"/>
+
</LinearLayout> \ No newline at end of file
diff --git a/packages/CompanionDeviceManager/res/values/strings.xml b/packages/CompanionDeviceManager/res/values/strings.xml
index 83dbbf32377b..97201e203463 100644
--- a/packages/CompanionDeviceManager/res/values/strings.xml
+++ b/packages/CompanionDeviceManager/res/values/strings.xml
@@ -31,15 +31,12 @@
<string name="chooser_title">Choose a <xliff:g id="profile_name" example="watch">%1$s</xliff:g> to be managed by &lt;strong&gt;<xliff:g id="app_name" example="Android Wear">%2$s</xliff:g>&lt;/strong&gt;</string>
<!-- Description of the privileges the application will get if associated with the companion device of WATCH profile (type) [CHAR LIMIT=NONE] -->
- <string name="summary_watch">This app is needed to manage your <xliff:g id="device_name" example="My Watch">%1$s</xliff:g>. <xliff:g id="app_name" example="Android Wear">%2$s</xliff:g> will be allowed to interact with your notifications and access your Phone, SMS, Contacts, Calendar, Call logs and Nearby devices permissions.</string>
+ <string name="summary_watch">The app is needed to manage your <xliff:g id="device_name" example="My Watch">%1$s</xliff:g>. <xliff:g id="app_name" example="Android Wear">%2$s</xliff:g> will be allowed to interact with your notifications and access your Phone, SMS, Contacts, Calendar, Call logs and Nearby devices permissions.</string>
- <!-- ================= DEVICE_PROFILE_APP_STREAMING ================= -->
-
- <!-- Apps permission will be granted of APP_STREAMING profile [CHAR LIMIT=30] -->
- <string name="permission_apps">Apps</string>
+ <!-- Description of the privileges the application will get if associated with the companion device of WATCH profile for singleDevice(type) [CHAR LIMIT=NONE] -->
+ <string name="summary_watch_single_device">The app is needed to manage your <xliff:g id="device_name" example="My Watch">%1$s</xliff:g>. <xliff:g id="app_name" example="Android Wear">%2$s</xliff:g> will be allowed to interact with these permissions:</string>
- <!-- Description of apps permission of APP_STREAMING profile [CHAR LIMIT=NONE] -->
- <string name="permission_apps_summary">Stream your phone\u2019s apps</string>
+ <!-- ================= DEVICE_PROFILE_APP_STREAMING ================= -->
<!-- Confirmation for associating an application with a companion device of APP_STREAMING profile (type) [CHAR LIMIT=NONE] -->
<string name="title_app_streaming">Allow &lt;strong&gt;<xliff:g id="app_name" example="Exo">%1$s</xliff:g>&lt;/strong&gt; to access this information from your phone</string>
@@ -66,18 +63,6 @@
<!-- Description of the privileges the application will get if associated with the companion device of COMPUTER profile (type) [CHAR LIMIT=NONE] -->
<string name="summary_computer"></string>
- <!-- Notification permission will be granted of COMPUTER profile [CHAR LIMIT=30] -->
- <string name="permission_notification">Notifications</string>
-
- <!-- Description of notification permission of COMPUTER profile [CHAR LIMIT=NONE] -->
- <string name="permission_notification_summary">Can read all notifications, including information like contacts, messages, and photos</string>
-
- <!-- Storage permission will be granted of COMPUTER profile [CHAR LIMIT=30] -->
- <string name="permission_storage">Photos and media</string>
-
- <!-- Description of storage permission of COMPUTER profile [CHAR LIMIT=NONE] -->
- <string name="permission_storage_summary"></string>
-
<!-- Title of the helper dialog for COMPUTER profile [CHAR LIMIT=30]. -->
<string name="helper_title_computer">Google Play services</string>
@@ -117,4 +102,57 @@
<!--Description for information icon [CHAR LIMIT=30]-->
<string name="vendor_header_button_description">More Information Button</string>
+ <!-- ================= Permissions ================= -->
+
+ <!-- Phone permission will be granted of corresponding profile [CHAR LIMIT=30] -->
+ <string name="permission_phone">Phone</string>
+
+ <!-- SMS permission will be granted of corresponding profile [CHAR LIMIT=30] -->
+ <string name="permission_sms">SMS</string>
+
+ <!-- Contacts permission will be granted of corresponding profile [CHAR LIMIT=30] -->
+ <string name="permission_contacts">Contacts</string>
+
+ <!-- Calendar permission will be granted of corresponding profile [CHAR LIMIT=30] -->
+ <string name="permission_calendar">Calendar</string>
+
+ <!-- Calendar permission will be granted of corresponding profile [CHAR LIMIT=30] -->
+ <string name="permission_nearby_devices">Nearby devices</string>
+
+ <!-- Storage permission will be granted of corresponding profile [CHAR LIMIT=30] -->
+ <string name="permission_storage">Photos and media</string>
+
+ <!-- Notification permission will be granted of corresponding profile [CHAR LIMIT=30] -->
+ <string name="permission_notification">Notifications</string>
+
+ <!-- Apps permission will be granted of corresponding profile [CHAR LIMIT=30] -->
+ <string name="permission_app_streaming">Apps</string>
+
+ <!-- Description of phone permission of corresponding profile [CHAR LIMIT=NONE] -->
+ <string name="permission_phone_summary">Can access your phone number and network info. Required for making calls and VoIP, voicemail, call redirect, and editing call logs</string>
+
+ <!-- Description of SMS permission of corresponding profile [CHAR LIMIT=NONE] -->
+ <!-- TODO(b/253644212) Need the description for sms permission -->
+ <string name="permission_sms_summary"></string>
+
+ <!-- Description of contacts permission of corresponding profile [CHAR LIMIT=NONE] -->
+ <string name="permission_contacts_summary">Can read, create, or edit our contact list, as well as access the list of all accounts used on your device</string>
+
+ <!-- Description of calendar permission of corresponding profile [CHAR LIMIT=NONE] -->
+ <!-- TODO(b/253644212) Need the description for calendar permission -->
+ <string name="permission_calendar_summary"></string>
+
+ <!-- Description of nearby devices' permission of corresponding profile [CHAR LIMIT=NONE] -->
+ <!-- TODO(b/253644212) Need the description for nearby devices' permission -->
+ <string name="permission_nearby_devices_summary"></string>
+
+ <!-- Description of notification permission of corresponding profile [CHAR LIMIT=NONE] -->
+ <string name="permission_notification_summary">Can read all notifications, including information like contacts, messages, and photos</string>
+
+ <!-- Description of app streaming permission of corresponding profile [CHAR LIMIT=NONE] -->
+ <string name="permission_app_streaming_summary">Stream your phone\u2019s apps</string>
+
+ <!-- Description of storage permission of corresponding profile [CHAR LIMIT=NONE] -->
+ <string name="permission_storage_summary"></string>
+
</resources>
diff --git a/packages/CompanionDeviceManager/res/values/styles.xml b/packages/CompanionDeviceManager/res/values/styles.xml
index 2000d9675ca4..3c75cd5b8668 100644
--- a/packages/CompanionDeviceManager/res/values/styles.xml
+++ b/packages/CompanionDeviceManager/res/values/styles.xml
@@ -36,7 +36,7 @@
</style>
<style name="DescriptionTitle"
- parent="@*android:style/TextAppearance.Widget.Toolbar.Title">
+ parent="@android:style/TextAppearance.DeviceDefault.Medium">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:gravity">center</item>
@@ -46,7 +46,8 @@
<item name="android:textColor">?android:attr/textColorPrimary</item>
</style>
- <style name="DescriptionSummary">
+ <style name="DescriptionSummary"
+ parent="@android:style/TextAppearance.DeviceDefault.Medium">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_marginTop">18dp</item>
@@ -61,6 +62,7 @@
<item name="android:layout_width">70dp</item>
<item name="android:layout_height">48dp</item>
<item name="android:textAllCaps">false</item>
+ <item name="android:textSize">14sp</item>
<item name="android:textColor">@android:color/system_neutral1_900</item>
<item name="android:background">@drawable/helper_back_button</item>
</style>
@@ -73,6 +75,7 @@
<item name="android:textAllCaps">false</item>
<item name="android:textSize">14sp</item>
<item name="android:textColor">@android:color/system_neutral1_900</item>
+ <item name="android:textAppearance">@android:style/TextAppearance.DeviceDefault.Medium</item>
<item name="android:background">@drawable/btn_positive_bottom</item>
</style>
@@ -85,6 +88,7 @@
<item name="android:textSize">14sp</item>
<item name="android:textColor">@android:color/system_neutral1_900</item>
<item name="android:layout_marginTop">4dp</item>
+ <item name="android:textAppearance">@android:style/TextAppearance.DeviceDefault.Medium</item>
<item name="android:background">@drawable/btn_negative_top</item>
</style>
@@ -93,13 +97,17 @@
<item name="android:layout_width">100dp</item>
<item name="android:layout_height">36dp</item>
<item name="android:textAllCaps">false</item>
+ <item name="android:textSize">14sp</item>
+ <item name="android:textAppearance">@android:style/TextAppearance.DeviceDefault.Medium</item>
<item name="android:background">@drawable/btn_negative_multiple_devices</item>
</style>
<style name="DeviceListBorder">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">1dp</item>
- <item name="android:background">@android:color/system_accent1_300</item>
+ <item name="android:layout_marginStart">32dp</item>
+ <item name="android:layout_marginEnd">32dp</item>
+ <item name="android:background">@android:color/system_neutral1_200</item>
</style>
<style name="Spinner"
@@ -115,4 +123,9 @@
<item name="android:fillViewport">true</item>
<item name="android:clipChildren">false</item>
</style>
+
+ <style name="TextAppearance">
+ <item name="android:textAppearance">@android:style/TextAppearance.DeviceDefault.Medium</item>
+ </style>
+
</resources> \ No newline at end of file
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java
index 723c59ae1b9c..3a3a5d20b47c 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java
@@ -31,9 +31,14 @@ import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTE
import static com.android.companiondevicemanager.CompanionDeviceDiscoveryService.DiscoveryState;
import static com.android.companiondevicemanager.CompanionDeviceDiscoveryService.DiscoveryState.FINISHED_TIMEOUT;
-import static com.android.companiondevicemanager.PermissionListAdapter.TYPE_APPS;
-import static com.android.companiondevicemanager.PermissionListAdapter.TYPE_NOTIFICATION;
-import static com.android.companiondevicemanager.PermissionListAdapter.TYPE_STORAGE;
+import static com.android.companiondevicemanager.PermissionListAdapter.PERMISSION_APP_STREAMING;
+import static com.android.companiondevicemanager.PermissionListAdapter.PERMISSION_CALENDAR;
+import static com.android.companiondevicemanager.PermissionListAdapter.PERMISSION_CONTACTS;
+import static com.android.companiondevicemanager.PermissionListAdapter.PERMISSION_NEARBY_DEVICES;
+import static com.android.companiondevicemanager.PermissionListAdapter.PERMISSION_NOTIFICATION;
+import static com.android.companiondevicemanager.PermissionListAdapter.PERMISSION_PHONE;
+import static com.android.companiondevicemanager.PermissionListAdapter.PERMISSION_SMS;
+import static com.android.companiondevicemanager.PermissionListAdapter.PERMISSION_STORAGE;
import static com.android.companiondevicemanager.Utils.getApplicationLabel;
import static com.android.companiondevicemanager.Utils.getHtmlFromResources;
import static com.android.companiondevicemanager.Utils.getIcon;
@@ -55,6 +60,9 @@ import android.companion.IAssociationRequestCallback;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
+import android.graphics.BlendMode;
+import android.graphics.BlendModeColorFilter;
+import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.net.MacAddress;
import android.os.Bundle;
@@ -64,6 +72,7 @@ import android.os.ResultReceiver;
import android.text.Spanned;
import android.util.Log;
import android.view.View;
+import android.view.ViewTreeObserver;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ImageView;
@@ -72,12 +81,14 @@ import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
+import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
/**
@@ -140,8 +151,14 @@ public class CompanionDeviceActivity extends FragmentActivity implements
// Present for multiple devices' association requests only.
private Button mButtonNotAllowMultipleDevices;
+ // Present for top and bottom borders for permissions list and device list.
+ private View mBorderTop;
+ private View mBorderBottom;
+
private LinearLayout mAssociationConfirmationDialog;
- private LinearLayout mMultipleDeviceList;
+ // Contains device list, permission list and top/bottom borders.
+ private ConstraintLayout mConstraintList;
+ // Only present for self-managed association requests.
private RelativeLayout mVendorHeader;
// The recycler view is only shown for multiple-device regular association request, after
@@ -150,7 +167,7 @@ public class CompanionDeviceActivity extends FragmentActivity implements
private @Nullable DeviceListAdapter mDeviceAdapter;
- // The recycler view is only shown for selfManaged association request.
+ // The recycler view is only shown for selfManaged and singleDevice association request.
private @Nullable RecyclerView mPermissionListRecyclerView;
private @Nullable PermissionListAdapter mPermissionListAdapter;
@@ -164,6 +181,8 @@ public class CompanionDeviceActivity extends FragmentActivity implements
private @Nullable List<Integer> mPermissionTypes;
+ private LinearLayoutManager mPermissionsLayoutManager = new LinearLayoutManager(this);
+
@Override
public void onCreate(Bundle savedInstanceState) {
if (DEBUG) Log.d(TAG, "onCreate()");
@@ -212,7 +231,6 @@ public class CompanionDeviceActivity extends FragmentActivity implements
boolean forCancelDialog = intent.getBooleanExtra(EXTRA_FORCE_CANCEL_CONFIRMATION, false);
if (forCancelDialog) {
-
Log.i(TAG, "Cancelling the user confirmation");
cancel(/* discoveryTimeOut */ false,
@@ -285,10 +303,13 @@ public class CompanionDeviceActivity extends FragmentActivity implements
setContentView(R.layout.activity_confirmation);
- mMultipleDeviceList = findViewById(R.id.multiple_device_list);
+ mConstraintList = findViewById(R.id.constraint_list);
mAssociationConfirmationDialog = findViewById(R.id.association_confirmation);
mVendorHeader = findViewById(R.id.vendor_header);
+ mBorderTop = findViewById(R.id.border_top);
+ mBorderBottom = findViewById(R.id.border_bottom);
+
mTitle = findViewById(R.id.title);
mSummary = findViewById(R.id.summary);
@@ -463,10 +484,11 @@ public class CompanionDeviceActivity extends FragmentActivity implements
return;
}
+ // TODO(b/253644212): Add maps for profile -> title, summary, permissions
switch (deviceProfile) {
case DEVICE_PROFILE_APP_STREAMING:
title = getHtmlFromResources(this, R.string.title_app_streaming, deviceName);
- mPermissionTypes.add(TYPE_APPS);
+ mPermissionTypes.add(PERMISSION_APP_STREAMING);
break;
case DEVICE_PROFILE_AUTOMOTIVE_PROJECTION:
@@ -476,25 +498,27 @@ public class CompanionDeviceActivity extends FragmentActivity implements
case DEVICE_PROFILE_COMPUTER:
title = getHtmlFromResources(this, R.string.title_computer, deviceName);
- mPermissionTypes.add(TYPE_NOTIFICATION);
- mPermissionTypes.add(TYPE_STORAGE);
+ mPermissionTypes.addAll(Arrays.asList(PERMISSION_NOTIFICATION, PERMISSION_STORAGE));
break;
default:
throw new RuntimeException("Unsupported profile " + deviceProfile);
}
+ // Summary is not needed for selfManaged dialog.
mSummary.setVisibility(View.GONE);
- mPermissionListAdapter.setPermissionType(mPermissionTypes);
- mPermissionListRecyclerView.setAdapter(mPermissionListAdapter);
- mPermissionListRecyclerView.setLayoutManager(new LinearLayoutManager(this));
+ setupPermissionList();
mTitle.setText(title);
mVendorHeaderName.setText(vendorName);
- mDeviceListRecyclerView.setVisibility(View.GONE);
- mProfileIcon.setVisibility(View.GONE);
mVendorHeader.setVisibility(View.VISIBLE);
+ mVendorHeader.setVisibility(View.VISIBLE);
+ mProfileIcon.setVisibility(View.GONE);
+ mDeviceListRecyclerView.setVisibility(View.GONE);
+ // Top and bottom borders should be gone for selfManaged dialog.
+ mBorderTop.setVisibility(View.GONE);
+ mBorderBottom.setVisibility(View.GONE);
}
private void initUiForSingleDevice(CharSequence appLabel) {
@@ -502,11 +526,15 @@ public class CompanionDeviceActivity extends FragmentActivity implements
final String deviceProfile = mRequest.getDeviceProfile();
+ mPermissionTypes = new ArrayList<>();
+
CompanionDeviceDiscoveryService.getScanResult().observe(this,
deviceFilterPairs -> updateSingleDeviceUi(
deviceFilterPairs, deviceProfile, appLabel));
mSingleDeviceSpinner.setVisibility(View.VISIBLE);
+ // Hide permission list and confirmation dialog first before the
+ // first matched device is found.
mPermissionListRecyclerView.setVisibility(View.GONE);
mDeviceListRecyclerView.setVisibility(View.GONE);
mAssociationConfirmationDialog.setVisibility(View.GONE);
@@ -537,11 +565,20 @@ public class CompanionDeviceActivity extends FragmentActivity implements
title = getHtmlFromResources(this, R.string.confirmation_title, appLabel, deviceName);
summary = getHtmlFromResources(this, R.string.summary_generic);
profileIcon = getIcon(this, R.drawable.ic_device_other);
+ // Summary is not needed for null profile.
mSummary.setVisibility(View.GONE);
+ mConstraintList.setVisibility(View.GONE);
} else if (deviceProfile.equals(DEVICE_PROFILE_WATCH)) {
- title = getHtmlFromResources(this, R.string.confirmation_title, appLabel, profileName);
- summary = getHtmlFromResources(this, R.string.summary_watch, deviceName, appLabel);
+ title = getHtmlFromResources(this, R.string.confirmation_title, appLabel, deviceName);
+ summary = getHtmlFromResources(
+ this, R.string.summary_watch_single_device, profileName, appLabel);
profileIcon = getIcon(this, R.drawable.ic_watch);
+
+ mPermissionTypes.addAll(Arrays.asList(
+ PERMISSION_NOTIFICATION, PERMISSION_PHONE, PERMISSION_SMS, PERMISSION_CONTACTS,
+ PERMISSION_CALENDAR, PERMISSION_NEARBY_DEVICES));
+
+ setupPermissionList();
} else {
throw new RuntimeException("Unsupported profile " + deviceProfile);
}
@@ -596,8 +633,9 @@ public class CompanionDeviceActivity extends FragmentActivity implements
// "Remove" consent button: users would need to click on the list item.
mButtonAllow.setVisibility(View.GONE);
mButtonNotAllow.setVisibility(View.GONE);
+ mDeviceListRecyclerView.setVisibility(View.VISIBLE);
mButtonNotAllowMultipleDevices.setVisibility(View.VISIBLE);
- mMultipleDeviceList.setVisibility(View.VISIBLE);
+ mConstraintList.setVisibility(View.VISIBLE);
mMultipleDeviceSpinner.setVisibility(View.VISIBLE);
}
@@ -654,6 +692,80 @@ public class CompanionDeviceActivity extends FragmentActivity implements
return mApproved || mCancelled;
}
+ // Set up the mPermissionListRecyclerView, including set up the adapter,
+ // initiate the layoutManager for the recyclerview, add listeners for monitoring the scrolling
+ // and when mPermissionListRecyclerView is fully populated.
+ // Lastly, disable the Allow and Don't allow buttons.
+ private void setupPermissionList() {
+ mPermissionListAdapter.setPermissionType(mPermissionTypes);
+ mPermissionListRecyclerView.setAdapter(mPermissionListAdapter);
+ mPermissionListRecyclerView.setLayoutManager(mPermissionsLayoutManager);
+
+ disableButtons();
+
+ // Enable buttons once users scroll down to the bottom of the permission list.
+ mPermissionListRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
+ @Override
+ public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
+ super.onScrollStateChanged(recyclerView, newState);
+ if (!recyclerView.canScrollVertically(1)) {
+ enableButtons();
+ }
+ }
+ });
+ // Enable buttons if last item in the permission list is visible to the users when
+ // mPermissionListRecyclerView is fully populated.
+ mPermissionListRecyclerView.getViewTreeObserver().addOnGlobalLayoutListener(
+ new ViewTreeObserver.OnGlobalLayoutListener() {
+ @Override
+ public void onGlobalLayout() {
+ LinearLayoutManager layoutManager =
+ (LinearLayoutManager) mPermissionListRecyclerView
+ .getLayoutManager();
+ int lastVisibleItemPosition =
+ layoutManager.findLastCompletelyVisibleItemPosition();
+ int numItems = mPermissionListRecyclerView.getAdapter().getItemCount();
+
+ if (lastVisibleItemPosition >= numItems - 1) {
+ enableButtons();
+ }
+
+ mPermissionListRecyclerView.getViewTreeObserver()
+ .removeOnGlobalLayoutListener(this);
+ }
+ });
+
+ mConstraintList.setVisibility(View.VISIBLE);
+ mPermissionListRecyclerView.setVisibility(View.VISIBLE);
+ }
+
+ // Disable and grey out the Allow and Don't allow buttons if the last permission in the
+ // permission list is not visible to the users.
+ private void disableButtons() {
+ mButtonAllow.setEnabled(false);
+ mButtonNotAllow.setEnabled(false);
+ mButtonAllow.setTextColor(
+ getResources().getColor(android.R.color.system_neutral1_400, null));
+ mButtonNotAllow.setTextColor(
+ getResources().getColor(android.R.color.system_neutral1_400, null));
+ mButtonAllow.getBackground().setColorFilter(
+ (new BlendModeColorFilter(Color.LTGRAY, BlendMode.DARKEN)));
+ mButtonNotAllow.getBackground().setColorFilter(
+ (new BlendModeColorFilter(Color.LTGRAY, BlendMode.DARKEN)));
+ }
+ // Enable and restore the color for the Allow and Don't allow buttons if the last permission in
+ // the permission list is visible to the users.
+ private void enableButtons() {
+ mButtonAllow.setEnabled(true);
+ mButtonNotAllow.setEnabled(true);
+ mButtonAllow.getBackground().setColorFilter(null);
+ mButtonNotAllow.getBackground().setColorFilter(null);
+ mButtonAllow.setTextColor(
+ getResources().getColor(android.R.color.system_neutral1_900, null));
+ mButtonNotAllow.setTextColor(
+ getResources().getColor(android.R.color.system_neutral1_900, null));
+ }
+
private final ResultReceiver mOnAssociationCreatedReceiver =
new ResultReceiver(Handler.getMain()) {
@Override
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/PermissionListAdapter.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/PermissionListAdapter.java
index 895b729ea8c7..0ee94a2c3921 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/PermissionListAdapter.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/PermissionListAdapter.java
@@ -27,6 +27,7 @@ import android.util.ArrayMap;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
@@ -37,37 +38,58 @@ import java.util.Map;
class PermissionListAdapter extends RecyclerView.Adapter<PermissionListAdapter.ViewHolder> {
private final Context mContext;
-
private List<Integer> mPermissions;
-
- static final int TYPE_NOTIFICATION = 0;
- static final int TYPE_STORAGE = 1;
- static final int TYPE_APPS = 2;
+ // Add the expand buttons if permissions are more than PERMISSION_SIZE in the permission list.
+ private static final int PERMISSION_SIZE = 2;
+
+ static final int PERMISSION_NOTIFICATION = 0;
+ static final int PERMISSION_STORAGE = 1;
+ static final int PERMISSION_APP_STREAMING = 2;
+ static final int PERMISSION_PHONE = 3;
+ static final int PERMISSION_SMS = 4;
+ static final int PERMISSION_CONTACTS = 5;
+ static final int PERMISSION_CALENDAR = 6;
+ static final int PERMISSION_NEARBY_DEVICES = 7;
private static final Map<Integer, Integer> sTitleMap;
static {
final Map<Integer, Integer> map = new ArrayMap<>();
- map.put(TYPE_NOTIFICATION, R.string.permission_notification);
- map.put(TYPE_STORAGE, R.string.permission_storage);
- map.put(TYPE_APPS, R.string.permission_apps);
+ map.put(PERMISSION_NOTIFICATION, R.string.permission_notification);
+ map.put(PERMISSION_STORAGE, R.string.permission_storage);
+ map.put(PERMISSION_APP_STREAMING, R.string.permission_app_streaming);
+ map.put(PERMISSION_PHONE, R.string.permission_phone);
+ map.put(PERMISSION_SMS, R.string.permission_sms);
+ map.put(PERMISSION_CONTACTS, R.string.permission_contacts);
+ map.put(PERMISSION_CALENDAR, R.string.permission_calendar);
+ map.put(PERMISSION_NEARBY_DEVICES, R.string.permission_nearby_devices);
sTitleMap = unmodifiableMap(map);
}
private static final Map<Integer, Integer> sSummaryMap;
static {
final Map<Integer, Integer> map = new ArrayMap<>();
- map.put(TYPE_NOTIFICATION, R.string.permission_notification_summary);
- map.put(TYPE_STORAGE, R.string.permission_storage_summary);
- map.put(TYPE_APPS, R.string.permission_apps_summary);
+ map.put(PERMISSION_NOTIFICATION, R.string.permission_notification_summary);
+ map.put(PERMISSION_STORAGE, R.string.permission_storage_summary);
+ map.put(PERMISSION_APP_STREAMING, R.string.permission_app_streaming_summary);
+ map.put(PERMISSION_PHONE, R.string.permission_phone_summary);
+ map.put(PERMISSION_SMS, R.string.permission_sms_summary);
+ map.put(PERMISSION_CONTACTS, R.string.permission_contacts_summary);
+ map.put(PERMISSION_CALENDAR, R.string.permission_calendar_summary);
+ map.put(PERMISSION_NEARBY_DEVICES, R.string.permission_nearby_devices_summary);
sSummaryMap = unmodifiableMap(map);
}
private static final Map<Integer, Integer> sIconMap;
static {
final Map<Integer, Integer> map = new ArrayMap<>();
- map.put(TYPE_NOTIFICATION, R.drawable.ic_notifications);
- map.put(TYPE_STORAGE, R.drawable.ic_storage);
- map.put(TYPE_APPS, R.drawable.ic_apps);
+ map.put(PERMISSION_NOTIFICATION, R.drawable.ic_permission_notifications);
+ map.put(PERMISSION_STORAGE, R.drawable.ic_permission_storage);
+ map.put(PERMISSION_APP_STREAMING, R.drawable.ic_permission_app_streaming);
+ map.put(PERMISSION_PHONE, R.drawable.ic_permission_phone);
+ map.put(PERMISSION_SMS, R.drawable.ic_permission_sms);
+ map.put(PERMISSION_CONTACTS, R.drawable.ic_permission_contacts);
+ map.put(PERMISSION_CALENDAR, R.drawable.ic_permission_calendar);
+ map.put(PERMISSION_NEARBY_DEVICES, R.drawable.ic_permission_nearby_devices);
sIconMap = unmodifiableMap(map);
}
@@ -82,6 +104,29 @@ class PermissionListAdapter extends RecyclerView.Adapter<PermissionListAdapter.V
ViewHolder viewHolder = new ViewHolder(view);
viewHolder.mPermissionIcon.setImageDrawable(getIcon(mContext, sIconMap.get(viewType)));
+ if (viewHolder.mExpandButton.getTag() == null) {
+ viewHolder.mExpandButton.setTag(R.drawable.btn_expand_more);
+ }
+ // Add expand buttons if the permissions are more than PERMISSION_SIZE in this list.
+ if (mPermissions.size() > PERMISSION_SIZE) {
+ view.setOnClickListener(v -> {
+ if ((Integer) viewHolder.mExpandButton.getTag() == R.drawable.btn_expand_more) {
+ viewHolder.mExpandButton.setImageResource(R.drawable.btn_expand_less);
+
+ if (viewHolder.mSummary != null) {
+ viewHolder.mPermissionSummary.setText(viewHolder.mSummary);
+ }
+
+ viewHolder.mPermissionSummary.setVisibility(View.VISIBLE);
+ viewHolder.mExpandButton.setTag(R.drawable.btn_expand_less);
+ } else {
+ viewHolder.mExpandButton.setImageResource(R.drawable.btn_expand_more);
+ viewHolder.mPermissionSummary.setVisibility(View.GONE);
+ viewHolder.mExpandButton.setTag(R.drawable.btn_expand_more);
+ }
+ });
+ }
+
return viewHolder;
}
@@ -91,8 +136,15 @@ class PermissionListAdapter extends RecyclerView.Adapter<PermissionListAdapter.V
final Spanned title = getHtmlFromResources(mContext, sTitleMap.get(type));
final Spanned summary = getHtmlFromResources(mContext, sSummaryMap.get(type));
+ holder.mSummary = summary;
holder.mPermissionName.setText(title);
- holder.mPermissionSummary.setText(summary);
+
+ if (mPermissions.size() <= PERMISSION_SIZE) {
+ holder.mPermissionSummary.setText(summary);
+ holder.mExpandButton.setVisibility(View.GONE);
+ } else {
+ holder.mPermissionSummary.setVisibility(View.GONE);
+ }
}
@Override
@@ -114,11 +166,14 @@ class PermissionListAdapter extends RecyclerView.Adapter<PermissionListAdapter.V
private final TextView mPermissionName;
private final TextView mPermissionSummary;
private final ImageView mPermissionIcon;
+ private final ImageButton mExpandButton;
+ private Spanned mSummary = null;
ViewHolder(View itemView) {
super(itemView);
mPermissionName = itemView.findViewById(R.id.permission_name);
mPermissionSummary = itemView.findViewById(R.id.permission_summary);
mPermissionIcon = itemView.findViewById(R.id.permission_icon);
+ mExpandButton = itemView.findViewById(R.id.permission_expand_button);
}
}
diff --git a/packages/CredentialManager/res/values/strings.xml b/packages/CredentialManager/res/values/strings.xml
index 114de89ce82a..1ee2a26d3acf 100644
--- a/packages/CredentialManager/res/values/strings.xml
+++ b/packages/CredentialManager/res/values/strings.xml
@@ -6,15 +6,21 @@
<string name="string_more_options">More options</string>
<string name="string_create_in_another_place">Create in another place</string>
<string name="string_save_to_another_place">Save to another place</string>
+ <string name="string_use_another_device">Use another device</string>
+ <string name="string_save_to_another_device">Save to another device</string>
<string name="string_no_thanks">No thanks</string>
<string name="passkey_creation_intro_title">A simple way to sign in safely</string>
<string name="passkey_creation_intro_body">Use your fingerprint, face or screen lock to sign in with a unique passkey that can’t be forgotten or stolen. Learn more</string>
- <string name="choose_provider_title">Choose your default provider</string>
- <string name="choose_provider_body">This provider will store passkeys and passwords for you and help you easily autofill and sign in. Learn more</string>
+ <string name="choose_provider_title">Choose where to <xliff:g id="createTypes">%1$s</xliff:g></string>
+ <!-- TODO: Change the wording after design is completed. -->
+ <string name="choose_provider_body">This password manager will store your passwords, passkeys, and other sign-in info to help you easily sign in. You can change where to save your sign-in info at any time.</string>
<string name="choose_create_option_passkey_title">Create a passkey in <xliff:g id="providerInfoDisplayName">%1$s</xliff:g>?</string>
<string name="choose_create_option_password_title">Save your password to <xliff:g id="providerInfoDisplayName">%1$s</xliff:g>?</string>
<string name="choose_create_option_sign_in_title">Save your sign-in info to <xliff:g id="providerInfoDisplayName">%1$s</xliff:g>?</string>
<string name="choose_sign_in_title">Use saved sign in</string>
+ <string name="create_your_passkey">create your passkey</string>
+ <string name="save_your_password">save your password</string>
+ <string name="save_your_sign_in_info">save your sign-in info</string>
<string name="create_passkey_in">Create passkey in</string>
<string name="save_password_to">Save password to</string>
<string name="save_sign_in_to">Save sign-in to</string>
@@ -29,7 +35,7 @@
<string name="password">password</string>
<string name="sign_ins">sign-ins</string>
<string name="another_device">Another device</string>
- <string name="other_password_manager">Other password manager</string>
+ <string name="other_password_manager">Other password managers</string>
<!-- TODO: Check the wording here. -->
<string name="confirm_default_or_use_once_description">This password manager will store your passwords and passkeys to help you easily sign in.</string>
<!-- Spoken content description of an element which will close the sheet when clicked. -->
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt b/packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt
index 7e69987f1bf8..2bede9acaed2 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt
@@ -17,6 +17,7 @@
package com.android.credentialmanager
import android.credentials.Credential.TYPE_PASSWORD_CREDENTIAL
+import android.app.PendingIntent
import android.app.slice.Slice
import android.app.slice.SliceSpec
import android.content.Context
@@ -32,6 +33,7 @@ import android.credentials.ui.DisabledProviderData
import android.credentials.ui.ProviderData
import android.credentials.ui.RequestInfo
import android.credentials.ui.BaseDialogResult
+import android.credentials.ui.ProviderPendingIntentResponse
import android.credentials.ui.UserSelectionDialogResult
import android.graphics.drawable.Icon
import android.os.Binder
@@ -54,7 +56,7 @@ class CredentialManagerRepo(
private val context: Context,
intent: Intent,
) {
- private val requestInfo: RequestInfo
+ val requestInfo: RequestInfo
private val providerEnabledList: List<ProviderData>
private val providerDisabledList: List<DisabledProviderData>
// TODO: require non-null.
@@ -75,7 +77,7 @@ class CredentialManagerRepo(
RequestInfo.TYPE_GET ->
intent.extras?.getParcelableArrayList(
ProviderData.EXTRA_ENABLED_PROVIDER_DATA_LIST,
- DisabledProviderData::class.java
+ GetCredentialProviderData::class.java
) ?: testGetCredentialProviderList()
else -> {
// TODO: fail gracefully
@@ -101,12 +103,19 @@ class CredentialManagerRepo(
resultReceiver?.send(BaseDialogResult.RESULT_CODE_DIALOG_CANCELED, resultData)
}
- fun onOptionSelected(providerPackageName: String, entryKey: String, entrySubkey: String) {
+ fun onOptionSelected(
+ providerPackageName: String,
+ entryKey: String,
+ entrySubkey: String,
+ resultCode: Int? = null,
+ resultData: Intent? = null,
+ ) {
val userSelectionDialogResult = UserSelectionDialogResult(
requestInfo.token,
providerPackageName,
entryKey,
- entrySubkey
+ entrySubkey,
+ if (resultCode != null) ProviderPendingIntentResponse(resultCode, resultData) else null
)
val resultData = Bundle()
UserSelectionDialogResult.addToBundle(userSelectionDialogResult, resultData)
@@ -140,8 +149,8 @@ class CredentialManagerRepo(
if (providerInfo.isDefault) {hasDefault = true; defaultProvider = providerInfo} }
// TODO: covert from real requestInfo for create passkey
var requestDisplayInfo = RequestDisplayInfo(
- "Elisa Beckett",
"beckett-bakert@gmail.com",
+ "Elisa Beckett",
TYPE_PUBLIC_KEY_CREDENTIAL,
"tribank")
val createCredentialRequest = requestInfo.createCredentialRequest
@@ -156,9 +165,14 @@ class CredentialManagerRepo(
return CreateCredentialUiState(
enabledProviders = providerEnabledList,
disabledProviders = providerDisabledList,
- if (hasDefault)
- {CreateScreenState.CREATION_OPTION_SELECTION} else {CreateScreenState.PASSKEY_INTRO},
+ // TODO: Add the screen when defaultProvider has no createOption but
+ // there's remoteInfo under other providers
+ if (!hasDefault || defaultProvider.createOptions.isEmpty()) {
+ if (requestDisplayInfo.type == TYPE_PUBLIC_KEY_CREDENTIAL)
+ {CreateScreenState.PASSKEY_INTRO} else {CreateScreenState.PROVIDER_SELECTION}
+ } else {CreateScreenState.CREATION_OPTION_SELECTION},
requestDisplayInfo,
+ false,
if (hasDefault) {
ActiveEntry(defaultProvider, defaultProvider.createOptions.first())
} else null
@@ -196,7 +210,6 @@ class CredentialManagerRepo(
.setRemoteEntry(
newRemoteEntry("key2", "subkey-1")
)
- .setIsDefaultProvider(true)
.build(),
CreateCredentialProviderData
.Builder("com.dashlane")
@@ -328,6 +341,14 @@ class CredentialManagerRepo(
userDisplayName: String?,
lastUsedTimeMillis: Long?,
): Entry {
+ val intent = Intent("com.androidauth.androidvault.CONFIRM_PASSWORD")
+ .setPackage("com.androidauth.androidvault")
+ intent.putExtra("provider_extra_sample", "testprovider")
+
+ val pendingIntent = PendingIntent.getActivity(context, 1,
+ intent, (PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
+ or PendingIntent.FLAG_ONE_SHOT))
+
val slice = Slice.Builder(
Entry.CREDENTIAL_MANAGER_ENTRY_URI, SliceSpec(credentialType, 1)
).addText(
@@ -347,7 +368,9 @@ class CredentialManagerRepo(
return Entry(
key,
subkey,
- slice.build()
+ slice.build(),
+ pendingIntent,
+ null
)
}
@@ -360,10 +383,22 @@ class CredentialManagerRepo(
totalCredentialCount: Int,
lastUsedTimeMillis: Long,
): Entry {
+ val intent = Intent("com.androidauth.androidvault.CONFIRM_PASSWORD")
+ .setPackage("com.androidauth.androidvault")
+ intent.putExtra("provider_extra_sample", "testprovider")
+ val pendingIntent = PendingIntent.getActivity(context, 1,
+ intent, (PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
+ or PendingIntent.FLAG_ONE_SHOT))
+ val createPasswordRequest = android.service.credentials.CreateCredentialRequest(
+ context.applicationInfo.packageName,
+ "PASSWORD",
+ toBundle("beckett-bakert@gmail.com", "password123")
+ )
+ val fillInIntent = Intent().putExtra("create_request_params", createPasswordRequest)
+
val slice = Slice.Builder(
Entry.CREDENTIAL_MANAGER_ENTRY_URI, SliceSpec(Entry.VERSION, 1)
- )
- .addText(
+ ).addText(
providerDisplayName, null, listOf(Entry.HINT_USER_PROVIDER_ACCOUNT_NAME))
.addIcon(
Icon.createWithResource(context, R.drawable.ic_passkey),
@@ -384,7 +419,9 @@ class CredentialManagerRepo(
return Entry(
key,
subkey,
- slice
+ slice,
+ pendingIntent,
+ fillInIntent,
)
}
@@ -406,7 +443,7 @@ class CredentialManagerRepo(
return RequestInfo.newCreateRequestInfo(
Binder(),
CreateCredentialRequest(
- TYPE_PASSWORD_CREDENTIAL,
+ TYPE_PUBLIC_KEY_CREDENTIAL,
data
),
/*isFirstUsage=*/false,
@@ -415,7 +452,6 @@ class CredentialManagerRepo(
}
private fun testGetRequestInfo(): RequestInfo {
- val data = Bundle()
return RequestInfo.newGetRequestInfo(
Binder(),
GetCredentialRequest.Builder()
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorActivity.kt b/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorActivity.kt
index 1041a33333b3..d324f875c85a 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorActivity.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorActivity.kt
@@ -16,17 +16,21 @@
package com.android.credentialmanager
-import android.credentials.ui.RequestInfo
import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
+import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.compose.setContent
+import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.material.ExperimentalMaterialApi
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
import androidx.lifecycle.Observer
import androidx.lifecycle.viewmodel.compose.viewModel
import com.android.credentialmanager.common.DialogType
import com.android.credentialmanager.common.DialogResult
+import com.android.credentialmanager.common.ProviderActivityResult
import com.android.credentialmanager.common.ResultState
import com.android.credentialmanager.createflow.CreateCredentialScreen
import com.android.credentialmanager.createflow.CreateCredentialViewModel
@@ -39,28 +43,23 @@ class CredentialSelectorActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
CredentialManagerRepo.setup(this, intent)
- val requestInfo = intent.extras?.getParcelable<RequestInfo>(RequestInfo.EXTRA_REQUEST_INFO)
- if (requestInfo != null) {
- val requestType = requestInfo.type
- setContent {
- CredentialSelectorTheme {
- CredentialManagerBottomSheet(requestType)
- }
- }
- } else {
- // TODO: prototype only code to be removed. In production should exit.
- setContent {
- CredentialSelectorTheme {
- CredentialManagerBottomSheet(RequestInfo.TYPE_CREATE)
- }
+ val requestInfo = CredentialManagerRepo.getInstance().requestInfo
+ setContent {
+ CredentialSelectorTheme {
+ CredentialManagerBottomSheet(DialogType.toDialogType(requestInfo.type))
}
}
}
@ExperimentalMaterialApi
@Composable
- fun CredentialManagerBottomSheet(operationType: String) {
- val dialogType = DialogType.toDialogType(operationType)
+ fun CredentialManagerBottomSheet(dialogType: DialogType) {
+ val providerActivityResult = remember { mutableStateOf<ProviderActivityResult?>(null) }
+ val launcher = rememberLauncherForActivityResult(
+ ActivityResultContracts.StartIntentSenderForResult()
+ ) {
+ providerActivityResult.value = ProviderActivityResult(it.resultCode, it.data)
+ }
when (dialogType) {
DialogType.CREATE_PASSKEY -> {
val viewModel: CreateCredentialViewModel = viewModel()
@@ -68,7 +67,10 @@ class CredentialSelectorActivity : ComponentActivity() {
this@CredentialSelectorActivity,
onCancel
)
- CreateCredentialScreen(viewModel = viewModel)
+ providerActivityResult.value?.let {
+ viewModel.onProviderActivityResult(it)
+ }
+ CreateCredentialScreen(viewModel = viewModel, providerActivityLauncher = launcher)
}
DialogType.GET_CREDENTIALS -> {
val viewModel: GetCredentialViewModel = viewModel()
@@ -76,7 +78,10 @@ class CredentialSelectorActivity : ComponentActivity() {
this@CredentialSelectorActivity,
onCancel
)
- GetCredentialScreen(viewModel = viewModel)
+ providerActivityResult.value?.let {
+ viewModel.onProviderActivityResult(it)
+ }
+ GetCredentialScreen(viewModel = viewModel, providerActivityLauncher = launcher)
}
else -> {
Log.w("AccountSelector", "Unknown type, not rendering any UI")
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt b/packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt
index fad9364e3c23..2eb328498571 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt
@@ -46,8 +46,15 @@ class GetFlowUtils {
val packageManager = context.packageManager
return providerDataList.map {
// TODO: get from the actual service info
+ val componentName = ComponentName.unflattenFromString(it.providerFlattenedComponentName)
+ var packageName = componentName?.packageName
+ if (componentName == null) {
+ // TODO: Remove once test data is fixed
+ packageName = it.providerFlattenedComponentName
+ }
+
val pkgInfo = packageManager
- .getPackageInfo(it.providerFlattenedComponentName,
+ .getPackageInfo(packageName!!,
PackageManager.PackageInfoFlags.of(0))
val providerDisplayName = pkgInfo.applicationInfo.loadLabel(packageManager).toString()
// TODO: decide what to do when failed to load a provider icon
@@ -86,12 +93,14 @@ class GetFlowUtils {
providerId = providerId,
entryKey = it.key,
entrySubkey = it.subkey,
+ pendingIntent = it.pendingIntent,
+ fillInIntent = it.frameworkExtrasIntent,
credentialType = credentialEntryUi.credentialType.toString(),
credentialTypeDisplayName = credentialEntryUi.credentialTypeDisplayName.toString(),
userName = credentialEntryUi.userName.toString(),
displayName = credentialEntryUi.userDisplayName?.toString(),
// TODO: proper fallback
- icon = credentialEntryUi.entryIcon.loadDrawable(context)
+ icon = credentialEntryUi.entryIcon?.loadDrawable(context)
?: context.getDrawable(R.drawable.ic_passkey)!!,
lastUsedTimeMillis = credentialEntryUi.lastUsedTimeMillis,
)
@@ -113,6 +122,8 @@ class GetFlowUtils {
providerId = providerId,
entryKey = authEntry.key,
entrySubkey = authEntry.subkey,
+ pendingIntent = authEntry.pendingIntent,
+ fillInIntent = authEntry.frameworkExtrasIntent,
title = providerDisplayName,
icon = providerIcon,
)
@@ -127,6 +138,8 @@ class GetFlowUtils {
providerId = providerId,
entryKey = remoteEntry.key,
entrySubkey = remoteEntry.subkey,
+ pendingIntent = remoteEntry.pendingIntent,
+ fillInIntent = remoteEntry.frameworkExtrasIntent,
)
}
@@ -142,6 +155,8 @@ class GetFlowUtils {
providerId = providerId,
entryKey = it.key,
entrySubkey = it.subkey,
+ pendingIntent = it.pendingIntent,
+ fillInIntent = it.frameworkExtrasIntent,
title = actionEntryUi.text.toString(),
// TODO: gracefully fail
icon = actionEntryUi.icon.loadDrawable(context)!!,
@@ -178,9 +193,10 @@ class CreateFlowUtils {
icon = pkgInfo.applicationInfo.loadIcon(packageManager)!!,
name = it.providerFlattenedComponentName,
displayName = pkgInfo.applicationInfo.loadLabel(packageManager).toString(),
- createOptions = toCreationOptionInfoList(it.saveEntries, context),
+ createOptions = toCreationOptionInfoList(
+ it.providerFlattenedComponentName, it.saveEntries, context),
isDefault = it.isDefaultProvider,
- remoteEntry = toRemoteInfo(it.remoteEntry),
+ remoteEntry = toRemoteInfo(it.providerFlattenedComponentName, it.remoteEntry),
)
}
}
@@ -204,6 +220,7 @@ class CreateFlowUtils {
}
private fun toCreationOptionInfoList(
+ providerId: String,
creationEntries: List<Entry>,
context: Context,
): List<CreateOptionInfo> {
@@ -212,11 +229,12 @@ class CreateFlowUtils {
return@map CreateOptionInfo(
// TODO: remove fallbacks
+ providerId = providerId,
entryKey = it.key,
entrySubkey = it.subkey,
+ pendingIntent = it.pendingIntent,
+ fillInIntent = it.frameworkExtrasIntent,
userProviderDisplayName = saveEntryUi.userProviderAccountName as String,
- credentialTypeIcon = saveEntryUi.credentialTypeIcon?.loadDrawable(context)
- ?: context.getDrawable(R.drawable.ic_passkey)!!,
profileIcon = saveEntryUi.profileIcon?.loadDrawable(context)
?: context.getDrawable(R.drawable.ic_profile)!!,
passwordCount = saveEntryUi.passwordCount ?: 0,
@@ -228,13 +246,17 @@ class CreateFlowUtils {
}
private fun toRemoteInfo(
+ providerId: String,
remoteEntry: Entry?,
): RemoteInfo? {
// TODO: should also call fromSlice after getting the official jetpack code.
return if (remoteEntry != null) {
RemoteInfo(
+ providerId = providerId,
entryKey = remoteEntry.key,
entrySubkey = remoteEntry.subkey,
+ pendingIntent = remoteEntry.pendingIntent,
+ fillInIntent = remoteEntry.frameworkExtrasIntent,
)
} else null
}
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/common/ProviderActivityResult.kt b/packages/CredentialManager/src/com/android/credentialmanager/common/ProviderActivityResult.kt
new file mode 100644
index 000000000000..9e33d51371dd
--- /dev/null
+++ b/packages/CredentialManager/src/com/android/credentialmanager/common/ProviderActivityResult.kt
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.credentialmanager.common
+
+import android.content.Intent
+
+data class ProviderActivityResult(
+ val resultCode: Int,
+ val data: Intent?,
+) \ No newline at end of file
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt
index 27d366d55937..9f73aefa52b2 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt
@@ -3,6 +3,9 @@
package com.android.credentialmanager.createflow
import android.credentials.Credential.TYPE_PASSWORD_CREDENTIAL
+import androidx.activity.compose.ManagedActivityResultLauncher
+import androidx.activity.result.ActivityResult
+import androidx.activity.result.IntentSenderRequest
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
@@ -44,13 +47,21 @@ import com.android.credentialmanager.common.ui.CancelButton
import com.android.credentialmanager.common.ui.ConfirmButton
import com.android.credentialmanager.common.ui.Entry
import com.android.credentialmanager.ui.theme.EntryShape
+import com.android.credentialmanager.ui.theme.LocalAndroidColorScheme
import com.android.credentialmanager.jetpack.developer.PublicKeyCredential.Companion.TYPE_PUBLIC_KEY_CREDENTIAL
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun CreateCredentialScreen(
viewModel: CreateCredentialViewModel,
+ providerActivityLauncher: ManagedActivityResultLauncher<IntentSenderRequest, ActivityResult>
) {
+ val selectEntryCallback: (EntryInfo) -> Unit = {
+ viewModel.onEntrySelected(it, providerActivityLauncher)
+ }
+ val confirmEntryCallback: () -> Unit = {
+ viewModel.onConfirmCreationSelected(providerActivityLauncher)
+ }
val state = rememberModalBottomSheetState(
initialValue = ModalBottomSheetValue.Expanded,
skipHalfExpanded = true
@@ -65,29 +76,34 @@ fun CreateCredentialScreen(
onCancel = viewModel::onCancel,
)
CreateScreenState.PROVIDER_SELECTION -> ProviderSelectionCard(
+ requestDisplayInfo = uiState.requestDisplayInfo,
enabledProviderList = uiState.enabledProviders,
+ disabledProviderList = uiState.disabledProviders,
onCancel = viewModel::onCancel,
- onProviderSelected = viewModel::onProviderSelected
+ onOptionSelected = viewModel::onEntrySelectedFromFirstUseScreen,
+ onDisabledPasswordManagerSelected = viewModel::onDisabledPasswordManagerSelected,
+ onRemoteEntrySelected = selectEntryCallback,
)
CreateScreenState.CREATION_OPTION_SELECTION -> CreationSelectionCard(
requestDisplayInfo = uiState.requestDisplayInfo,
+ enabledProviderList = uiState.enabledProviders,
providerInfo = uiState.activeEntry?.activeProvider!!,
createOptionInfo = uiState.activeEntry.activeEntryInfo as CreateOptionInfo,
- onOptionSelected = viewModel::onPrimaryCreateOptionInfoSelected,
- onConfirm = viewModel::onPrimaryCreateOptionInfoSelected,
+ showActiveEntryOnly = uiState.showActiveEntryOnly,
+ onOptionSelected = selectEntryCallback,
+ onConfirm = confirmEntryCallback,
onCancel = viewModel::onCancel,
- multiProvider = uiState.enabledProviders.size > 1,
- onMoreOptionsSelected = viewModel::onMoreOptionsSelected
+ onMoreOptionsSelected = viewModel::onMoreOptionsSelected,
)
CreateScreenState.MORE_OPTIONS_SELECTION -> MoreOptionsSelectionCard(
- requestDisplayInfo = uiState.requestDisplayInfo,
- enabledProviderList = uiState.enabledProviders,
- disabledProviderList = uiState.disabledProviders,
- onBackButtonSelected = viewModel::onBackButtonSelected,
- onOptionSelected = viewModel::onMoreOptionsRowSelected,
- onDisabledPasswordManagerSelected = viewModel::onDisabledPasswordManagerSelected,
- onRemoteEntrySelected = viewModel::onRemoteEntrySelected
- )
+ requestDisplayInfo = uiState.requestDisplayInfo,
+ enabledProviderList = uiState.enabledProviders,
+ disabledProviderList = uiState.disabledProviders,
+ onBackButtonSelected = viewModel::onBackButtonSelected,
+ onOptionSelected = viewModel::onEntrySelectedFromMoreOptionScreen,
+ onDisabledPasswordManagerSelected = viewModel::onDisabledPasswordManagerSelected,
+ onRemoteEntrySelected = selectEntryCallback,
+ )
CreateScreenState.MORE_OPTIONS_ROW_INTRO -> MoreOptionsRowIntroCard(
providerInfo = uiState.activeEntry?.activeProvider!!,
onDefaultOrNotSelected = viewModel::onDefaultOrNotSelected
@@ -115,18 +131,20 @@ fun ConfirmationCard(
Icon(
painter = painterResource(R.drawable.ic_passkey),
contentDescription = null,
- tint = Color.Unspecified,
- modifier = Modifier.align(alignment = Alignment.CenterHorizontally).padding(top = 24.dp)
+ tint = LocalAndroidColorScheme.current.colorAccentPrimaryVariant,
+ modifier = Modifier.align(alignment = Alignment.CenterHorizontally)
+ .padding(top = 24.dp, bottom = 12.dp)
)
Text(
text = stringResource(R.string.passkey_creation_intro_title),
style = MaterialTheme.typography.titleMedium,
modifier = Modifier
.padding(horizontal = 24.dp)
- .align(alignment = Alignment.CenterHorizontally)
+ .align(alignment = Alignment.CenterHorizontally),
+ textAlign = TextAlign.Center
)
Divider(
- thickness = 24.dp,
+ thickness = 16.dp,
color = Color.Transparent
)
Text(
@@ -135,7 +153,7 @@ fun ConfirmationCard(
modifier = Modifier.padding(horizontal = 28.dp)
)
Divider(
- thickness = 48.dp,
+ thickness = 32.dp,
color = Color.Transparent
)
Row(
@@ -154,7 +172,7 @@ fun ConfirmationCard(
Divider(
thickness = 18.dp,
color = Color.Transparent,
- modifier = Modifier.padding(bottom = 16.dp)
+ modifier = Modifier.padding(bottom = 18.dp)
)
}
}
@@ -163,16 +181,41 @@ fun ConfirmationCard(
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ProviderSelectionCard(
+ requestDisplayInfo: RequestDisplayInfo,
enabledProviderList: List<EnabledProviderInfo>,
- onProviderSelected: (String) -> Unit,
- onCancel: () -> Unit
+ disabledProviderList: List<DisabledProviderInfo>?,
+ onOptionSelected: (ActiveEntry) -> Unit,
+ onDisabledPasswordManagerSelected: () -> Unit,
+ onCancel: () -> Unit,
+ onRemoteEntrySelected: (EntryInfo) -> Unit,
) {
Card() {
Column() {
+ // TODO: Change the icon for create passwords and sign-ins
+ Icon(
+ painter = painterResource(R.drawable.ic_passkey),
+ contentDescription = null,
+ tint = LocalAndroidColorScheme.current.colorAccentPrimaryVariant,
+ modifier = Modifier.align(alignment = Alignment.CenterHorizontally)
+ .padding(top = 24.dp, bottom = 16.dp)
+ )
Text(
- text = stringResource(R.string.choose_provider_title),
+ text = stringResource(
+ R.string.choose_provider_title,
+ when (requestDisplayInfo.type) {
+ TYPE_PUBLIC_KEY_CREDENTIAL -> stringResource(R.string.create_your_passkey)
+ TYPE_PASSWORD_CREDENTIAL -> stringResource(R.string.save_your_password)
+ else -> stringResource(R.string.save_your_sign_in_info)
+ },
+ ),
style = MaterialTheme.typography.titleMedium,
- modifier = Modifier.padding(all = 24.dp).align(alignment = Alignment.CenterHorizontally)
+ modifier = Modifier.padding(horizontal = 24.dp)
+ .align(alignment = Alignment.CenterHorizontally),
+ textAlign = TextAlign.Center
+ )
+ Divider(
+ thickness = 16.dp,
+ color = Color.Transparent
)
Text(
text = stringResource(R.string.choose_provider_body),
@@ -180,7 +223,7 @@ fun ProviderSelectionCard(
modifier = Modifier.padding(horizontal = 28.dp)
)
Divider(
- thickness = 24.dp,
+ thickness = 18.dp,
color = Color.Transparent
)
Card(
@@ -192,17 +235,45 @@ fun ProviderSelectionCard(
LazyColumn(
verticalArrangement = Arrangement.spacedBy(2.dp)
) {
- enabledProviderList.forEach {
+ enabledProviderList.forEach { enabledProviderInfo ->
+ enabledProviderInfo.createOptions.forEach { createOptionInfo ->
+ item {
+ MoreOptionsInfoRow(
+ providerInfo = enabledProviderInfo,
+ createOptionInfo = createOptionInfo,
+ onOptionSelected = {
+ onOptionSelected(ActiveEntry(enabledProviderInfo, createOptionInfo))
+ })
+ }
+ }
+ }
+ if (disabledProviderList != null) {
item {
- ProviderRow(providerInfo = it, onProviderSelected = onProviderSelected)
+ MoreOptionsDisabledProvidersRow(
+ disabledProviders = disabledProviderList,
+ onDisabledPasswordManagerSelected = onDisabledPasswordManagerSelected,
+ )
}
}
}
}
- Divider(
- thickness = 24.dp,
- color = Color.Transparent
- )
+ // TODO: handle the error situation that if multiple remoteInfos exists
+ enabledProviderList.forEach { enabledProvider ->
+ if (enabledProvider.remoteEntry != null) {
+ TextButton(
+ onClick = {
+ onRemoteEntrySelected(enabledProvider.remoteEntry!!) },
+ modifier = Modifier
+ .padding(horizontal = 24.dp)
+ .align(alignment = Alignment.CenterHorizontally)
+ ) {
+ Text(
+ text = stringResource(R.string.string_save_to_another_device),
+ textAlign = TextAlign.Center,
+ )
+ }
+ }
+ }
Row(
horizontalArrangement = Arrangement.Start,
modifier = Modifier.fillMaxWidth().padding(horizontal = 24.dp)
@@ -227,7 +298,7 @@ fun MoreOptionsSelectionCard(
onBackButtonSelected: () -> Unit,
onOptionSelected: (ActiveEntry) -> Unit,
onDisabledPasswordManagerSelected: () -> Unit,
- onRemoteEntrySelected: () -> Unit,
+ onRemoteEntrySelected: (EntryInfo) -> Unit,
) {
Card() {
Column() {
@@ -285,17 +356,15 @@ fun MoreOptionsSelectionCard(
)
}
}
- var hasRemoteInfo = false
+ // TODO: handle the error situation that if multiple remoteInfos exists
enabledProviderList.forEach {
if (it.remoteEntry != null) {
- hasRemoteInfo = true
- }
- }
- if (hasRemoteInfo) {
- item {
- RemoteEntryRow(
- onRemoteEntrySelected = onRemoteEntrySelected,
- )
+ item {
+ RemoteEntryRow(
+ remoteInfo = it.remoteEntry!!,
+ onRemoteEntrySelected = onRemoteEntrySelected,
+ )
+ }
}
}
}
@@ -356,37 +425,17 @@ fun MoreOptionsRowIntroCard(
}
}
-@Composable
-fun ProviderRow(providerInfo: ProviderInfo, onProviderSelected: (String) -> Unit) {
- Entry(
- onClick = {onProviderSelected(providerInfo.name)},
- icon = {
- Image(modifier = Modifier.size(32.dp).padding(start = 10.dp),
- bitmap = providerInfo.icon.toBitmap().asImageBitmap(),
- // painter = painterResource(R.drawable.ic_passkey),
- // TODO: add description.
- contentDescription = "")
- },
- label = {
- Text(
- text = providerInfo.displayName,
- style = MaterialTheme.typography.labelLarge,
- modifier = Modifier.padding(vertical = 18.dp)
- )
- }
- )
-}
-
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun CreationSelectionCard(
requestDisplayInfo: RequestDisplayInfo,
- providerInfo: ProviderInfo,
+ enabledProviderList: List<EnabledProviderInfo>,
+ providerInfo: EnabledProviderInfo,
createOptionInfo: CreateOptionInfo,
- onOptionSelected: () -> Unit,
+ showActiveEntryOnly: Boolean,
+ onOptionSelected: (EntryInfo) -> Unit,
onConfirm: () -> Unit,
onCancel: () -> Unit,
- multiProvider: Boolean,
onMoreOptionsSelected: () -> Unit,
) {
Card() {
@@ -435,32 +484,51 @@ fun CreationSelectionCard(
.padding(horizontal = 24.dp)
.align(alignment = Alignment.CenterHorizontally),
) {
- LazyColumn(
- verticalArrangement = Arrangement.spacedBy(2.dp)
+ PrimaryCreateOptionRow(
+ requestDisplayInfo = requestDisplayInfo,
+ createOptionInfo = createOptionInfo,
+ onOptionSelected = onOptionSelected
+ )
+ }
+ if (!showActiveEntryOnly) {
+ var createOptionsSize = 0
+ enabledProviderList.forEach{
+ enabledProvider -> createOptionsSize += enabledProvider.createOptions.size}
+ if (createOptionsSize > 1) {
+ TextButton(
+ onClick = onMoreOptionsSelected,
+ modifier = Modifier
+ .padding(horizontal = 24.dp)
+ .align(alignment = Alignment.CenterHorizontally)){
+ Text(
+ text =
+ when (requestDisplayInfo.type) {
+ TYPE_PUBLIC_KEY_CREDENTIAL ->
+ stringResource(R.string.string_create_in_another_place)
+ else -> stringResource(R.string.string_save_to_another_place)},
+ textAlign = TextAlign.Center,
+ )
+ }
+ } else if (
+ requestDisplayInfo.type == TYPE_PUBLIC_KEY_CREDENTIAL
) {
- item {
- PrimaryCreateOptionRow(
- requestDisplayInfo = requestDisplayInfo,
- createOptionInfo = createOptionInfo,
- onOptionSelected = onOptionSelected
- )
+ // TODO: handle the error situation that if multiple remoteInfos exists
+ enabledProviderList.forEach { enabledProvider ->
+ if (enabledProvider.remoteEntry != null) {
+ TextButton(
+ onClick = {
+ onOptionSelected(enabledProvider.remoteEntry!!) },
+ modifier = Modifier
+ .padding(horizontal = 24.dp)
+ .align(alignment = Alignment.CenterHorizontally)
+ ) {
+ Text(
+ text = stringResource(R.string.string_use_another_device),
+ textAlign = TextAlign.Center,
+ )
+ }
}
- }
- }
- if (multiProvider) {
- TextButton(
- onClick = onMoreOptionsSelected,
- modifier = Modifier
- .padding(horizontal = 24.dp)
- .align(alignment = Alignment.CenterHorizontally)){
- Text(
- text =
- when (requestDisplayInfo.type) {
- TYPE_PUBLIC_KEY_CREDENTIAL ->
- stringResource(R.string.string_create_in_another_place)
- else -> stringResource(R.string.string_save_to_another_place)},
- textAlign = TextAlign.Center,
- )
+ }
}
}
Divider(
@@ -494,14 +562,18 @@ fun CreationSelectionCard(
fun PrimaryCreateOptionRow(
requestDisplayInfo: RequestDisplayInfo,
createOptionInfo: CreateOptionInfo,
- onOptionSelected: () -> Unit
+ onOptionSelected: (EntryInfo) -> Unit
) {
Entry(
- onClick = onOptionSelected,
+ onClick = {onOptionSelected(createOptionInfo)},
icon = {
- Image(modifier = Modifier.size(32.dp).padding(start = 10.dp),
- bitmap = createOptionInfo.credentialTypeIcon.toBitmap().asImageBitmap(),
- contentDescription = null)
+ // TODO: Upload the other two types icons and change it according to request types
+ Icon(
+ painter = painterResource(R.drawable.ic_passkey),
+ contentDescription = null,
+ tint = LocalAndroidColorScheme.current.colorAccentPrimaryVariant,
+ modifier = Modifier.padding(start = 18.dp)
+ )
},
label = {
Column() {
@@ -520,7 +592,7 @@ fun PrimaryCreateOptionRow(
)
} else {
Text(
- text = requestDisplayInfo.subtitle,
+ text = requestDisplayInfo.title,
style = MaterialTheme.typography.titleLarge,
modifier = Modifier.padding(top = 16.dp, bottom = 16.dp)
)
@@ -620,6 +692,7 @@ fun MoreOptionsDisabledProvidersRow(
style = MaterialTheme.typography.titleLarge,
modifier = Modifier.padding(top = 16.dp, start = 16.dp)
)
+ // TODO: Update the subtitle once design is confirmed
Text(
text = disabledProviders.joinToString(separator = ", "){ it.displayName },
style = MaterialTheme.typography.bodyMedium,
@@ -633,10 +706,11 @@ fun MoreOptionsDisabledProvidersRow(
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun RemoteEntryRow(
- onRemoteEntrySelected: () -> Unit,
+ remoteInfo: RemoteInfo,
+ onRemoteEntrySelected: (RemoteInfo) -> Unit,
) {
Entry(
- onClick = onRemoteEntrySelected,
+ onClick = {onRemoteEntrySelected(remoteInfo)},
icon = {
Icon(
painter = painterResource(R.drawable.ic_other_devices),
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialViewModel.kt b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialViewModel.kt
index 6be019fa0882..0f685a104329 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialViewModel.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialViewModel.kt
@@ -17,6 +17,9 @@
package com.android.credentialmanager.createflow
import android.util.Log
+import androidx.activity.compose.ManagedActivityResultLauncher
+import androidx.activity.result.ActivityResult
+import androidx.activity.result.IntentSenderRequest
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
@@ -25,6 +28,7 @@ import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.android.credentialmanager.CredentialManagerRepo
import com.android.credentialmanager.common.DialogResult
+import com.android.credentialmanager.common.ProviderActivityResult
import com.android.credentialmanager.common.ResultState
data class CreateCredentialUiState(
@@ -32,7 +36,9 @@ data class CreateCredentialUiState(
val disabledProviders: List<DisabledProviderInfo>? = null,
val currentScreenState: CreateScreenState,
val requestDisplayInfo: RequestDisplayInfo,
+ val showActiveEntryOnly: Boolean,
val activeEntry: ActiveEntry? = null,
+ val selectedEntry: EntryInfo? = null,
)
class CreateCredentialViewModel(
@@ -51,29 +57,27 @@ class CreateCredentialViewModel(
}
fun onConfirmIntro() {
- if (uiState.enabledProviders.size > 1) {
- uiState = uiState.copy(
- currentScreenState = CreateScreenState.PROVIDER_SELECTION
+ var createOptionSize = 0
+ uiState.enabledProviders.forEach {
+ enabledProvider -> createOptionSize += enabledProvider.createOptions.size}
+ uiState = if (createOptionSize > 1) {
+ uiState.copy(
+ currentScreenState = CreateScreenState.PROVIDER_SELECTION,
+ showActiveEntryOnly = true
)
- } else if (uiState.enabledProviders.size == 1){
- uiState = uiState.copy(
+ } else if (createOptionSize == 1){
+ uiState.copy(
currentScreenState = CreateScreenState.CREATION_OPTION_SELECTION,
+ showActiveEntryOnly = false,
activeEntry = ActiveEntry(uiState.enabledProviders.first(),
- uiState.enabledProviders.first().createOptions.first())
+ uiState.enabledProviders.first().createOptions.first()
+ )
)
} else {
throw java.lang.IllegalStateException("Empty provider list.")
}
}
- fun onProviderSelected(providerName: String) {
- uiState = uiState.copy(
- currentScreenState = CreateScreenState.CREATION_OPTION_SELECTION,
- activeEntry = ActiveEntry(getProviderInfoByName(providerName),
- getProviderInfoByName(providerName).createOptions.first())
- )
- }
-
fun getProviderInfoByName(providerName: String): EnabledProviderInfo {
return uiState.enabledProviders.single {
it.name.equals(providerName)
@@ -92,18 +96,23 @@ class CreateCredentialViewModel(
)
}
- fun onMoreOptionsRowSelected(activeEntry: ActiveEntry) {
+ fun onEntrySelectedFromMoreOptionScreen(activeEntry: ActiveEntry) {
uiState = uiState.copy(
currentScreenState = CreateScreenState.MORE_OPTIONS_ROW_INTRO,
+ showActiveEntryOnly = false,
activeEntry = activeEntry
)
}
- fun onDisabledPasswordManagerSelected() {
- // TODO: Complete this function
+ fun onEntrySelectedFromFirstUseScreen(activeEntry: ActiveEntry) {
+ uiState = uiState.copy(
+ currentScreenState = CreateScreenState.CREATION_OPTION_SELECTION,
+ showActiveEntryOnly = true,
+ activeEntry = activeEntry
+ )
}
- fun onRemoteEntrySelected() {
+ fun onDisabledPasswordManagerSelected() {
// TODO: Complete this function
}
@@ -119,22 +128,64 @@ class CreateCredentialViewModel(
// TODO: implement the if choose as default or not logic later
}
- fun onPrimaryCreateOptionInfoSelected() {
- val entryKey = uiState.activeEntry?.activeEntryInfo?.entryKey
- val entrySubkey = uiState.activeEntry?.activeEntryInfo?.entrySubkey
+ fun onEntrySelected(
+ selectedEntry: EntryInfo,
+ launcher: ManagedActivityResultLauncher<IntentSenderRequest, ActivityResult>
+ ) {
+ val providerId = selectedEntry.providerId
+ val entryKey = selectedEntry.entryKey
+ val entrySubkey = selectedEntry.entrySubkey
Log.d(
- "Account Selector",
- "Option selected for creation: " +
- "{key = $entryKey, subkey = $entrySubkey}"
- )
- if (entryKey != null && entrySubkey != null) {
+ "Account Selector", "Option selected for entry: " +
+ " {provider=$providerId, key=$entryKey, subkey=$entrySubkey")
+ if (selectedEntry.pendingIntent != null) {
+ uiState = uiState.copy(selectedEntry = selectedEntry)
+ val intentSenderRequest = IntentSenderRequest.Builder(selectedEntry.pendingIntent)
+ .setFillInIntent(selectedEntry.fillInIntent).build()
+ launcher.launch(intentSenderRequest)
+ } else {
CredentialManagerRepo.getInstance().onOptionSelected(
- uiState.activeEntry?.activeProvider!!.name,
+ providerId,
entryKey,
entrySubkey
)
+ dialogResult.value = DialogResult(
+ ResultState.COMPLETE,
+ )
+ }
+ }
+
+ fun onConfirmCreationSelected(
+ launcher: ManagedActivityResultLauncher<IntentSenderRequest, ActivityResult>
+ ) {
+ val selectedEntry = uiState.activeEntry?.activeEntryInfo
+ if (selectedEntry != null) {
+ onEntrySelected(selectedEntry, launcher)
+ } else {
+ Log.w("Account Selector",
+ "Illegal state: confirm is pressed but activeEntry isn't set.")
+ dialogResult.value = DialogResult(
+ ResultState.COMPLETE,
+ )
+ }
+ }
+
+ fun onProviderActivityResult(providerActivityResult: ProviderActivityResult) {
+ val entry = uiState.selectedEntry
+ val resultCode = providerActivityResult.resultCode
+ val resultData = providerActivityResult.data
+ if (entry != null) {
+ val providerId = entry.providerId
+ Log.d("Account Selector", "Got provider activity result: {provider=" +
+ "$providerId, key=${entry.entryKey}, subkey=${entry.entrySubkey}, " +
+ "resultCode=$resultCode, resultData=$resultData}"
+ )
+ CredentialManagerRepo.getInstance().onOptionSelected(
+ providerId, entry.entryKey, entry.entrySubkey, resultCode, resultData,
+ )
} else {
- TODO("Gracefully handle illegal state.")
+ Log.w("Account Selector",
+ "Illegal state: received a provider result but found no matching entry.")
}
dialogResult.value = DialogResult(
ResultState.COMPLETE,
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateModel.kt b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateModel.kt
index 1ab234a0e0bc..6dd6afb81dc4 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateModel.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateModel.kt
@@ -16,6 +16,8 @@
package com.android.credentialmanager.createflow
+import android.app.PendingIntent
+import android.content.Intent
import android.graphics.drawable.Drawable
open class ProviderInfo(
@@ -40,26 +42,34 @@ class DisabledProviderInfo(
) : ProviderInfo(icon, name, displayName)
open class EntryInfo (
+ val providerId: String,
val entryKey: String,
val entrySubkey: String,
+ val pendingIntent: PendingIntent?,
+ val fillInIntent: Intent?,
)
class CreateOptionInfo(
+ providerId: String,
entryKey: String,
entrySubkey: String,
+ pendingIntent: PendingIntent?,
+ fillInIntent: Intent?,
val userProviderDisplayName: String?,
- val credentialTypeIcon: Drawable,
val profileIcon: Drawable,
val passwordCount: Int?,
val passkeyCount: Int?,
val totalCredentialCount: Int?,
val lastUsedTimeMillis: Long?,
-) : EntryInfo(entryKey, entrySubkey)
+) : EntryInfo(providerId, entryKey, entrySubkey, pendingIntent, fillInIntent)
class RemoteInfo(
+ providerId: String,
entryKey: String,
entrySubkey: String,
-) : EntryInfo(entryKey, entrySubkey)
+ pendingIntent: PendingIntent?,
+ fillInIntent: Intent?,
+) : EntryInfo(providerId, entryKey, entrySubkey, pendingIntent, fillInIntent)
data class RequestDisplayInfo(
val title: String,
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt
index 19a032fcf4b8..db0c16c0bb9e 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt
@@ -17,6 +17,9 @@
package com.android.credentialmanager.getflow
import android.text.TextUtils
+import androidx.activity.compose.ManagedActivityResultLauncher
+import androidx.activity.result.ActivityResult
+import androidx.activity.result.IntentSenderRequest
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Arrangement
@@ -62,7 +65,11 @@ import com.android.credentialmanager.jetpack.developer.PublicKeyCredential
@Composable
fun GetCredentialScreen(
viewModel: GetCredentialViewModel,
+ providerActivityLauncher: ManagedActivityResultLauncher<IntentSenderRequest, ActivityResult>
) {
+ val entrySelectionCallback: (EntryInfo) -> Unit = {
+ viewModel.onEntrySelected(it, providerActivityLauncher)
+ }
val state = rememberModalBottomSheetState(
initialValue = ModalBottomSheetValue.Expanded,
skipHalfExpanded = true
@@ -75,14 +82,14 @@ fun GetCredentialScreen(
GetScreenState.PRIMARY_SELECTION -> PrimarySelectionCard(
requestDisplayInfo = uiState.requestDisplayInfo,
providerDisplayInfo = uiState.providerDisplayInfo,
- onEntrySelected = viewModel::onEntrySelected,
+ onEntrySelected = entrySelectionCallback,
onCancel = viewModel::onCancel,
onMoreOptionSelected = viewModel::onMoreOptionSelected,
)
GetScreenState.ALL_SIGN_IN_OPTIONS -> AllSignInOptionCard(
providerInfoList = uiState.providerInfoList,
providerDisplayInfo = uiState.providerDisplayInfo,
- onEntrySelected = viewModel::onEntrySelected,
+ onEntrySelected = entrySelectionCallback,
onBackButtonClicked = viewModel::onBackToPrimarySelectionScreen,
)
}
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialViewModel.kt b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialViewModel.kt
index 22370a91cde4..6dea9c299989 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialViewModel.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialViewModel.kt
@@ -17,6 +17,9 @@
package com.android.credentialmanager.getflow
import android.util.Log
+import androidx.activity.compose.ManagedActivityResultLauncher
+import androidx.activity.result.ActivityResult
+import androidx.activity.result.IntentSenderRequest
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
@@ -25,6 +28,7 @@ import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.android.credentialmanager.CredentialManagerRepo
import com.android.credentialmanager.common.DialogResult
+import com.android.credentialmanager.common.ProviderActivityResult
import com.android.credentialmanager.common.ResultState
import com.android.credentialmanager.jetpack.developer.PublicKeyCredential
import com.android.internal.util.Preconditions
@@ -34,6 +38,7 @@ data class GetCredentialUiState(
val currentScreenState: GetScreenState,
val requestDisplayInfo: RequestDisplayInfo,
val providerDisplayInfo: ProviderDisplayInfo = toProviderDisplayInfo(providerInfoList),
+ val selectedEntry: EntryInfo? = null,
)
class GetCredentialViewModel(
@@ -51,14 +56,42 @@ class GetCredentialViewModel(
return dialogResult
}
- fun onEntrySelected(entry: EntryInfo) {
+ fun onEntrySelected(
+ entry: EntryInfo,
+ launcher: ManagedActivityResultLauncher<IntentSenderRequest, ActivityResult>
+ ) {
Log.d("Account Selector", "credential selected:" +
" {provider=${entry.providerId}, key=${entry.entryKey}, subkey=${entry.entrySubkey}}")
- CredentialManagerRepo.getInstance().onOptionSelected(
- entry.providerId,
- entry.entryKey,
- entry.entrySubkey
- )
+ if (entry.pendingIntent != null) {
+ uiState = uiState.copy(selectedEntry = entry)
+ val intentSenderRequest = IntentSenderRequest.Builder(entry.pendingIntent)
+ .setFillInIntent(entry.fillInIntent).build()
+ launcher.launch(intentSenderRequest)
+ } else {
+ CredentialManagerRepo.getInstance().onOptionSelected(
+ entry.providerId, entry.entryKey, entry.entrySubkey,
+ )
+ dialogResult.value = DialogResult(ResultState.COMPLETE)
+ }
+ }
+
+ fun onProviderActivityResult(providerActivityResult: ProviderActivityResult) {
+ val entry = uiState.selectedEntry
+ val resultCode = providerActivityResult.resultCode
+ val resultData = providerActivityResult.data
+ if (entry != null) {
+ Log.d("Account Selector", "Got provider activity result: {provider=" +
+ "${entry.providerId}, key=${entry.entryKey}, subkey=${entry.entrySubkey}, " +
+ "resultCode=$resultCode, resultData=$resultData}"
+ )
+ CredentialManagerRepo.getInstance().onOptionSelected(
+ entry.providerId, entry.entryKey, entry.entrySubkey,
+ resultCode, resultData,
+ )
+ } else {
+ Log.w("Account Selector",
+ "Illegal state: received a provider result but found no matching entry.")
+ }
dialogResult.value = DialogResult(ResultState.COMPLETE)
}
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetModel.kt b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetModel.kt
index 76d9847f5356..0c3baffd8864 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetModel.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetModel.kt
@@ -16,6 +16,8 @@
package com.android.credentialmanager.getflow
+import android.app.PendingIntent
+import android.content.Intent
import android.graphics.drawable.Drawable
data class ProviderInfo(
@@ -49,12 +51,16 @@ abstract class EntryInfo (
val providerId: String,
val entryKey: String,
val entrySubkey: String,
+ val pendingIntent: PendingIntent?,
+ val fillInIntent: Intent?,
)
class CredentialEntryInfo(
providerId: String,
entryKey: String,
entrySubkey: String,
+ pendingIntent: PendingIntent?,
+ fillInIntent: Intent?,
/** Type of this credential used for sorting. Not localized so must not be directly displayed. */
val credentialType: String,
/** Localized type value of this credential used for display purpose. */
@@ -63,30 +69,36 @@ class CredentialEntryInfo(
val displayName: String?,
val icon: Drawable,
val lastUsedTimeMillis: Long?,
-) : EntryInfo(providerId, entryKey, entrySubkey)
+) : EntryInfo(providerId, entryKey, entrySubkey, pendingIntent, fillInIntent)
class AuthenticationEntryInfo(
providerId: String,
entryKey: String,
entrySubkey: String,
+ pendingIntent: PendingIntent?,
+ fillInIntent: Intent?,
val title: String,
val icon: Drawable,
-) : EntryInfo(providerId, entryKey, entrySubkey)
+) : EntryInfo(providerId, entryKey, entrySubkey, pendingIntent, fillInIntent)
class RemoteEntryInfo(
providerId: String,
entryKey: String,
entrySubkey: String,
-) : EntryInfo(providerId, entryKey, entrySubkey)
+ pendingIntent: PendingIntent?,
+ fillInIntent: Intent?,
+) : EntryInfo(providerId, entryKey, entrySubkey, pendingIntent, fillInIntent)
class ActionEntryInfo(
providerId: String,
entryKey: String,
entrySubkey: String,
+ pendingIntent: PendingIntent?,
+ fillInIntent: Intent?,
val title: String,
val icon: Drawable,
val subTitle: String?,
-) : EntryInfo(providerId, entryKey, entrySubkey)
+) : EntryInfo(providerId, entryKey, entrySubkey, pendingIntent, fillInIntent)
data class RequestDisplayInfo(
val appDomainName: String,
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/provider/CredentialEntryUi.kt b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/provider/CredentialEntryUi.kt
index dfbcae119fa0..1693eb629b1b 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/provider/CredentialEntryUi.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/provider/CredentialEntryUi.kt
@@ -30,7 +30,7 @@ class CredentialEntryUi(
val credentialTypeDisplayName: CharSequence,
val userName: CharSequence,
val userDisplayName: CharSequence?,
- val entryIcon: Icon,
+ val entryIcon: Icon?,
val lastUsedTimeMillis: Long?,
val note: CharSequence?,
) {
@@ -62,7 +62,7 @@ class CredentialEntryUi(
}
return CredentialEntryUi(
- credentialType, credentialTypeDisplayName!!, userName!!, userDisplayName, entryIcon!!,
+ credentialType, credentialTypeDisplayName!!, userName!!, userDisplayName, entryIcon,
lastUsedTimeMillis, note,
)
}
diff --git a/packages/SettingsLib/Spa/build.gradle b/packages/SettingsLib/Spa/build.gradle
index b8fd5791404f..dea9bf45d39a 100644
--- a/packages/SettingsLib/Spa/build.gradle
+++ b/packages/SettingsLib/Spa/build.gradle
@@ -24,7 +24,7 @@ buildscript {
}
}
plugins {
- id 'com.android.application' version '7.3.0' apply false
- id 'com.android.library' version '7.3.0' apply false
+ id 'com.android.application' version '7.3.1' apply false
+ id 'com.android.library' version '7.3.1' apply false
id 'org.jetbrains.kotlin.android' version '1.7.20' apply false
}
diff --git a/packages/SettingsLib/Spa/gallery/AndroidManifest.xml b/packages/SettingsLib/Spa/gallery/AndroidManifest.xml
index 1e52aaf72076..0123c270c447 100644
--- a/packages/SettingsLib/Spa/gallery/AndroidManifest.xml
+++ b/packages/SettingsLib/Spa/gallery/AndroidManifest.xml
@@ -17,16 +17,17 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.settingslib.spa.gallery">
- <uses-sdk android:minSdkVersion="21"/>
+ <uses-sdk android:minSdkVersion="21" />
<application
android:name=".GalleryApplication"
+ android:enableOnBackInvokedCallback="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_label"
- android:supportsRtl="true"
- android:enableOnBackInvokedCallback="true">
+ android:supportsRtl="true">
<activity
android:name=".GalleryMainActivity"
+ android:configChanges="orientation|screenLayout|screenSize|smallestScreenSize"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsDimension.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsDimension.kt
index c2223e684f29..7962e601999a 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsDimension.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsDimension.kt
@@ -40,6 +40,9 @@ object SettingsDimension {
/** The size when app icon is displayed in App info page. */
val appIconInfoSize = 48.dp
+ /** The [PaddingValues] for buttons. */
+ val buttonPadding = PaddingValues(horizontal = itemPaddingEnd, vertical = 12.dp)
+
/** The sizes info of illustration widget. */
val illustrationMaxWidth = 412.dp
val illustrationMaxHeight = 300.dp
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsTypography.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsTypography.kt
index 03699bf4d4c0..5eaa4956b2e8 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsTypography.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsTypography.kt
@@ -142,3 +142,7 @@ internal fun rememberSettingsTypography(): Typography {
val settingsFontFamily = rememberSettingsFontFamily()
return remember { SettingsTypography(settingsFontFamily).typography }
}
+
+/** Creates a new [TextStyle] which font weight set to medium. */
+internal fun TextStyle.toMediumWeight() =
+ copy(fontWeight = FontWeight.Medium, letterSpacing = 0.01.em)
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/button/ActionButtons.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/button/ActionButtons.kt
index a9d1c3735ab7..5e6c61423c24 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/button/ActionButtons.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/button/ActionButtons.kt
@@ -64,7 +64,7 @@ data class ActionButton(
fun ActionButtons(actionButtons: List<ActionButton>) {
Row(
Modifier
- .padding(SettingsDimension.itemPaddingVertical)
+ .padding(SettingsDimension.buttonPadding)
.clip(SettingsShape.CornerLarge)
.height(IntrinsicSize.Min)
) {
@@ -94,9 +94,7 @@ private fun RowScope.ActionButton(actionButton: ActionButton) {
),
contentPadding = PaddingValues(horizontal = 4.dp, vertical = 20.dp),
) {
- Column(
- horizontalAlignment = Alignment.CenterHorizontally,
- ) {
+ Column(horizontalAlignment = Alignment.CenterHorizontally) {
Icon(
imageVector = actionButton.imageVector,
contentDescription = null,
@@ -105,7 +103,7 @@ private fun RowScope.ActionButton(actionButton: ActionButton) {
Spacer(Modifier.height(4.dp))
Text(
text = actionButton.text,
- style = MaterialTheme.typography.labelLarge,
+ style = MaterialTheme.typography.labelMedium,
)
}
}
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/Text.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/Text.kt
index 123354f371f3..5f2344ed97c0 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/Text.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/Text.kt
@@ -30,18 +30,24 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.android.settingslib.spa.framework.theme.SettingsTheme
+import com.android.settingslib.spa.framework.theme.toMediumWeight
@Composable
-fun SettingsTitle(title: State<String>) {
- SettingsTitle(title.value)
+fun SettingsTitle(title: State<String>, useMediumWeight: Boolean = false) {
+ SettingsTitle(title.value, useMediumWeight)
}
@Composable
-fun SettingsTitle(title: String) {
+fun SettingsTitle(title: String, useMediumWeight: Boolean = false) {
Text(
text = title,
color = MaterialTheme.colorScheme.onSurface,
- style = MaterialTheme.typography.titleMedium,
+ style = MaterialTheme.typography.titleMedium.let {
+ when (useMediumWeight) {
+ true -> it.toMediumWeight()
+ else -> it
+ }
+ },
)
}
diff --git a/packages/SettingsLib/Spa/tests/Android.bp b/packages/SettingsLib/Spa/tests/Android.bp
index dcfc171dad0c..6974005819ea 100644
--- a/packages/SettingsLib/Spa/tests/Android.bp
+++ b/packages/SettingsLib/Spa/tests/Android.bp
@@ -27,13 +27,10 @@ android_test {
static_libs: [
"SpaLib",
"SpaLibTestUtils",
- "androidx.test.runner",
- "androidx.test.ext.junit",
"androidx.compose.runtime_runtime",
- "androidx.compose.ui_ui-test-junit4",
- "androidx.compose.ui_ui-test-manifest",
+ "androidx.test.ext.junit",
+ "androidx.test.runner",
"mockito-target-minus-junit4",
- "truth-prebuilt",
],
kotlincflags: ["-Xjvm-default=all"],
min_sdk_version: "31",
diff --git a/packages/SettingsLib/Spa/tests/build.gradle b/packages/SettingsLib/Spa/tests/build.gradle
index 2d501fccab3a..59718951e381 100644
--- a/packages/SettingsLib/Spa/tests/build.gradle
+++ b/packages/SettingsLib/Spa/tests/build.gradle
@@ -61,8 +61,5 @@ android {
dependencies {
androidTestImplementation project(":spa")
androidTestImplementation project(":testutils")
- androidTestImplementation "androidx.compose.ui:ui-test-junit4:$jetpack_compose_version"
- androidTestImplementation "com.google.truth:truth:1.1.3"
- androidTestImplementation "org.mockito:mockito-android:3.4.6"
- androidTestDebugImplementation "androidx.compose.ui:ui-test-manifest:$jetpack_compose_version"
+ androidTestImplementation "com.linkedin.dexmaker:dexmaker-mockito:2.28.1"
}
diff --git a/packages/SettingsLib/Spa/testutils/Android.bp b/packages/SettingsLib/Spa/testutils/Android.bp
index 68ad41452bd1..0f618fab9656 100644
--- a/packages/SettingsLib/Spa/testutils/Android.bp
+++ b/packages/SettingsLib/Spa/testutils/Android.bp
@@ -24,7 +24,10 @@ android_library {
srcs: ["src/**/*.kt"],
static_libs: [
- "mockito-target-minus-junit4",
+ "androidx.compose.ui_ui-test-junit4",
+ "androidx.compose.ui_ui-test-manifest",
+ "mockito",
+ "truth-prebuilt",
],
kotlincflags: [
"-Xjvm-default=all",
diff --git a/packages/SettingsLib/Spa/testutils/build.gradle b/packages/SettingsLib/Spa/testutils/build.gradle
index 3e50b2990309..58b4d42b604a 100644
--- a/packages/SettingsLib/Spa/testutils/build.gradle
+++ b/packages/SettingsLib/Spa/testutils/build.gradle
@@ -47,5 +47,8 @@ android {
}
dependencies {
- api "org.mockito:mockito-android:3.4.6"
+ api "androidx.compose.ui:ui-test-junit4:$jetpack_compose_version"
+ api "com.google.truth:truth:1.1.3"
+ api "org.mockito:mockito-core:2.21.0"
+ debugApi "androidx.compose.ui:ui-test-manifest:$jetpack_compose_version"
}
diff --git a/packages/SettingsLib/Spa/testutils/src/com/android/settingslib/spa/testutils/ComposeContentTestRuleExt.kt b/packages/SettingsLib/Spa/testutils/src/com/android/settingslib/spa/testutils/ComposeContentTestRuleExt.kt
new file mode 100644
index 000000000000..a5d1f402e022
--- /dev/null
+++ b/packages/SettingsLib/Spa/testutils/src/com/android/settingslib/spa/testutils/ComposeContentTestRuleExt.kt
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.spa.testutils
+
+import androidx.compose.ui.test.ComposeTimeoutException
+import androidx.compose.ui.test.SemanticsMatcher
+import androidx.compose.ui.test.SemanticsNodeInteraction
+import androidx.compose.ui.test.hasAnyAncestor
+import androidx.compose.ui.test.hasText
+import androidx.compose.ui.test.isDialog
+import androidx.compose.ui.test.junit4.ComposeContentTestRule
+
+/** Blocks until the found a semantics node that match the given condition. */
+fun ComposeContentTestRule.waitUntilExists(matcher: SemanticsMatcher) = waitUntil {
+ onAllNodes(matcher).fetchSemanticsNodes().isNotEmpty()
+}
+
+/** Blocks until the timeout is reached. */
+fun ComposeContentTestRule.delay(timeoutMillis: Long = 1_000) = try {
+ waitUntil(timeoutMillis) { false }
+} catch (_: ComposeTimeoutException) {
+ // Expected
+}
+
+/** Finds a text node that within dialog. */
+fun ComposeContentTestRule.onDialogText(text: String): SemanticsNodeInteraction =
+ onNode(hasAnyAncestor(isDialog()) and hasText(text))
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppInfo.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppInfo.kt
index 9611b136d881..16ca70fe90b9 100644
--- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppInfo.kt
+++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppInfo.kt
@@ -101,5 +101,5 @@ internal fun AppIcon(app: ApplicationInfo, size: Dp) {
@Composable
internal fun AppLabel(app: ApplicationInfo) {
val appRepository = rememberAppRepository()
- SettingsTitle(appRepository.produceLabel(app))
+ SettingsTitle(title = appRepository.produceLabel(app), useMediumWeight = true)
}
diff --git a/packages/SettingsLib/SpaPrivileged/tests/Android.bp b/packages/SettingsLib/SpaPrivileged/tests/Android.bp
index 5cd74e30c207..5fa4f77cc5b6 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/Android.bp
+++ b/packages/SettingsLib/SpaPrivileged/tests/Android.bp
@@ -32,11 +32,8 @@ android_test {
static_libs: [
"SpaLibTestUtils",
- "androidx.compose.ui_ui-test-junit4",
- "androidx.compose.ui_ui-test-manifest",
"androidx.test.ext.junit",
"androidx.test.runner",
"mockito-target-minus-junit4",
- "truth-prebuilt",
],
}
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppInfoTest.kt b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppInfoTest.kt
new file mode 100644
index 000000000000..8ca7950905af
--- /dev/null
+++ b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppInfoTest.kt
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.spaprivileged.template.app
+
+import android.content.Context
+import android.content.pm.ApplicationInfo
+import android.content.pm.PackageInfo
+import android.content.pm.PackageManager
+import androidx.compose.runtime.CompositionLocalProvider
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.test.assertIsDisplayed
+import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.compose.ui.test.onNodeWithText
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+class AppInfoTest {
+ @get:Rule
+ val composeTestRule = createComposeRule()
+
+ private var context: Context = ApplicationProvider.getApplicationContext()
+
+ @Test
+ fun appInfoLabel_isDisplayed() {
+ val packageInfo = PackageInfo().apply {
+ applicationInfo = APP
+ }
+ val appInfoProvider = AppInfoProvider(packageInfo)
+
+ composeTestRule.setContent {
+ CompositionLocalProvider(LocalContext provides context) {
+ appInfoProvider.AppInfo()
+ }
+ }
+
+ composeTestRule.onNodeWithText(LABEL).assertIsDisplayed()
+ }
+
+ @Test
+ fun appInfoVersion_whenDisplayVersionIsFalse() {
+ val packageInfo = PackageInfo().apply {
+ applicationInfo = APP
+ versionName = VERSION_NAME
+ }
+ val appInfoProvider = AppInfoProvider(packageInfo)
+
+ composeTestRule.setContent {
+ CompositionLocalProvider(LocalContext provides context) {
+ appInfoProvider.AppInfo(displayVersion = false)
+ }
+ }
+
+ composeTestRule.onNodeWithText(VERSION_NAME).assertDoesNotExist()
+ }
+
+ @Test
+ fun appInfoVersion_whenDisplayVersionIsTrue() {
+ val packageInfo = PackageInfo().apply {
+ applicationInfo = APP
+ versionName = VERSION_NAME
+ }
+ val appInfoProvider = AppInfoProvider(packageInfo)
+
+ composeTestRule.setContent {
+ CompositionLocalProvider(LocalContext provides context) {
+ appInfoProvider.AppInfo(displayVersion = true)
+ }
+ }
+
+ composeTestRule.onNodeWithText(VERSION_NAME).assertIsDisplayed()
+ }
+
+ @Test
+ fun footerAppVersion_versionIsDisplayed() {
+ val packageInfo = PackageInfo().apply {
+ applicationInfo = APP
+ versionName = VERSION_NAME
+ }
+ val appInfoProvider = AppInfoProvider(packageInfo)
+
+ composeTestRule.setContent {
+ CompositionLocalProvider(LocalContext provides context) {
+ appInfoProvider.FooterAppVersion()
+ }
+ }
+
+ composeTestRule.onNodeWithText("version $VERSION_NAME").assertIsDisplayed()
+ }
+
+ private companion object {
+ const val LABEL = "Label"
+ const val VERSION_NAME = "VersionName"
+ val APP = object : ApplicationInfo() {
+ override fun loadLabel(pm: PackageManager) = LABEL
+ }
+ }
+}
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java
index e30dd2fad357..cf7c7c5751dd 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java
@@ -175,6 +175,7 @@ public class GlobalSettingsValidators {
VALIDATORS.put(Global.ADVANCED_BATTERY_USAGE_AMOUNT, PERCENTAGE_INTEGER_VALIDATOR);
VALIDATORS.put(Global.ADAPTIVE_BATTERY_MANAGEMENT_ENABLED, BOOLEAN_VALIDATOR);
VALIDATORS.put(Global.POWER_BUTTON_LONG_PRESS_DURATION_MS, NONE_NEGATIVE_LONG_VALIDATOR);
+ VALIDATORS.put(Global.STYLUS_EVER_USED, BOOLEAN_VALIDATOR);
VALIDATORS.put(Global.Wearable.HAS_PAY_TOKENS, BOOLEAN_VALIDATOR);
VALIDATORS.put(Global.Wearable.GMS_CHECKIN_TIMEOUT_MIN, ANY_INTEGER_VALIDATOR);
diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
index f5c9bcd763b4..24c14352cb61 100644
--- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -272,6 +272,7 @@ public class SettingsBackupTest {
Settings.Global.SMART_REPLIES_IN_NOTIFICATIONS_FLAGS,
Settings.Global.SMART_SUGGESTIONS_IN_NOTIFICATIONS_FLAGS,
Settings.Global.STYLUS_HANDWRITING_ENABLED,
+ Settings.Global.STYLUS_EVER_USED,
Settings.Global.ENABLE_ADB_INCREMENTAL_INSTALL_DEFAULT,
Settings.Global.ENABLE_MULTI_SLOT_TIMEOUT_MILLIS,
Settings.Global.ENHANCED_4G_MODE_ENABLED,
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index 7c3948a19792..5c70edafc91a 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -168,25 +168,15 @@ java_library {
}
android_library {
- name: "SystemUI-tests",
+ name: "SystemUI-tests-base",
manifest: "tests/AndroidManifest-base.xml",
- additional_manifests: ["tests/AndroidManifest.xml"],
-
+
resource_dirs: [
"tests/res",
"res-product",
"res-keyguard",
"res",
],
- srcs: [
- "tests/src/**/*.kt",
- "tests/src/**/*.java",
- "src/**/*.kt",
- "src/**/*.java",
- "src/**/I*.aidl",
- ":ReleaseJavaFiles",
- ":SystemUI-tests-utils",
- ],
static_libs: [
"WifiTrackerLib",
"SystemUIAnimationLib",
@@ -225,9 +215,6 @@ android_library {
"metrics-helper-lib",
"hamcrest-library",
"androidx.test.rules",
- "androidx.test.uiautomator_uiautomator",
- "mockito-target-extended-minus-junit4",
- "androidx.test.ext.junit",
"testables",
"truth-prebuilt",
"monet",
@@ -242,6 +229,36 @@ android_library {
"android.test.base",
"android.test.mock",
],
+}
+
+// Device tests only
+android_library {
+ name: "SystemUI-tests",
+ manifest: "tests/AndroidManifest.xml",
+ additional_manifests: ["tests/AndroidManifest.xml"],
+ resource_dirs: [],
+ srcs: [
+ // Kotlin likes all files in the same module for internal
+ "src/**/*.kt",
+ "src/**/*.java",
+ "src/**/I*.aidl",
+ ":ReleaseJavaFiles",
+ "tests/src/**/*.kt",
+ "tests/src/**/*.java",
+ ":SystemUI-tests-utils",
+ ],
+ dont_merge_manifests: true,
+ static_libs: [
+ "SystemUI-tests-base",
+ "androidx.test.uiautomator_uiautomator",
+ "mockito-target-extended-minus-junit4",
+ "androidx.test.ext.junit",
+ ],
+ libs: [
+ "android.test.runner",
+ "android.test.base",
+ "android.test.mock",
+ ],
kotlincflags: ["-Xjvm-default=enable"],
aaptflags: [
"--extra-packages",
@@ -253,6 +270,58 @@ android_library {
},
}
+android_app {
+ name: "SystemUIRobo-stub",
+ defaults: [
+ "platform_app_defaults",
+ "SystemUI_app_defaults",
+ ],
+ srcs: [
+ "src/**/*.kt",
+ "src/**/*.java",
+ "src/**/I*.aidl",
+ ":ReleaseJavaFiles",
+ ],
+ manifest: "tests/AndroidManifest-base.xml",
+ static_libs: [
+ "SystemUI-tests-base",
+ ],
+ aaptflags: [
+ "--extra-packages",
+ "com.android.systemui",
+ ],
+ dont_merge_manifests: true,
+ platform_apis: true,
+ system_ext_specific: true,
+ certificate: "platform",
+ privileged: true,
+ resource_dirs: [],
+
+ kotlincflags: ["-Xjvm-default=enable"],
+ dxflags: ["--multi-dex"],
+ required: [
+ "privapp_whitelist_com.android.systemui",
+ ],
+ plugins: ["dagger2-compiler"],
+}
+
+android_robolectric_test {
+ name: "SystemUiRoboTests",
+ srcs: [
+ "tests/robolectric/src/**/*.kt",
+ "tests/robolectric/src/**/*.java",
+ ],
+ libs: [
+ "android.test.runner",
+ "android.test.base",
+ "android.test.mock",
+ "truth-prebuilt",
+ ],
+ kotlincflags: ["-Xjvm-default=enable"],
+ instrumentation_for: "SystemUIRobo-stub",
+ java_resource_dirs: ["tests/robolectric/config"],
+}
+
// Opt-out config for optimizing the SystemUI target using R8.
// Disabled via `export SYSTEMUI_OPTIMIZE_JAVA=false`, or explicitly in Make via
// `SYSTEMUI_OPTIMIZE_JAVA := false`.
diff --git a/packages/SystemUI/res/values-h700dp/dimens.xml b/packages/SystemUI/customization/res/values-h700dp/dimens.xml
index fbd985eaa751..2a15981ab940 100644
--- a/packages/SystemUI/res/values-h700dp/dimens.xml
+++ b/packages/SystemUI/customization/res/values-h700dp/dimens.xml
@@ -1,5 +1,5 @@
<!--
- ~ Copyright (C) 2021 The Android Open Source Project
+ ~ Copyright (C) 2022 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
@@ -17,4 +17,4 @@
<resources>
<!-- Large clock maximum font size (dp is intentional, to prevent any further scaling) -->
<dimen name="large_clock_text_size">170dp</dimen>
-</resources>
+</resources> \ No newline at end of file
diff --git a/data/etc/com.android.timezone.updater.xml b/packages/SystemUI/customization/res/values-h800dp/dimens.xml
index 60a66e22027d..60afc8a97a71 100644
--- a/data/etc/com.android.timezone.updater.xml
+++ b/packages/SystemUI/customization/res/values-h800dp/dimens.xml
@@ -1,6 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
<!--
- ~ Copyright (C) 2018 The Android Open Source Project
+ ~ Copyright (C) 2022 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
@@ -14,9 +13,8 @@
~ See the License for the specific language governing permissions and
~ limitations under the License
-->
-<permissions>
- <privapp-permissions package="com.android.timezone.updater">
- <permission name="android.permission.QUERY_TIME_ZONE_RULES" />
- <permission name="android.permission.UPDATE_TIME_ZONE_RULES" />
- </privapp-permissions>
-</permissions>
+
+<resources>
+ <!-- Large clock maximum font size (dp is intentional, to prevent any further scaling) -->
+ <dimen name="large_clock_text_size">200dp</dimen>
+</resources>
diff --git a/packages/SystemUI/customization/res/values/dimens.xml b/packages/SystemUI/customization/res/values/dimens.xml
index 8f90f0fefdb5..ba8f2843cdfc 100644
--- a/packages/SystemUI/customization/res/values/dimens.xml
+++ b/packages/SystemUI/customization/res/values/dimens.xml
@@ -17,8 +17,8 @@
-->
<resources>
<!-- Clock maximum font size (dp is intentional, to prevent any further scaling) -->
- <dimen name="large_clock_text_size">150sp</dimen>
- <dimen name="small_clock_text_size">86sp</dimen>
+ <dimen name="large_clock_text_size">150dp</dimen>
+ <dimen name="small_clock_text_size">86dp</dimen>
<!-- Default line spacing multiplier between hours and minutes of the keyguard clock -->
<item name="keyguard_clock_line_spacing_scale" type="dimen" format="float">.7</item>
diff --git a/packages/SystemUI/docs/device-entry/quickaffordance.md b/packages/SystemUI/docs/device-entry/quickaffordance.md
index 95b986faebb4..01d4f00467c4 100644
--- a/packages/SystemUI/docs/device-entry/quickaffordance.md
+++ b/packages/SystemUI/docs/device-entry/quickaffordance.md
@@ -1,25 +1,73 @@
# Keyguard Quick Affordances
-These are interactive UI elements that appear at the bottom of the lockscreen when the device is
-locked. They allow the user to perform quick actions without unlocking their device. For example:
+Quick Affordances are interactive UI elements that appear on the lock screen when the device is
+locked. They allow the user to perform quick actions without necessarily unlocking their device. For example:
opening an screen that lets them control the smart devices in their home, access their touch-to-pay
-credit card, etc.
-
-## Adding a new Quick Affordance
-### Step 1: create a new quick affordance config
-* Create a new class under the [systemui/keyguard/domain/quickaffordance](../../src/com/android/systemui/keyguard/domain/quickaffordance) directory
-* Please make sure that the class is injected through the Dagger dependency injection system by using the `@Inject` annotation on its main constructor and the `@SysUISingleton` annotation at class level, to make sure only one instance of the class is ever instantiated
-* Have the class implement the [KeyguardQuickAffordanceConfig](../../src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceConfig.kt) interface, notes:
- * The `state` Flow property must emit `State.Hidden` when the feature is not enabled!
- * It is safe to assume that `onQuickAffordanceClicked` will not be invoked if-and-only-if the previous rule is followed
- * When implementing `onQuickAffordanceClicked`, the implementation can do something or it can ask the framework to start an activity using an `Intent` provided by the implementation
-* Please include a unit test for your new implementation under [the correct directory](../../tests/src/com/android/systemui/keyguard/domain/quickaffordance)
-
-### Step 2: choose a position and priority
-* Add the new class as a dependency in the constructor of [KeyguardQuickAffordanceRegistry](../../src/com/android/systemui/keyguard/domain/quickaffordance/KeyguardQuickAffordanceRegistry.kt)
-* Place the new class in one of the available positions in the `configsByPosition` property, note:
- * In each position, there is a list. The order matters. The order of that list is the priority order in which the framework considers each config. The first config whose state property returns `State.Visible` determines the button that is shown for that position
- * Please only add to one position. The framework treats each position individually and there is no good way to prevent the same config from making its button appear in more than one position at the same time
-
-### Step 3: manually verify the new quick affordance
-* Build and launch SysUI on a device
-* Verify that the quick affordance button for the new implementation is correctly visible and clicking it does the right thing
+credit card, turn on the flashlight, etc.
+
+## Creating a new Quick Affordance
+All Quick Affordances are defined in System UI code.
+
+To implement a new Quick Affordance, a developer may add a new implementation of `KeyguardQuickAffordanceConfig` in the `packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance` package/directory and add it to the set defined in `KeyguardDataQuickAffordanceModule`.
+
+Tests belong in the `packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance` package. This should be enough for the system to pick up the new config and make it available for selection by the user.
+
+## Slots
+"Slots" is what we call the position of Quick Affordances on the lock screen. Each slot has a unique ID and a capacity denoting how many Quick Affordances can be "placed" in that slot.
+
+By default, AOSP ships with a "bottom right" and a "bottom left" slot, each with a slot capacity of `1`, allowing only one Quick Affordance on each side of the lock screen.
+
+### Customizing Slots
+OEMs may choose to override the IDs and number of slots and/or override the default capacities. This can be achieved by overridding the `config_keyguardQuickAffordanceSlots` resource in `packages/SystemUI/res/values/config.xml`.
+
+### Default Quick Affordances
+OEMs may also choose to predefine default Quick Affordances for each slot. To achieve this, a developer may override the `config_keyguardQuickAffordanceDefaults` resource in `packages/SystemUI/res/values/config.xml`. Note that defaults only work until the user of the device selects a different quick affordance for that slot, even if they select the "None" option.
+
+## Selections
+"Selections" are many-to-many relationships between slots and quick affordances. We add a selection when the user selects a quick affordance for a specific slot. We remove a selection when the user un-selects a quick affordance in a slot or when the user selects an additional quick affordance for a slot that is already at capacity. The definition of each slot tells us the maximum number of quick affordances that may be selected for each slot.
+
+## Building a Quick affordance Picker Experience
+This section describes how to implement a potential picker, selector, or configuration experience for quick affordances.
+
+### Accessing Quick Affordance Data
+Quick Affordances structured data are exposed to other applications through the `KeyguardQuickAffordanceProvider` content provider which is owned by the System UI process.
+
+To access this content provider, applications must have the `android.permission.ACCESS_KEYGUARD_QUICK_AFFORDANCES` permission which is a signature and privileged permission, limiting access to system apps or apps signed by the same signature as System UI. The `KeyguardQuickAffordanceProviderContract` file defines the content provider schema for consumers.
+
+Generally speaking, there are three important tables served by the content provider: `slots`, `affordances`, and `selections`. There is also a `flags` table, but that's not important and may be ignored.
+
+The `slots`, `affordances`, and `selections` tables may be queried using their `Uri` resulting with a `Cursor` where each row represents a slot, affordance, or selection, respectively. Note that the affordance list does not include the "None" option.
+
+### Modifying Quick Affordance Data
+The `selections` table accepts `insert` or `delete` operations to either add or remove a quick affordance on a slot.
+* To add a selection of a quick affordance on a slot, execute the `insert` operation on the `selections` table `Uri` and include the `slot_id` of the slot and `affordance_id` of the affordance, both in the `ContentValues`
+* To remove a selection of a specific quick affordance from a slot, execute the `delete` operation on the `selections` table `Uri` and include the `slot_id` of the slot and the `affordance_id` of the affordance to remove as the first and second selection arguments, respectively
+* To remove all selections of any currently-selected quick affordance from a specific slot, repeat the above, but omit the `affordance_id`
+
+### The Picker Experience
+A picker experience may:
+* Show the list of available slots based on the result of the `slots` table query
+* Show the list of available quick affordances on the device (regardless of selection) based on the result of the `affordances` table query
+* Show the quick affordances already selected for each slot based on the result of the `selections` table query
+* Select one quick affordance per slot at a time
+* Unselect an already-selected quick affordance from a slot
+* Unselect all already-selected quick affordances from a slot
+
+## Debugging
+To see the current state of the system, you can run `dumpsys`:
+
+```
+$ adb shell dumpsys activity service com.android.systemui/.SystemUIService KeyguardQuickAffordances
+```
+
+The output will spell out the current slot configuration, selections, and collection of available affordances, for example:
+```
+ KeyguardQuickAffordances:
+ ----------------------------------------------------------------------------
+ Slots & selections:
+ bottom_start: home (capacity = 1)
+ bottom_end is empty (capacity = 1)
+ Available affordances on device:
+ home ("Home")
+ wallet ("Wallet")
+ qr_code_scanner ("QR code scanner")
+```
diff --git a/packages/SystemUI/res/layout-sw600dp/global_actions_controls_list_view.xml b/packages/SystemUI/res/layout-sw600dp/global_actions_controls_list_view.xml
deleted file mode 100644
index ef49b9c3b6ad..000000000000
--- a/packages/SystemUI/res/layout-sw600dp/global_actions_controls_list_view.xml
+++ /dev/null
@@ -1,30 +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.
- -->
-
-<com.android.systemui.globalactions.MinHeightScrollView
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical"
- android:scrollbars="none">
- <LinearLayout
- android:id="@+id/global_actions_controls_list"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- android:layout_marginLeft="@dimen/global_actions_side_margin"
- android:layout_marginRight="@dimen/global_actions_side_margin" />
-</com.android.systemui.globalactions.MinHeightScrollView> \ No newline at end of file
diff --git a/packages/SystemUI/res/layout/controls_fullscreen.xml b/packages/SystemUI/res/layout/controls_fullscreen.xml
index 11a566588738..e08e63b39e59 100644
--- a/packages/SystemUI/res/layout/controls_fullscreen.xml
+++ b/packages/SystemUI/res/layout/controls_fullscreen.xml
@@ -15,28 +15,19 @@
limitations under the License.
-->
-<LinearLayout
+<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/control_detail_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
- <com.android.systemui.globalactions.MinHeightScrollView
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_weight="1"
- android:orientation="vertical"
- android:scrollbars="none">
<LinearLayout
android:id="@+id/global_actions_controls"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:clipChildren="false"
+ android:layout_height="match_parent"
android:orientation="vertical"
- android:clipToPadding="false"
android:paddingHorizontal="@dimen/controls_padding_horizontal" />
- </com.android.systemui.globalactions.MinHeightScrollView>
-</LinearLayout>
+</FrameLayout>
diff --git a/packages/SystemUI/res/layout/controls_with_favorites.xml b/packages/SystemUI/res/layout/controls_with_favorites.xml
index 9d011482d011..9efad2269463 100644
--- a/packages/SystemUI/res/layout/controls_with_favorites.xml
+++ b/packages/SystemUI/res/layout/controls_with_favorites.xml
@@ -18,7 +18,7 @@
<LinearLayout
android:layout_width="match_parent"
- android:layout_height="match_parent"
+ android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="@dimen/controls_top_margin"
android:layout_marginBottom="@dimen/controls_header_bottom_margin">
@@ -71,5 +71,27 @@
android:background="?android:attr/selectableItemBackgroundBorderless" />
</LinearLayout>
- <include layout="@layout/global_actions_controls_list_view" />
+ <ScrollView
+ android:id="@+id/controls_scroll_view"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1"
+ android:orientation="vertical"
+ android:clipChildren="true"
+ android:scrollbars="none">
+ <include layout="@layout/global_actions_controls_list_view" />
+
+ </ScrollView>
+
+ <FrameLayout
+ android:id="@+id/controls_panel"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1"
+ android:layout_marginLeft="@dimen/global_actions_side_margin"
+ android:layout_marginRight="@dimen/global_actions_side_margin"
+ android:background="#ff0000"
+ android:padding="@dimen/global_actions_side_margin"
+ android:visibility="gone"
+ />
</merge>
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index afa9818a8442..87ce1771a4f8 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"Laat altyd toe van hierdie rekenaar af"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"Laat toe"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"USB-ontfouting word nie toegelaat nie"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"Die gebruiker wat tans by hierdie toestel aangemeld is, kan nie USB-ontfouting aanskakel nie. Skakel na die primêre gebruiker toe oor om hierdie kenmerk te gebruik."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"Die gebruiker wat tans by hierdie toestel aangemeld is, kan nie USB-ontfouting aanskakel nie. Skakel na ’n admingebruiker toe oor om hierdie kenmerk te gebruik."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Wil jy die stelseltaal na <xliff:g id="LANGUAGE">%1$s</xliff:g> verander?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"\'n Ander toestel het versoek om die stelseltaal te verander"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Verander taal"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"Laat altyd toe op hierdie netwerk"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"Laat toe"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Draadlose ontfouting word nie toegelaat nie"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"Die gebruiker wat tans by hierdie toestel aangemeld is, kan nie draadlose ontfouting aanskakel nie. Skakel na die primêre gebruiker toe oor om hierdie kenmerk te gebruik."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"Die gebruiker wat tans by hierdie toestel aangemeld is, kan nie draadlose ontfouting aanskakel nie. Skakel na ’n admingebruiker toe oor om hierdie kenmerk te gebruik."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"USB-poort is gedeaktiveer"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"Die USB-poort is gedeaktiveer om jou toestel teen vloeistowwe en vuilgoed te beskerm en dit sal nie enige bykomstighede bespeur nie.\n\nJy sal ingelig word wanneer die USB-poort weer gebruik kan word."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"USB-poort is geaktiveer om laaiers en bykomstighede te bespeur"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Stembystand"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"QR-kodeskandeerder"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"Ontsluit"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"Toestel is gesluit"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Skandeer tans gesig"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Stuur"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"Kan nie gesig herken nie"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Gebruik eerder vingerafdruk"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth gekoppel."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"Batterypersentasie is onbekend."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"Vliegtuigmodus."</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN aan."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"Battery <xliff:g id="NUMBER">%d</xliff:g> persent."</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Battery <xliff:g id="PERCENTAGE">%1$s</xliff:g> persent, ongeveer <xliff:g id="TIME">%2$s</xliff:g> oor gegrond op jou gebruik"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Battery <xliff:g id="PERCENTAGE">%1$d</xliff:g> persent, ongeveer <xliff:g id="TIME">%2$s</xliff:g> oor gegrond op jou gebruik"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Battery laai tans, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"Sien alle kennisgewings"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"TeleTypewriter geaktiveer."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Luitoestel-vibreer."</string>
@@ -305,28 +310,17 @@
<string name="sensor_privacy_mic_unblocked_toast_content" msgid="306555320557065068">"Mikrofoon beskikbaar"</string>
<string name="sensor_privacy_camera_unblocked_toast_content" msgid="7843105715964332311">"Kamera beskikbaar"</string>
<string name="sensor_privacy_mic_camera_unblocked_toast_content" msgid="7339355093282661115">"Mikrofoon en kamera beskikbaar"</string>
- <!-- no translation found for sensor_privacy_mic_turned_on_dialog_title (6348853159838376513) -->
- <skip />
- <!-- no translation found for sensor_privacy_mic_turned_off_dialog_title (5760464281790732849) -->
- <skip />
- <!-- no translation found for sensor_privacy_mic_unblocked_dialog_content (4889961886199270224) -->
- <skip />
- <!-- no translation found for sensor_privacy_mic_blocked_no_exception_dialog_content (5864898470772965394) -->
- <skip />
- <!-- no translation found for sensor_privacy_mic_blocked_with_exception_dialog_content (810289713700437896) -->
- <skip />
- <!-- no translation found for sensor_privacy_camera_turned_on_dialog_title (8039095295100075952) -->
- <skip />
- <!-- no translation found for sensor_privacy_camera_turned_off_dialog_title (1936603903120742696) -->
- <skip />
- <!-- no translation found for sensor_privacy_camera_unblocked_dialog_content (7847190103011782278) -->
- <skip />
- <!-- no translation found for sensor_privacy_camera_blocked_dialog_content (3182428709314874616) -->
- <skip />
- <!-- no translation found for sensor_privacy_htt_blocked_dialog_content (3333321592997666441) -->
- <skip />
- <!-- no translation found for sensor_privacy_dialog_open_settings (1503088305279285048) -->
- <skip />
+ <string name="sensor_privacy_mic_turned_on_dialog_title" msgid="6348853159838376513">"Mikrofoon is aangeskakel"</string>
+ <string name="sensor_privacy_mic_turned_off_dialog_title" msgid="5760464281790732849">"Mikrofoon is afgeskakel"</string>
+ <string name="sensor_privacy_mic_unblocked_dialog_content" msgid="4889961886199270224">"Mikrofoon is vir alle apps en dienste geaktiveer."</string>
+ <string name="sensor_privacy_mic_blocked_no_exception_dialog_content" msgid="5864898470772965394">"Mikrofoontoegang is vir alle apps en dienste gedeaktiveer. Jy kan mikrofoontoegang aktiveer in Instellings &gt; Privaatheid &gt; Mikrofoon."</string>
+ <string name="sensor_privacy_mic_blocked_with_exception_dialog_content" msgid="810289713700437896">"Mikrofoontoegang is vir alle apps en dienste gedeaktiveer. Jy kan dit in Instellings &gt; Privaatheid &gt; Mikrofoon verander."</string>
+ <string name="sensor_privacy_camera_turned_on_dialog_title" msgid="8039095295100075952">"Kamera is aangeskakel"</string>
+ <string name="sensor_privacy_camera_turned_off_dialog_title" msgid="1936603903120742696">"Kamera is afgeskakel"</string>
+ <string name="sensor_privacy_camera_unblocked_dialog_content" msgid="7847190103011782278">"Kamera is vir alle apps en dienste geaktiveer."</string>
+ <string name="sensor_privacy_camera_blocked_dialog_content" msgid="3182428709314874616">"Kameratoegang is vir alle apps en dienste gedeaktiveer."</string>
+ <string name="sensor_privacy_htt_blocked_dialog_content" msgid="3333321592997666441">"Aktiveer mikrofoontoegang in Instellings om die mikrofoonknoppie te gebruik."</string>
+ <string name="sensor_privacy_dialog_open_settings" msgid="1503088305279285048">"Maak instellings oop."</string>
<string name="media_seamless_other_device" msgid="4654849800789196737">"Ander toestel"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Wissel oorsig"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Jy sal nie deur geluide en vibrasies gepla word nie, behalwe deur wekkers, herinneringe, geleenthede en bellers wat jy spesifiseer. Jy sal steeds enigiets hoor wat jy kies om te speel, insluitend musiek, video\'s en speletjies."</string>
@@ -397,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Wanneer jy ’n program deel, opneem of uitsaai, het <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> toegang tot enigiets wat in daardie program sigbaar is of daarin gespeel word. Wees dus versigtig met wagwoorde, betalingbesonderhede, boodskappe of ander sensitiewe inligting."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Gaan voort"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Deel of neem ’n program op"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Laat hierdie app toe om te deel of op te neem?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Wanneer jy deel, opneem of uitsaai, het hierdie app toegang tot enigiets wat op jou skerm sigbaar is of op jou toestel gespeel word. Wees dus versigtig met wagwoorde, betalingbesonderhede, boodskappe of ander sensitiewe inligting."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Wanneer jy ’n app deel, opneem of uitsaai, het hierdie app toegang tot enigiets wat in daardie program sigbaar is of daarin gespeel word. Wees dus versigtig met wagwoorde, betalingbesonderhede, boodskappe of ander sensitiewe inligting."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Deur jou IT-admin geblokkeer"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"Skermskote is deur toestelbeleid gedeaktiveer"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Vee alles uit"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Bestuur"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Geskiedenis"</string>
@@ -522,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Ontsluit om te gebruik"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Kon nie jou kaarte kry nie; probeer later weer"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Sluitskerminstellings"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"Skandeer QR-kode"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Werkprofiel"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Vliegtuigmodus"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Jy sal nie jou volgende wekker <xliff:g id="WHEN">%1$s</xliff:g> hoor nie"</string>
@@ -805,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Vergroot die hele skerm"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Vergroot \'n deel van die skerm"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Wissel"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Laat diagonale rollees toe"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Verander grootte"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"Verander vergrotingtipe"</string>
@@ -1035,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EE. d MMM."</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"Gee <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> toegang tot alle toestelloglêers?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"Gee eenmalige toegang"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Moenie toelaat nie"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"Toestelloglêers teken aan wat op jou toestel gebeur. Apps kan hierdie loglêers gebruik om kwessies op te spoor en reg te stel.\n\nSommige loglêers bevat dalk sensitiewe inligting, en daarom moet jy toegang tot alle toestelloglêers net gee aan apps wat jy vertrou. \n\nHierdie app het steeds toegang tot sy eie loglêers as jy nie vir hierdie app toegang tot alle toestelloglêers gee nie. Jou toestelvervaardiger het dalk steeds toegang tot sommige loglêers of inligting op jou toestel."</string>
</resources>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 5c4e76655259..7dfc8519b460 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -52,7 +52,8 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"ሁልጊዜ ከዚህ ኮምፒውተር ፍቀድ"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"ፍቀድ"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"የዩኤስቢ እርማት አይፈቀድም"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"አሁን ወደዚህ መሣሪያ የገባው ተጠቃሚ የዩኤስቢ እርማትን ማብራት አይችልም። ይህን ባህሪ ለመጠቀም ወደ ዋና ተጠቃሚ ይቀይሩ።"</string>
+ <!-- no translation found for usb_debugging_secondary_user_message (1888835696965417845) -->
+ <skip />
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"የስርዓት ቋንቋውን ወደ <xliff:g id="LANGUAGE">%1$s</xliff:g> መቀየር ይፈልጋሉ?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"በሌላ መሳሪያ የተጠየቀ የስርዓት ቋንቋ ለውጥ"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"ቋንቋ ቀይር"</string>
@@ -62,7 +63,8 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"ሁልጊዜ በዚህ አውታረ መረብ ላይ ፍቀድ"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"ፍቀድ"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"ገመድ-አልባ debugging አይፈቀድም"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"በአሁኑ ጊዜ በመለያ ወደዚህ መሣሪያ የገባው ተጠቃሚ የገመድ-አልባ ማረምን ማብራት አይችልም። ይህን ባህሪ ለመጠቀም ወደ ዋና ተጠቃሚ ይቀይሩ።"</string>
+ <!-- no translation found for wifi_debugging_secondary_user_message (9085779370142222881) -->
+ <skip />
<string name="usb_contaminant_title" msgid="894052515034594113">"የዩኤስቢ ወደብ ተሰናክሏል"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"መሣሪያዎን ከፈሳሽ ወይም ፍርስራሽ ለመጠበቅ ሲባል የዩኤስቢ ወደቡ ተሰናክሏል፣ እና ማናቸውም ተቀጥላዎችን አያገኝም።\n\nየዩኤስቢ ወደቡን እንደገና መጠቀም ችግር በማይኖረው ጊዜ ማሳወቂያ ይደርሰዎታል።"</string>
<string name="usb_port_enabled" msgid="531823867664717018">"ኃይል መሙያዎችን እና ተጨማሪ መሣሪያዎችን ፈልጎ ለማግኘት የነቃ የዩኤስቢ ወደብ"</string>
@@ -125,7 +127,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"የድምጽ እርዳታ"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"የQR ኮድ መቃኛ"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"ክፈት"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"መሣሪያ ተቆልፏል"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"የቅኝት ፊት"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"ላክ"</string>
@@ -168,7 +171,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"መልክን መለየት አልተቻለም"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"በምትኩ የጣት አሻራን ይጠቀሙ"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"ብሉቱዝ ተያይዟል።"</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"የባትሪ መቶኛ አይታወቅም።"</string>
@@ -180,8 +183,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"የአውሮፕላን ሁነታ።"</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"ቪፒኤን በርቷል።"</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"የባትሪ <xliff:g id="NUMBER">%d</xliff:g> መቶኛ።"</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"ባትሪ <xliff:g id="PERCENTAGE">%1$s</xliff:g> በመቶ፣ በአጠቃቀምዎ ላይ በመመስረት <xliff:g id="TIME">%2$s</xliff:g> ገደማ ይቀራል"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"ባትሪ <xliff:g id="PERCENTAGE">%1$d</xliff:g> በመቶ፣ በአጠቃቀምዎ ላይ በመመስረት <xliff:g id="TIME">%2$s</xliff:g> ገደማ ይቀራል"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"ባትሪ ኃይል በመሙላት ላይ፣ <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> %%."</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"ሁሉንም ማሳወቂያዎች ይመልከቱ"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"TeleTypewriter ነቅቷል።"</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"የስልክ ጥሪ ይንዘር።"</string>
@@ -386,16 +393,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"አንድን መተግበሪያ ሲያጋሩ፣ ሲቀርጹ ወይም cast ሲያደርጉ <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> በዚያ መተግበሪያ ላይ ለሚታይ ወይም ለሚጫወት ማንኛውም ነገር መዳረሻ አለው። ስለዚህ በይለፍ ቃላት፣ በክፍያ ዝርዝሮች፣ በመልዕክቶች ወይም በሌሎች ልዩ ጥንቃቄ የሚያስፈልጋቸው መረጃዎች ላይ ጥንቃቄ ያድርጉ።"</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"ቀጥል"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"መተግበሪያ ያጋሩ ወይም ይቅረጹ"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"ይህ መተግበሪያ እንዲያጋራ ወይም እንዲቀርጽ ይፈቀድለት?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"ሲያጋሩ፣ ሲቀርጹ ወይም cast ሲያደርጉ ይህ መተግበሪያ በማያ ገጽዎ ላይ ለሚታይ ወይም በመሣሪያዎ ላይ ለሚጫወት ማንኛውም ነገር መዳረሻ አለው። ስለዚህ በይለፍ ቃላት፣ በክፍያ ዝርዝሮች፣ በመልዕክቶች ወይም በሌሎች ልዩ ጥንቃቄ የሚያስፈልጋቸው መረጃዎች ላይ ጥንቃቄ ያድርጉ።"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"አንድን መተግበሪያ ሲያጋሩ፣ ሲቀርጹ ወይም cast ሲያደርጉ ይህ መተግበሪያ በዚያ መተግበሪያ ላይ ለሚታይ ወይም ለሚጫወት ማንኛውም ነገር መዳረሻ አለው። ስለዚህ በይለፍ ቃላት፣ በክፍያ ዝርዝሮች፣ በመልዕክቶች ወይም በሌሎች ልዩ ጥንቃቄ የሚያስፈልጋቸው መረጃዎች ላይ ጥንቃቄ ያድርጉ።"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"በእርስዎ የአይቲ አስተዳዳሪ ታግዷል"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"የማያ ገጽ ቀረጻ በመሣሪያ መመሪያ ተሰናክሏል"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"ሁሉንም አጽዳ"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"ያቀናብሩ"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"ታሪክ"</string>
@@ -511,7 +513,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"ለማየት ይክፈቱ"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"የእርስዎን ካርዶች ማግኘት ላይ ችግር ነበር፣ እባክዎ ቆይተው እንደገና ይሞክሩ"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"የገጽ መቆለፊያ ቅንብሮች"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"QR ኮድ ቃኝ"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"የስራ መገለጫ"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"የአውሮፕላን ሁነታ"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"የእርስዎን ቀጣይ ማንቂያ <xliff:g id="WHEN">%1$s</xliff:g> አይሰሙም"</string>
@@ -794,6 +797,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"ሙሉ ገጽ እይታን ያጉሉ"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"የማያ ገጹን ክፍል አጉላ"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"ማብሪያ/ማጥፊያ"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"ሰያፍ ሽብለላን ፍቀድ"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"መጠን ቀይር"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"የማጉላት አይነትን ለውጥ"</string>
@@ -1024,4 +1029,12 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE፣ MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <!-- no translation found for log_access_confirmation_title (4843557604739943395) -->
+ <skip />
+ <!-- no translation found for log_access_confirmation_allow (752147861593202968) -->
+ <skip />
+ <!-- no translation found for log_access_confirmation_deny (2389461495803585795) -->
+ <skip />
+ <!-- no translation found for log_access_confirmation_body (6883031912003112634) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index f9b866d930ef..e84402d9c2a5 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"السماح دائمًا من هذا الكمبيوتر"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"سماح"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"‏لا يُسمح بتصحيح أخطاء USB"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"‏لا يمكن للمستخدم الذي يسجّل دخوله حاليًا إلى هذا الجهاز تفعيل تصحيح الأخطاء USB. لاستخدام هذه الميزة، يمكنك التبديل إلى المستخدم الأساسي."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"‏لا يمكن للمستخدم المسجِّل دخوله حاليًا على هذا الجهاز تفعيل ميزة \"تصحيح أخطاء الجهاز عبر USB\". لاستخدام هذه الميزة، يمكنك التبديل إلى مستخدم مشرف."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"هل تريد تغيير لغة النظام إلى <xliff:g id="LANGUAGE">%1$s</xliff:g>؟"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"طلب جهاز آخر تغيير لغة النظام."</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"تغيير اللغة"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"السماح باستخدام هذه الميزة على هذه الشبكة دائمًا"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"سماح"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"غير مسموح باستخدام ميزة \"تصحيح الأخطاء اللاسلكي\""</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"لا يمكن للمستخدم المسجِّل دخوله حاليًا على هذا الجهاز تفعيل ميزة \"تصحيح الأخطاء اللاسلكي\". لاستخدام هذه الميزة، يمكنك التبديل إلى المستخدم الأساسي."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"لا يمكن للمستخدم المسجِّل دخوله حاليًا على هذا الجهاز تفعيل ميزة \"تصحيح الأخطاء اللاسلكي\". لاستخدام هذه الميزة، يمكنك التبديل إلى مستخدم مشرف."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"‏تمّ إيقاف منفذ USB"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"‏لحماية جهازك من السوائل أو الشوائب، سيتمّ إيقاف منفذ USB ولن يتم رصد أيّ ملحقات.\n\nوسيتمّ إعلامك عندما يُسمح باستخدام منفذ USB مرة أخرى."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"‏تم تفعيل منفذ USB لاكتشاف أجهزة الشحن والملحقات."</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"المساعد الصوتي"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"محفظة"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"الماسح الضوئي لرمز الاستجابة السريعة"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"فتح القفل"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"الجهاز مُقفل."</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"مسح الوجه"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"إرسال"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"يتعذّر التعرّف على الوجه."</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"يمكنك استخدام بصمة إصبعك."</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"تم توصيل البلوتوث."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"نسبة شحن البطارية غير معروفة."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"وضع الطيران."</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"‏الشبكة الافتراضية الخاصة (VPN) قيد التفعيل."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"مستوى البطارية <xliff:g id="NUMBER">%d</xliff:g> في المائة."</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"نسبة الشحن بالبطارية <xliff:g id="PERCENTAGE">%1$s</xliff:g> بالمائة، ويتبقى <xliff:g id="TIME">%2$s</xliff:g> تقريبًا بناءً على استخدامك."</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"نسبة الشحن بالبطارية <xliff:g id="PERCENTAGE">%1$d</xliff:g> بالمائة، ويتبقى <xliff:g id="TIME">%2$s</xliff:g> تقريبًا بناءً على استخدامك."</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"جارٍ شحن البطارية، <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"الاطّلاع على جميع الإشعارات"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"تم تفعيل المبرقة الكاتبة."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"رنين مع الاهتزاز."</string>
@@ -305,28 +310,17 @@
<string name="sensor_privacy_mic_unblocked_toast_content" msgid="306555320557065068">"يمكنك الوصول إلى الميكروفون الآن."</string>
<string name="sensor_privacy_camera_unblocked_toast_content" msgid="7843105715964332311">"يمكنك الوصول إلى الكاميرا الآن."</string>
<string name="sensor_privacy_mic_camera_unblocked_toast_content" msgid="7339355093282661115">"يمكنك الوصول إلى الميكروفون والكاميرا الآن."</string>
- <!-- no translation found for sensor_privacy_mic_turned_on_dialog_title (6348853159838376513) -->
- <skip />
- <!-- no translation found for sensor_privacy_mic_turned_off_dialog_title (5760464281790732849) -->
- <skip />
- <!-- no translation found for sensor_privacy_mic_unblocked_dialog_content (4889961886199270224) -->
- <skip />
- <!-- no translation found for sensor_privacy_mic_blocked_no_exception_dialog_content (5864898470772965394) -->
- <skip />
- <!-- no translation found for sensor_privacy_mic_blocked_with_exception_dialog_content (810289713700437896) -->
- <skip />
- <!-- no translation found for sensor_privacy_camera_turned_on_dialog_title (8039095295100075952) -->
- <skip />
- <!-- no translation found for sensor_privacy_camera_turned_off_dialog_title (1936603903120742696) -->
- <skip />
- <!-- no translation found for sensor_privacy_camera_unblocked_dialog_content (7847190103011782278) -->
- <skip />
- <!-- no translation found for sensor_privacy_camera_blocked_dialog_content (3182428709314874616) -->
- <skip />
- <!-- no translation found for sensor_privacy_htt_blocked_dialog_content (3333321592997666441) -->
- <skip />
- <!-- no translation found for sensor_privacy_dialog_open_settings (1503088305279285048) -->
- <skip />
+ <string name="sensor_privacy_mic_turned_on_dialog_title" msgid="6348853159838376513">"تم تفعيل الميكروفون"</string>
+ <string name="sensor_privacy_mic_turned_off_dialog_title" msgid="5760464281790732849">"تم إيقاف الميكروفون."</string>
+ <string name="sensor_privacy_mic_unblocked_dialog_content" msgid="4889961886199270224">"تم تفعيل الميكروفون لكل التطبيقات والخدمات."</string>
+ <string name="sensor_privacy_mic_blocked_no_exception_dialog_content" msgid="5864898470772965394">"‏تم إيقاف إمكانية وصول كل التطبيقات والخدمات إلى الميكروفون. يمكنك تفعيل إمكانية الوصول إلى الميكروفون في الإعدادات &gt; الخصوصية &gt; الميكروفون."</string>
+ <string name="sensor_privacy_mic_blocked_with_exception_dialog_content" msgid="810289713700437896">"‏تم إيقاف إمكانية وصول كل التطبيقات والخدمات إلى الميكروفون. يمكنك تغيير ذلك في الإعدادات &gt; الخصوصية &gt; الميكروفون."</string>
+ <string name="sensor_privacy_camera_turned_on_dialog_title" msgid="8039095295100075952">"تم تفعيل الكاميرا"</string>
+ <string name="sensor_privacy_camera_turned_off_dialog_title" msgid="1936603903120742696">"تم إيقاف الكاميرا"</string>
+ <string name="sensor_privacy_camera_unblocked_dialog_content" msgid="7847190103011782278">"تم تفعيل الكاميرا لكل التطبيقات والخدمات."</string>
+ <string name="sensor_privacy_camera_blocked_dialog_content" msgid="3182428709314874616">"تم إيقاف إمكانية وصول كل التطبيقات والخدمات إلى الكاميرا."</string>
+ <string name="sensor_privacy_htt_blocked_dialog_content" msgid="3333321592997666441">"لاستخدام زر الميكروفون، عليك تفعيل إمكانية الوصول إلى الميكروفون في \"الإعدادات\"."</string>
+ <string name="sensor_privacy_dialog_open_settings" msgid="1503088305279285048">"فتح الإعدادات"</string>
<string name="media_seamless_other_device" msgid="4654849800789196737">"جهاز آخر"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"تبديل \"النظرة العامة\""</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"لن يتم إزعاجك بالأصوات والاهتزاز، باستثناء المُنبِّهات والتذكيرات والأحداث والمتصلين الذين تحددهم. وسيظل بإمكانك سماع أي عناصر أخرى تختار تشغيلها، بما في ذلك الموسيقى والفيديوهات والألعاب."</string>
@@ -397,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"أثناء مشاركة محتوى تطبيق أو تسجيله أو بثه، يمكن لتطبيق <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> الوصول إلى كل العناصر المعروضة أو التي يتم تشغيلها في ذلك التطبيق، لذا يُرجى توخي الحذر بشأن كلمات المرور أو تفاصيل الدفع أو الرسائل أو المعلومات الحساسة الأخرى."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"متابعة"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"مشاركة محتوى تطبيق أو تسجيله"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"هل تريد السماح لهذا التطبيق بمشاركة المحتوى أو تسجيله؟"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"أثناء مشاركة المحتوى أو تسجيله أو بثه، يمكن لهذا التطبيق الوصول إلى كل العناصر المرئية على شاشتك أو التي يتم تشغيلها على جهازك، لذا يُرجى توخي الحذر بشأن كلمات المرور أو تفاصيل الدفع أو الرسائل أو المعلومات الحساسة الأخرى."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"أثناء مشاركة محتوى تطبيق أو تسجيله أو بثه، يمكن لهذا التطبيق الوصول إلى كل العناصر المعروضة أو التي يتم تشغيلها في ذلك التطبيق، لذا يُرجى توخي الحذر بشأن كلمات المرور أو تفاصيل الدفع أو الرسائل أو المعلومات الحساسة الأخرى."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"حظر مشرف تكنولوجيا المعلومات هذه الميزة"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"ميزة \"تصوير الشاشة\" غير مفعَّلة بسبب سياسة الجهاز."</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"محو الكل"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"إدارة"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"السجلّ"</string>
@@ -522,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"فتح القفل للاستخدام"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"حدثت مشكلة أثناء الحصول على البطاقات، يُرجى إعادة المحاولة لاحقًا."</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"إعدادات شاشة القفل"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"مسح رمز الاستجابة السريعة ضوئيًا"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"الملف الشخصي للعمل"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"وضع الطيران"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"لن تسمع المنبّه القادم في <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -805,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"تكبير الشاشة كلها"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"تكبير جزء من الشاشة"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"تبديل"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"السماح بالتمرير القطري"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"تغيير الحجم"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"تغيير نوع التكبير"</string>
@@ -1035,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"‏EEE،‏ d‏ MMM"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"هل تريد السماح لتطبيق \"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g>\" بالوصول إلى جميع سجلّات الجهاز؟"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"السماح بالوصول إلى السجلّ لمرة واحدة"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"عدم السماح"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"ترصد سجلّات الجهاز ما يحدث على جهازك. يمكن أن تستخدم التطبيقات هذه السجلّات لتحديد المشاكل وحلّها.\n\nقد تحتوي بعض السجلّات على معلومات حساسة، ولذلك يجب عدم السماح بالوصول إلى جميع سجلّات الجهاز إلا للتطبيقات التي تثق بها. \n\nإذا لم تسمح بوصول هذا التطبيق إلى جميع سجلّات الجهاز، يظل بإمكان التطبيق الوصول إلى سجلّاته. ويظل بإمكان الشركة المصنِّعة لجهازك الوصول إلى بعض السجلّات أو المعلومات المتوفّرة على جهازك."</string>
</resources>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index a34182022b38..ac2eb5a29c38 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"এই কম্পিউটাৰটোৰ পৰা সদায় অনুমতি দিয়ক"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"অনুমতি দিয়ক"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"ইউএছবি ডিবাগিঙৰ অনুমতি নাই"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"এই ডিভাইচটোত বর্তমান ছাইন ইন হৈ থকা ব্যৱহাৰকাৰীজনে ইউএছবি ডিবাগিং অন কৰিব নোৱাৰে। এই সুবিধাটো ব্যৱহাৰ কৰিবলৈ হ\'লে মুখ্য ব্যৱহাৰকাৰী হিচাপে ছাইন ইন কৰক।"</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"বৰ্তমান এই ডিভাইচটোত ছাইন ইন হৈ থকা ব্যৱহাৰকাৰীগৰাকীয়ে ইউএছবি ডিবাগিং অন কৰিব নোৱাৰে। এই সুবিধাটো ব্যৱহাৰ কৰিবলৈ, এগৰাকী প্ৰশাসক ব্যৱহাৰকাৰীলৈ সলনি কৰক।"</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"আপুনি ছিষ্টেমৰ ভাষা <xliff:g id="LANGUAGE">%1$s</xliff:g>লৈ সলনি কৰিবলৈ বিচাৰেনে?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"অন্য এটা ডিভাইচে ছিষ্টেমৰ ভাষা সলনি কৰাৰ অনুৰোধ কৰিছে"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"ভাষা সলনি কৰক"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"এই নেটৱৰ্কত সদায় অনুমতি দিয়ক"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"অনুমতি দিয়ক"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"ৱায়াৰলেচ ডি\'বাগিংৰ অনুমতি নাই"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"এই ডিভাইচটোত বর্তমান ছাইন ইন হৈ থকা ব্যৱহাৰকাৰীজনে ৱায়াৰলেচ ডি\'বাগিং অন কৰিব নোৱাৰে। এই সুবিধাটো ব্যৱহাৰ কৰিবলৈ হ’লে প্ৰাথমিক ব্যৱহাৰকাৰী হিচাপে ছাইন ইন কৰক।"</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"বৰ্তমান এই ডিভাইচটোত ছাইন ইন হৈ থকা ব্যৱহাৰকাৰীগৰাকীয়ে ৱায়াৰলেচ ডি’বাগিং অন কৰিব নোৱাৰে। এই সুবিধাটো ব্যৱহাৰ কৰিবলৈ, এগৰাকী প্ৰশাসক ব্যৱহাৰকাৰীলৈ সলনি কৰক।"</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"ইউএছবি প’ৰ্ট অক্ষম কৰা হ’ল"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"আপোনাৰ ডিভাইচটো তৰল বা ধূলি-মাকতিৰ পৰা ৰক্ষা কৰিবলৈ ইউএছবি প’ৰ্টটো অক্ষম কৰি ৰখা হৈছে ফলত ই কোনো আনুষংগিক সামগ্ৰী ধৰা পেলাব নোৱাৰে।\n\nযেতিয়া ইউএছবি প’ৰ্টটো নিৰাপদভাৱে ব্যৱহাৰ কৰিব পৰা হ’ব তেতিয়া আপোনাক জনোৱা হ’ব।"</string>
<string name="usb_port_enabled" msgid="531823867664717018">"চাৰ্জাৰ আৰু আনুষংগিক সামগ্ৰী চিনাক্ত কৰিবলৈ USB প’ৰ্ট সক্ষম কৰা হ’ল"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"কণ্ঠধ্বনিৰে সহায়"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"ৱালেট"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"কিউআৰ ক’ড স্কেনাৰ"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"আনলক কৰক"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"ডিভাইচটো লক হৈ আছে"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"চেহেৰা স্কেন কৰি থকা হৈছে"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"পঠিয়াওক"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"মুখাৱয়ব চিনিব নোৱাৰি"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"ইয়াৰ সলনি ফিংগাৰপ্ৰিণ্ট ব্যৱহাৰ কৰক"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"ব্লুটুথ সংযোগ হ’ল।"</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"বেটাৰীৰ চাৰ্জৰ শতাংশ অজ্ঞাত।"</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"এয়াৰপ্লে’ন ম’ড।"</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"ভিপিএন অন অৱস্থাত আছে।"</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"<xliff:g id="NUMBER">%d</xliff:g> শতাংশ বেটাৰী।"</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"আপোনাৰ ব্যৱহাৰৰ ওপৰত ভিত্তি কৰি বেটাৰী <xliff:g id="PERCENTAGE">%1$s</xliff:g> শতাংশ, প্ৰায় <xliff:g id="TIME">%2$s</xliff:g> বাকী আছে"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"আপোনাৰ ব্যৱহাৰৰ ওপৰত ভিত্তি কৰি বেটাৰী <xliff:g id="PERCENTAGE">%1$d</xliff:g> শতাংশ, প্ৰায় <xliff:g id="TIME">%2$s</xliff:g> বাকী আছে"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"বেটাৰী চাৰ্জ হৈ আছে, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> শতাংশ।"</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"আটাইবোৰ জাননী চাওক"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"TeleTypewriter সক্ষম কৰা হ\'ল৷"</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"ৰিংগাৰ কম্পন অৱস্থাত আছে৷"</string>
@@ -386,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"আপুনি শ্বেয়াৰ কৰা, ৰেকৰ্ড কৰা অথবা কাষ্ট কৰাৰ সময়ত, সেইটো এপত দৃশ্যমান যিকোনো বস্তু অথবা আপোনাৰ ডিভাইচত প্লে’ কৰা যিকোনো সমললৈ <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>ৰ এক্সেছ থাকে। গতিকে, পাছৱৰ্ড, পৰিশোধৰ সবিশেষ, বাৰ্তা অথবা অন্য সংবেদনশীল তথ্যৰ ক্ষেত্ৰত সাৱধান হওক।"</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"অব্যাহত ৰাখক"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"এটা এপ্ শ্বেয়াৰ অথবা ৰেকৰ্ড কৰক"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"এই এপ্‌টোক শ্বেয়াৰ অথবা ৰেকৰ্ড কৰিবলৈ অনুমতি দিবনে?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"আপুনি শ্বেয়াৰ কৰা, ৰেকৰ্ড কৰা অথবা কাষ্ট কৰাৰ সময়ত, আপোনাৰ স্ক্ৰীনখনত দৃশ্যমান যিকোনো বস্তু অথবা আপোনাৰ ডিভাইচত প্লে’ কৰা যিকোনো সমললৈ এই এপ্‌টোৰ এক্সেছ থাকে। গতিকে, পাছৱৰ্ড, পৰিশোধৰ সবিশেষ, বাৰ্তা অথবা অন্য সংবেদনশীল তথ্যৰ ক্ষেত্ৰত সাৱধান হওক।"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"আপুনি শ্বেয়াৰ কৰা, ৰেকৰ্ড কৰা অথবা কাষ্ট কৰাৰ সময়ত, সেইটো এপত দৃশ্যমান যিকোনো বস্তু অথবা আপোনাৰ ডিভাইচত প্লে’ কৰা যিকোনো সমললৈ এই এপ্‌টোৰ এক্সেছ থাকে। গতিকে, পাছৱৰ্ড, পৰিশোধৰ সবিশেষ, বাৰ্তা অথবা অন্য সংবেদনশীল তথ্যৰ ক্ষেত্ৰত সাৱধান হওক।"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"আপোনাৰ আইটি প্ৰশাসকে অৱৰোধ কৰিছে"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"ডিভাইচ সম্পৰ্কীয় নীতিয়ে স্ক্ৰীন কেপশ্বাৰ কৰাটো অক্ষম কৰিছে"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"আটাইবোৰ মচক"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"পৰিচালনা"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"ইতিহাস"</string>
@@ -511,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"ব্যৱহাৰ কৰিবলৈ আনলক কৰক"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"আপোনাৰ কাৰ্ড লাভ কৰোঁতে এটা সমস্যা হৈছে, অনুগ্ৰহ কৰি পাছত পুনৰ চেষ্টা কৰক"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"লক স্ক্ৰীনৰ ছেটিং"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"কিউআৰ ক’ড স্কেন কৰক"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"কৰ্মস্থানৰ প্ৰ\'ফাইল"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"এয়াৰপ্লে’ন ম’ড"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"আপুনি আপোনাৰ পিছৰটো এলাৰ্ম <xliff:g id="WHEN">%1$s</xliff:g> বজাত শুনা নাপাব"</string>
@@ -794,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"পূৰ্ণ স্ক্ৰীন বিবৰ্ধন কৰক"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"স্ক্ৰীনৰ কিছু অংশ বিবৰ্ধন কৰক"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"ছুইচ"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"কৰ্ণডালৰ দিশত স্ক্ৰ’ল কৰাৰ সুবিধা"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"আকাৰ সলনি কৰক"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"বিবৰ্ধনৰ প্ৰকাৰ সলনি কৰক"</string>
@@ -1024,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g>ক আটাইবোৰ ডিভাইচৰ লগ এক্সেছ কৰাৰ অনুমতি প্ৰদান কৰিবনে?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"কেৱল এবাৰ এক্সেছ কৰাৰ অনুমতি দিয়ক"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"অনুমতি নিদিব"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"আপোনাৰ ডিভাইচত কি কি ঘটে সেয়া ডিভাইচ লগে ৰেকৰ্ড কৰে। এপ্‌সমূহে সমস্যা বিচাৰিবলৈ আৰু সমাধান কৰিবলৈ এই লগসমূহ ব্যৱহাৰ কৰিব পাৰে।\n\nকিছুমান লগত সংবেদনশীল তথ্য থাকিব পাৰে, গতিকে কেৱল আপুনি বিশ্বাস কৰা এপকহে আটাইবোৰ ডিভাইচ লগ এক্সেছ কৰাৰ অনুমতি দিয়ক। \n\nআপুনি যদি এই এপ্‌টোক আটাইবোৰ ডিভাইচ লগ এক্সেছ কৰাৰ অনুমতি নিদিয়ে, তথাপিও ই নিজৰ লগসমূহ এক্সেছ কৰিব পাৰিব। আপোনাৰ ডিভাইচৰ নিৰ্মাতাই তথাপিও হয়তো আপোনাৰ ডিভাইচটোত থকা কিছু লগ অথবা তথ্য এক্সেছ কৰিব পাৰিব।"</string>
</resources>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index ed95d8080fc3..2b159903c500 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"Bu kompüterdən həmişə icazə verilsin"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"İcazə verin"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"USB ilə sazlama qadağandır"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"Hazırda bu cihaza daxil olmuş istifadəçi USB sazlama prosesini aktiv edə bilməz. Bu funksiyadan istifadə etmək üçün əsas istifadəçi hesaba daxil olmalıdır."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"Hazırda bu cihaza daxil olmuş istifadəçi USB sazlama prosesini aktiv edə bilməz. Bu funksiyadan istifadə etmək üçün admin istifadəçiyə keçin."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Sistem dili <xliff:g id="LANGUAGE">%1$s</xliff:g> dilinə dəyişdirilsin?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Sistem dilinin dəyişdirilməsi başqa cihaz tərəfindən tələb olunur"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Dili dəyişin"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"Bu şəbəkədə həmişə icazə verilsin"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"İcazə verin"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"WiFi sazlamasına icazə verilmir"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"Hazırda bu cihaza daxil olmuş istifadəçi WiFi sazlamasını aktiv edə bilmir. Bu funksiyadan istifadə etmək üçün əsas istifadəçiyə keçin."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"Hazırda bu cihaza daxil olmuş istifadəçi WiFi sazlamasını aktiv edə bilmir. Bu funksiyadan istifadə etmək üçün admin istifadəçiyə keçin."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"USB portu deaktiv edildi"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"USB portu deaktivdir. Cihazı maye və zərbədən qorumaq üçün aksesuar aşkarlanmayacaq.\n\nUSB portu yenidən istifadə üçün təhlükəsiz olduqda bildiriş göndəriləcək."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"Adapter və aksesuarları aşkarlamaq üçün USB portu aktiv edildi"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Səs Yardımçısı"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Pulqabı"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"QR Kodu Skaneri"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"Kiliddən çıxarın"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"Cihaz kilidlənib"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Üzün skan edilməsi"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Göndərin"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"Üzü tanımaq olmur"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Barmaq izi istifadə edin"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth qoşulub."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"Batareyanın faizi naməlumdur."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"Uçuş rejimi"</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN aktivdir."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"Batareya <xliff:g id="NUMBER">%d</xliff:g> faizdir."</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Batareya <xliff:g id="PERCENTAGE">%1$s</xliff:g> faizdir, istifadəyə əsasən təxminən <xliff:g id="TIME">%2$s</xliff:g> qalıb"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Batareya <xliff:g id="PERCENTAGE">%1$d</xliff:g> faizdir, istifadəyə əsasən təxminən <xliff:g id="TIME">%2$s</xliff:g> qalıb"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Batareya doldurulur, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%% faiz."</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"Bütün bildirişlərə baxın"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"TeleTypewriter aktivləşdirilib."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Zəng vibrasiyası"</string>
@@ -386,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Paylaşdığınız, qeydə aldığınız və ya yayımladığınız zaman <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> tətbiqi həmin tətbiqdə göstərilən və ya oxudulan hər şeyə giriş edə bilir. Odur ki, parollar, ödəniş detalları, mesajlar və ya digər həssas məlumatlarla bağlı diqqətli olun."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Davam edin"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Tətbiqi paylaşın və ya qeydə alın"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Bu tətbiqə paylaşmağa və ya yazmağa icazə verilsin?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Paylaşdığınız, yazdığınız və ya yayımladığınız zaman bu tətbiq ekranınızda görünən və ya cihazınızda oxudulan hər şeyə giriş edə bilir. Odur ki, parollar, ödəniş detalları, mesajlar və ya digər həssas məlumatlarla bağlı diqqətli olun."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Paylaşdığınız, qeydə aldığınız və ya yayımladığınız zaman bu tətbiq həmin tətbiqdə göstərilən və ya oxudulan hər şeyə giriş edə bilir. Odur ki, parollar, ödəniş detalları, mesajlar və ya digər həssas məlumatlarla bağlı diqqətli olun."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"İT admininiz tərəfindən bloklanıb"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"Ekran çəkimi cihaz siyasəti ilə deaktiv edilib"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Hamısını silin"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"İdarə edin"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Tarixçə"</string>
@@ -511,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"İstifadə etmək üçün kiliddən çıxarın"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Kartların əldə edilməsində problem oldu, sonra yenidən cəhd edin"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Kilid ekranı ayarları"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"QR kodu skanlayın"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"İş profili"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Təyyarə rejimi"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"<xliff:g id="WHEN">%1$s</xliff:g> zaman növbəti xəbərdarlığınızı eşitməyəcəksiniz"</string>
@@ -794,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Tam ekranı böyüdün"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Ekran hissəsinin böyüdülməsi"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Dəyişdirici"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Diaqonal sürüşdürməyə icazə verin"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Ölçüsünü dəyişin"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"Böyütmə növünü dəyişdirin"</string>
@@ -1024,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"HHH, AAA g"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"s:dd"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"ss:dd"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> tətbiqinin bütün cihaz qeydlərinə girişinə icazə verilsin?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"Birdəfəlik girişə icazə verin"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"İcazə verməyin"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"Cihaz qeydləri cihazınızda baş verənləri qeyd edir. Tətbiqlər problemləri tapmaq və həll etmək üçün bu qeydlərdən istifadə edə bilər.\n\nBəzi qeydlərdə həssas məlumatlar ola bilər, ona görə də yalnız etibar etdiyiniz tətbiqlərin bütün cihaz qeydlərinə giriş etməsinə icazə verin. \n\nBu tətbiqin bütün cihaz qeydlərinə girişinə icazə verməsəniz, o, hələ də öz qeydlərinə giriş edə bilər. Cihaz istehsalçınız hələ də cihazınızda bəzi qeydlərə və ya məlumatlara giriş edə bilər."</string>
</resources>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index a2cbce79c927..17d7ffa5a1d0 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"Uvek 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 na USB-u nije dozvoljeno"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"Korisnik koji je trenutno prijavljen na ovaj uređaj ne može da uključi otklanjanje grešaka na USB-u. Da biste koristili ovu funkciju, prebacite na primarnog korisnika."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"Korisnik koji je trenutno prijavljen na ovaj uređaj ne može da uključi otklanjanje grešaka sa USB-a. Da biste koristili ovu funkciju, pređite na korisnika sa administratorskim pravima."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Da li želite da promenite jezik sistema na <xliff:g id="LANGUAGE">%1$s</xliff:g>?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Drugi uređaj je zatražio promenu jezika sistema"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Promeni jezik"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"Uvek dozvoli na ovoj mreži"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"Dozvoli"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Bežično otklanjanje grešaka nije dozvoljeno"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"Korisnik koji je trenutno prijavljen na ovaj uređaj ne može da uključi bežično otklanjanje grešaka. Da biste koristili ovu funkciju, pređite na primarnog korisnika."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"Korisnik koji je trenutno prijavljen na ovaj uređaj ne može da uključi bežično otklanjanje grešaka. Da biste koristili ovu funkciju, pređite na korisnika sa administratorskim pravima."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"USB port je onemogućen"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"Da bi se uređaj zaštitio od tečnosti ili nečistoće, USB port je onemogućen i neće otkrivati dodatnu opremu.\n\nObavestićemo vas kada ponovo budete mogli da koristite USB port."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"USB port je omogućen radi otkrivanja punjača i dodatne opreme"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Glasovna pomoć"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Novčanik"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"Skener QR koda"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"Otključajte"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"Uređaj je zaključan"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Skeniranje lica"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Pošalji"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"Lice nije prepoznato"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Koristite otisak prsta"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth je priključen."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"Procenat napunjenosti baterije nije poznat."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"Režim rada u avionu."</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN je uključen."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"Baterija je na <xliff:g id="NUMBER">%d</xliff:g> posto."</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Baterija je na <xliff:g id="PERCENTAGE">%1$s</xliff:g> posto, preostalo vreme na osnovu korišćenja je <xliff:g id="TIME">%2$s</xliff:g>"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Baterija je na <xliff:g id="PERCENTAGE">%1$d</xliff:g> posto, preostalo vreme na osnovu korišćenja je <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Baterija se puni, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> posto."</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"Pogledajte sva obaveštenja"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"TeleTypewriter je omogućen."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Vibracija zvona."</string>
@@ -305,28 +310,17 @@
<string name="sensor_privacy_mic_unblocked_toast_content" msgid="306555320557065068">"Mikrofon je dostupan"</string>
<string name="sensor_privacy_camera_unblocked_toast_content" msgid="7843105715964332311">"Kamera je dostupna"</string>
<string name="sensor_privacy_mic_camera_unblocked_toast_content" msgid="7339355093282661115">"Mikrofon i kamera su dostupni"</string>
- <!-- no translation found for sensor_privacy_mic_turned_on_dialog_title (6348853159838376513) -->
- <skip />
- <!-- no translation found for sensor_privacy_mic_turned_off_dialog_title (5760464281790732849) -->
- <skip />
- <!-- no translation found for sensor_privacy_mic_unblocked_dialog_content (4889961886199270224) -->
- <skip />
- <!-- no translation found for sensor_privacy_mic_blocked_no_exception_dialog_content (5864898470772965394) -->
- <skip />
- <!-- no translation found for sensor_privacy_mic_blocked_with_exception_dialog_content (810289713700437896) -->
- <skip />
- <!-- no translation found for sensor_privacy_camera_turned_on_dialog_title (8039095295100075952) -->
- <skip />
- <!-- no translation found for sensor_privacy_camera_turned_off_dialog_title (1936603903120742696) -->
- <skip />
- <!-- no translation found for sensor_privacy_camera_unblocked_dialog_content (7847190103011782278) -->
- <skip />
- <!-- no translation found for sensor_privacy_camera_blocked_dialog_content (3182428709314874616) -->
- <skip />
- <!-- no translation found for sensor_privacy_htt_blocked_dialog_content (3333321592997666441) -->
- <skip />
- <!-- no translation found for sensor_privacy_dialog_open_settings (1503088305279285048) -->
- <skip />
+ <string name="sensor_privacy_mic_turned_on_dialog_title" msgid="6348853159838376513">"Mikrofon je uključen"</string>
+ <string name="sensor_privacy_mic_turned_off_dialog_title" msgid="5760464281790732849">"Mikrofon je isključen"</string>
+ <string name="sensor_privacy_mic_unblocked_dialog_content" msgid="4889961886199270224">"Mikrofon je omogućen za sve aplikacije i usluge."</string>
+ <string name="sensor_privacy_mic_blocked_no_exception_dialog_content" msgid="5864898470772965394">"Pristup mikrofonu je onemogućen za sve aplikacije i usluge. Možete da omogućite pristup mikrofonu u Podešavanjima &gt; Privatnost &gt; Mikrofon."</string>
+ <string name="sensor_privacy_mic_blocked_with_exception_dialog_content" msgid="810289713700437896">"Pristup mikrofonu je onemogućen za sve aplikacije i usluge. To možete da promenite u Podešavanjima &gt; Privatnost &gt; Mikrofon."</string>
+ <string name="sensor_privacy_camera_turned_on_dialog_title" msgid="8039095295100075952">"Kamera je uključena"</string>
+ <string name="sensor_privacy_camera_turned_off_dialog_title" msgid="1936603903120742696">"Kamera je isključena"</string>
+ <string name="sensor_privacy_camera_unblocked_dialog_content" msgid="7847190103011782278">"Kamera je omogućena za sve aplikacije i usluge."</string>
+ <string name="sensor_privacy_camera_blocked_dialog_content" msgid="3182428709314874616">"Pristup kameri je onemogućen za sve aplikacije i usluge."</string>
+ <string name="sensor_privacy_htt_blocked_dialog_content" msgid="3333321592997666441">"Da biste koristili dugme mikrofona, omogućite pristup mikrofonu u Podešavanjima."</string>
+ <string name="sensor_privacy_dialog_open_settings" msgid="1503088305279285048">"Otvori Podešavanja."</string>
<string name="media_seamless_other_device" msgid="4654849800789196737">"Drugi uređaj"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Uključi/isključi pregled"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Neće vas uznemiravati zvukovi i vibracije osim za alarme, podsetnike, događaje i pozivaoce koje navedete. I dalje ćete čuti sve što odaberete da pustite, uključujući muziku, video snimke i igre."</string>
@@ -397,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Kada delite, snimate ili prebacujete aplikaciju, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ima pristup kompletnom sadržaju koji je vidljiv ili se pušta u toj aplikaciji. Budite pažljivi sa lozinkama, informacijama o plaćanju, porukama ili drugim osetljivim informacijama."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Nastavi"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Delite ili snimite aplikaciju"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Želite da dozvolite ovoj aplikaciji da deli ili snima?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Kada delite, snimate ili prebacujete, ova aplikacija ima pristup kompletnom sadržaju koji je vidljiv na ekranu ili se pušta na uređaju. Budite pažljivi sa lozinkama, informacijama o plaćanju, porukama ili drugim osetljivim informacijama."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Kada delite, snimate ili prebacujete aplikaciju, ova aplikacija ima pristup kompletnom sadržaju koji je vidljiv ili se pušta u toj aplikaciji. Budite pažljivi sa lozinkama, informacijama o plaćanju, porukama ili drugim osetljivim informacijama."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Blokira IT administrator"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"Snimanje ekrana je onemogućeno smernicama za uređaj"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Obriši sve"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Upravljajte"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Istorija"</string>
@@ -522,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Otključaj radi korišćenja"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Došlo je do problema pri preuzimanju kartica. Probajte ponovo kasnije"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Podešavanja zaključanog ekrana"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"Skenirajte QR kôd"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Poslovni profil"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Režim rada u avionu"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Nećete čuti sledeći alarm u <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -805,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Uvećajte ceo ekran"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Uvećajte deo ekrana"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Pređi"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Dozvoli dijagonalno skrolovanje"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Promeni veličinu"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"Promeni tip uvećanja"</string>
@@ -1035,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"DDD, d. MMM"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"s:min"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"č:min"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"Želite da dozvolite da <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> pristupa svim evidencijama uređaja?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"Dozvoli jednokratan pristup"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Ne dozvoli"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"Evidencije uređaja registruju šta se dešava na uređaju. Aplikacije mogu da koriste te evidencije da bi pronašle i rešile probleme.\n\nNeke evidencije mogu da sadrže osetljive informacije, pa pristup svim evidencijama uređaja treba da dozvoljavate samo aplikacijama u koje imate poverenja. \n\nAko ne dozvolite ovoj aplikaciji da pristupa svim evidencijama uređaja, ona i dalje može da pristupa sopstvenim evidencijama. Proizvođač uređaja će možda i dalje moći da pristupa nekim evidencijama ili informacijama na uređaju."</string>
</resources>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 3d05c86435c3..497f8c06cd2f 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"Заўсёды дазваляць з гэтага камп\'ютара"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"Дазволіць"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"Адладка па USB забаронена"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"Карыстальнік, які зараз увайшоў у гэту прыладу, не можа ўключыць адладку па USB. Каб выкарыстоўваць гэту функцыю, пераключыцеся на асноўнага карыстальніка."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"Карыстальнік, які зараз увайшоў у гэтую прыладу, не можа ўключыць адладку цераз USB. Каб выкарыстоўваць гэтую функцыю, пераключыцеся на адміністратара."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Змяніць мову сістэмы на наступную: \"<xliff:g id="LANGUAGE">%1$s</xliff:g>\"?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Іншая прылада запытала змяненне мовы сістэмы"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Змяніць мову"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"Заўсёды дазваляць у гэтай сетцы"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"Дазволіць"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Адладка па Wi-Fi не дазволена"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"Карыстальнік, які зараз увайшоў у гэту прыладу, не можа ўключыць адладку па Wi-Fi. Каб выкарыстоўваць гэту функцыю, пераключыцеся на асноўнага карыстальніка."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"Карыстальнік, які зараз увайшоў у гэтую прыладу, не можа ўключыць адладку па Wi-Fi. Каб выкарыстоўваць гэтую функцыю, пераключыцеся на адміністратара."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"Порт USB адключаны"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"Порт USB адключаны, каб засцерагчы прыладу ад вадкасці і смецця, таму дадатковае абсталяванне не будзе выяўлена.\n\nВы атрымаеце апавяшчэнне, калі порт USB можна будзе выкарыстоўваць зноў."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"USB-порту дазволена вызначаць зарадныя прылады і аксесуары"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Галасавая дапамога"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Кашалёк"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"Сканер QR-кодаў"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"Разблакiраваць"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"Прылада заблакіравана"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Сканіраванне твару"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Адправіць"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"Твар не распазнаны"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Скарыстайце адбітак пальца"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth-сувязь."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"Працэнт зараду акумулятара невядомы."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"Рэжым палёту."</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN уключана."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"Працэнт зараду акумулятара: <xliff:g id="NUMBER">%d</xliff:g>."</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Зарад акумулятара ў працэнтах: <xliff:g id="PERCENTAGE">%1$s</xliff:g>. Пры такім выкарыстанні яго хопіць прыблізна на <xliff:g id="TIME">%2$s</xliff:g>"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Зарад акумулятара ў працэнтах: <xliff:g id="PERCENTAGE">%1$d</xliff:g>. Пры такім выкарыстанні яго хопіць прыблізна на <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Акумулятар зараджаецца. Бягучы зарад: <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"Паказаць усе апавяшчэнні"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"TeleTypewriter уключаны."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Выклік з вібрацыяй."</string>
@@ -305,28 +310,17 @@
<string name="sensor_privacy_mic_unblocked_toast_content" msgid="306555320557065068">"Мікрафон можна выкарыстоўваць"</string>
<string name="sensor_privacy_camera_unblocked_toast_content" msgid="7843105715964332311">"Камеру можна выкарыстоўваць"</string>
<string name="sensor_privacy_mic_camera_unblocked_toast_content" msgid="7339355093282661115">"Мікрафон і камеру можна выкарыстоўваць"</string>
- <!-- no translation found for sensor_privacy_mic_turned_on_dialog_title (6348853159838376513) -->
- <skip />
- <!-- no translation found for sensor_privacy_mic_turned_off_dialog_title (5760464281790732849) -->
- <skip />
- <!-- no translation found for sensor_privacy_mic_unblocked_dialog_content (4889961886199270224) -->
- <skip />
- <!-- no translation found for sensor_privacy_mic_blocked_no_exception_dialog_content (5864898470772965394) -->
- <skip />
- <!-- no translation found for sensor_privacy_mic_blocked_with_exception_dialog_content (810289713700437896) -->
- <skip />
- <!-- no translation found for sensor_privacy_camera_turned_on_dialog_title (8039095295100075952) -->
- <skip />
- <!-- no translation found for sensor_privacy_camera_turned_off_dialog_title (1936603903120742696) -->
- <skip />
- <!-- no translation found for sensor_privacy_camera_unblocked_dialog_content (7847190103011782278) -->
- <skip />
- <!-- no translation found for sensor_privacy_camera_blocked_dialog_content (3182428709314874616) -->
- <skip />
- <!-- no translation found for sensor_privacy_htt_blocked_dialog_content (3333321592997666441) -->
- <skip />
- <!-- no translation found for sensor_privacy_dialog_open_settings (1503088305279285048) -->
- <skip />
+ <string name="sensor_privacy_mic_turned_on_dialog_title" msgid="6348853159838376513">"Мікрафон уключаны"</string>
+ <string name="sensor_privacy_mic_turned_off_dialog_title" msgid="5760464281790732849">"Мікрафон выключаны"</string>
+ <string name="sensor_privacy_mic_unblocked_dialog_content" msgid="4889961886199270224">"Мікрафон уключаны для ўсіх праграм і сэрвісаў."</string>
+ <string name="sensor_privacy_mic_blocked_no_exception_dialog_content" msgid="5864898470772965394">"Доступ да мікрафона адключаны для ўсіх праграм і сэрвісаў. Вы можаце даць доступ да мікрафона праз меню \"Налады &gt; Прыватнасць &gt; Мікрафон\"."</string>
+ <string name="sensor_privacy_mic_blocked_with_exception_dialog_content" msgid="810289713700437896">"Доступ да мікрафона адключаны для ўсіх праграм і сэрвісаў. Гэту наладу можна змяніць праз меню \"Налады &gt; Прыватнасць &gt; Мікрафон\"."</string>
+ <string name="sensor_privacy_camera_turned_on_dialog_title" msgid="8039095295100075952">"Камера ўключана"</string>
+ <string name="sensor_privacy_camera_turned_off_dialog_title" msgid="1936603903120742696">"Камера выключана"</string>
+ <string name="sensor_privacy_camera_unblocked_dialog_content" msgid="7847190103011782278">"Камера ўключана для ўсіх праграм і сэрвісаў."</string>
+ <string name="sensor_privacy_camera_blocked_dialog_content" msgid="3182428709314874616">"Доступ да камеры адключаны для ўсіх праграм і сэрвісаў."</string>
+ <string name="sensor_privacy_htt_blocked_dialog_content" msgid="3333321592997666441">"Каб выкарыстоўваць кнопку мікрафона, дайце доступ да мікрафона ў Наладах."</string>
+ <string name="sensor_privacy_dialog_open_settings" msgid="1503088305279285048">"Адкрыць налады."</string>
<string name="media_seamless_other_device" msgid="4654849800789196737">"Іншая прылада"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Уключыць/выключыць агляд"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Вас не будуць турбаваць гукі і вібрацыя, за выключэннем будзільнікаў, напамінаў, падзей і выбраных вамі абанентаў. Вы будзеце чуць усё, што ўключыце, у тым ліку музыку, відэа і гульні."</string>
@@ -397,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Калі пачынаецца абагульванне, запіс ці трансляцыя змесціва праграмы, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> атрымлівае доступ да ўсяго змесціва, якое паказваецца ці прайграецца ў праграме. Таму прадухіліце паказ пароляў, плацежных рэквізітаў, паведамленняў і іншай канфідэнцыяльнай інфармацыі."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Далей"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Абагульванне або запіс праграмы"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Дазволіць гэтай праграме абагульваць або запісваць змесціва?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Калі пачынаецца абагульванне, запіс ці трансляцыя, гэта праграма атрымлівае доступ да ўсяго змесціва, якое паказваецца на экране ці прайграецца на прыладзе. Таму прадухіліце паказ пароляў, звестак пра плацяжы, паведамленняў і іншай канфідэнцыяльнай інфармацыі."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Калі пачынаецца абагульванне, запіс ці трансляцыя змесціва праграмы, гэта праграма атрымлівае доступ да ўсяго змесціва, якое ў ёй паказваецца ці прайграецца. Таму прадухіліце паказ пароляў, звестак пра плацяжы, паведамленняў і іншай канфідэнцыяльнай інфармацыі."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Заблакіравана вашым ІТ-адміністратарам"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"Здыманне экрана адключана згодна з палітыкай прылады"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Ачысціць усё"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Кіраваць"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Гісторыя"</string>
@@ -522,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Разблакіраваць для выкарыстання"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Узнікла праблема з загрузкай вашых карт. Паўтарыце спробу пазней"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Налады экрана блакіроўкі"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"Сканіраванне QR-кода"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Працоўны профіль"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Рэжым палёту"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Вы не пачуеце наступны будзільнік <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -805,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Павялічыць увесь экран"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Павялічыць частку экрана"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Пераключальнік"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Дазволіць прагортванне па дыяганалі"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Змяніць памер"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"Змяніць тып павелічэння"</string>
@@ -1035,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"Дазволіць праграме \"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g>\" мець доступ да ўсіх журналаў прылады?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"Дазволіць аднаразовы доступ"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Не дазваляць"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"Журналы прылад запісваюць усё, што адбываецца на вашай прыладзе. Праграмы выкарыстоўваюць гэтыя журналы для пошуку і выпраўлення памылак.\n\nУ некаторых журналах можа ўтрымлівацца канфідэнцыяльная інфармацыя, таму дазваляйце доступ да ўсіх журналаў прылады толькі тым праграмам, якім вы давяраеце. \n\nКалі вы не дасцё гэтай праграме доступу да ўсіх журналаў прылад, у яе ўсё роўна застанецца доступ да ўласных журналаў. Для вытворцы вашай прылады будуць даступнымі некаторыя журналы і інфармацыя на вашай прыладзе."</string>
</resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 7253b49824a2..0f45de77f327 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"Винаги да се разрешава от този компютър"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"Разрешаване"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"Отстраняването на грешки през USB не е разрешено"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"Потребителят, който понастоящем е влязъл в това устройство, не може да включи функцията за отстраняване на грешки през USB. За да я използвате, превключете към основния потребител."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"Потребителят, който понастоящем е влязъл в това устройство, не може да включи функцията за отстраняване на грешки през USB. За да я използвате, превключете към потребител с администраторски достъп."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Искате ли да промените езика на системата на <xliff:g id="LANGUAGE">%1$s</xliff:g>?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Друго устройство е заявило промяна на езика на системата"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Промяна на езика"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"Винаги да се разрешава в тази мрежа"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"Разрешаване"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Безжичното отстраняване на грешки не е разрешено"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"Потребителят, който понастоящем е влязъл в това устройство, не може да включи функцията за безжично отстраняване на грешки. За да използвате, превключете към основния потребител."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"Потребителят, който понастоящем е влязъл в това устройство, не може да включи функцията за безжично отстраняване на грешки. За да я използвате, превключете към потребител с администраторски достъп."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"USB портът е деактивиран"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"С цел защита на устройството ви от течности и замърсяване USB портът е деактивиран и няма да открива аксесоари.\n\nЩе получите известие, когато можете отново да използвате USB порта."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"USB портът може да разпознава зарядни устройства и аксесоари"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Гласова помощ"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Портфейл"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"Скенер за QR кодове"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"Отключване"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"Устройството е заключено"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Извършва се сканиране на лице"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Изпращане"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"Лицето не е разпознато"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Използвайте отпечатък"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth е включен."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"Процентът на батерията е неизвестен."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"Самолетен режим."</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"Функцията за виртуална частна мрежа (VPN) е включена."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"<xliff:g id="NUMBER">%d</xliff:g> процента батерия."</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Батерията е на <xliff:g id="PERCENTAGE">%1$s</xliff:g> процента. Още около <xliff:g id="TIME">%2$s</xliff:g> въз основа на използването"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Батерията е на <xliff:g id="PERCENTAGE">%1$d</xliff:g> процента. Още около <xliff:g id="TIME">%2$s</xliff:g> въз основа на използването"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Батерията се зарежда, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"Вижте всички известия"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"TeleTypewriter бе активиран."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Вибрира при звънене."</string>
@@ -386,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Когато споделяте, записвате или предавате, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> има достъп до всичко, което се показва или възпроизвежда в това приложение, затова бъдете внимателни с пароли, подробности за начини на плащане, съобщения или друга поверителна информация."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Напред"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Споделяне или записване на приложение"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Да се разреши ли на това приложение да споделя или записва?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Когато споделяте, записвате или предавате, това приложение има достъп до всичко, което се вижда на екрана ви или се възпроизвежда на устройството ви, затова бъдете внимателни с пароли, подробности за начини на плащане, съобщения или друга поверителна информация."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Когато споделяте, записвате или предавате, това приложение има достъп до всичко, което се показва или възпроизвежда в него, затова бъдете внимателни с пароли, подробности за начини на плащане, съобщения или друга поверителна информация."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Блокирано от системния ви администратор"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"Заснемането на екрана е деактивирано от правило за устройството"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Изчистване на всички"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Управление"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"История"</string>
@@ -511,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Отключване с цел използване"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"При извличането на картите ви възникна проблем. Моля, опитайте отново по-късно"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Настройки за заключения екран"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"QR код: сканиране"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Потребителски профил в Work"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Самолетен режим"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Няма да чуете следващия си будилник в <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -794,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Увеличаване на целия екран"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Увеличаване на част от екрана"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Превключване"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Разрешаване на диагонално превъртане"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Преоразмеряване"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"Промяна на типа увеличение"</string>
@@ -1024,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"Да се разреши ли на <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> достъп до всички регистрационни файлове за устройството?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"Разрешаване на еднократен достъп"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Забраняване"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"В регистрационните файлове за устройството се записва какво се извършва на него. Приложенията могат да използват тези регистрационни файлове, за да откриват и отстраняват проблеми.\n\nНякои регистрационни файлове за устройството може да съдържат поверителна информация, затова разрешавайте достъп до всички тях само на приложения, на които имате доверие. \n\nАко не разрешите на това приложение достъп до всички регистрационни файлове за устройството, то пак може да осъществява достъп до собствените си регистрационни файлове. Възможно е производителят на устройството да продължи да има достъп до някои регистрационни файлове или информация на устройството ви."</string>
</resources>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index 915d0eb1a737..5ec402825682 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"এই কম্পিউটার থেকে সর্বদা অনুমতি দিন"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"অনুমতি দিন"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"USB ডিবাগিং অনুমোদিত নয়"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"ব্যবহারকারী এখন এই ডিভাইসে সাইন-ইন করেছেন তাই USB ডিবাগিং চালু করা যাবে না। এই বৈশিষ্ট্যটি ব্যবহার করতে, প্রাথমিক ব্যবহারকারীতে পাল্টে নিন।"</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"বর্তমানে এই ডিভাইসে সাইন-ইন করে থাকা ব্যবহারকারী \'USB ডিবাগিং\' চালু করতে পারবেন না। এই ফিচার ব্যবহার করতে, একজন অ্যাডমিন ব্যবহারকারী হিসেবে সাইন-ইন করুন।"</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"আপনি কি সিস্টেমের ভাষা পরিবর্তন করে <xliff:g id="LANGUAGE">%1$s</xliff:g> করতে চান?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"অন্য ডিভাইসের দ্বারা সিস্টেমের ভাষা পরিবর্তনের অনুরোধ করা হয়েছে"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"ভাষা পরিবর্তন করুন"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"এই নেটওয়ার্কে সবসময় অনুমতি দিন"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"অনুমতি দিন"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"ওয়্যারলেস ডিবাগিং করা যাবে না"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"ব্যবহারকারী এখন এই ডিভাইসে সাইন-ইন করেছেন তাই ওয়্যারলেস ডিবাগিং চালু করা যাবে না। এই ফিচারটি ব্যবহার করতে, প্রাথমিক ব্যবহারকারীতে পাল্টে নিন।"</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"বর্তমানে এই ডিভাইসে সাইন-ইন করে থাকা ব্যবহারকারী \'ওয়্যারলেস ডিবাগিং\' চালু করতে পারবেন না। এই ফিচার ব্যবহার করতে, একজন অ্যাডমিন ব্যবহারকারী হিসেবে সাইন-ইন করুন।"</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"ইউএসবি পোর্ট বন্ধ করা হয়েছে"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"কোনও তরল পদার্থ ও ধুলো থেকে আপনার ডিভাইসকে সুরক্ষিত রাখতে, ইউএসবি পোর্ট বন্ধ করা আছে, তাই কোনও অ্যাক্সেসরির শনাক্ত করা যাবে না।\n\nইউএসবি পোর্ট আবার ব্যবহার করা নিরাপদ হলে, আপনাকে জানানো হবে।"</string>
<string name="usb_port_enabled" msgid="531823867664717018">"চার্জার ও আনুষঙ্গিক আইটেম শনাক্ত করার জন্য ইউএসবি চালু করা হয়েছে"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"ভয়েস সহায়তা"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"QR কোড স্ক্যানার"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"আনলক করুন"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"ডিভাইস লক করা আছে"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"ফেস স্ক্যান করা হচ্ছে"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"পাঠান"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"ফেস শনাক্ত করা যায়নি"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"পরিবর্তে ফিঙ্গারপ্রিন্ট ব্যবহার করুন"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"ব্লুটুথ সংযুক্ত হয়েছে৷"</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"ব্যাটারি কত শতাংশ আছে তা জানা যায়নি।"</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"বিমান মোড৷"</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN চালু আছে।"</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"<xliff:g id="NUMBER">%d</xliff:g> শতাংশ ব্যাটারি রয়েছে৷"</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"ব্যাটারি <xliff:g id="PERCENTAGE">%1$s</xliff:g> শতাংশ, বর্তমান ব্যবহারের উপর ভিত্তি করে আর <xliff:g id="TIME">%2$s</xliff:g> চলবে"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"ব্যাটারি <xliff:g id="PERCENTAGE">%1$d</xliff:g> শতাংশ, বর্তমান ব্যবহারের উপর ভিত্তি করে আর <xliff:g id="TIME">%2$s</xliff:g> চলবে"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"ব্যাটারি চার্জ হচ্ছে, এখন <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> শতাংশ চার্জ আছে৷"</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"সমস্ত বিজ্ঞপ্তি দেখুন"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"টেলি টাইপরাইটার সক্ষম করা আছে৷"</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"রিং বাজার সাথে স্পন্দিত করুন৷"</string>
@@ -386,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"কোনও অ্যাপ আপনার শেয়ার করা, রেকর্ড করা বা কাস্ট করার সময়, সেই অ্যাপে দেখা যায় বা খেলা হয় এমন সব কিছু অ্যাক্সেস করার অনুমতি <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>-এর আছে। তাই পাসওয়ার্ড, পেমেন্টের বিবরণ, মেসেজ বা অন্য সংবেদনশীল তথ্য সম্পর্কে সতর্ক থাকুন।"</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"চালিয়ে যান"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"অ্যাপ শেয়ার বা রেকর্ড করা"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"এই অ্যাপকে শেয়ার বা রেকর্ড করার অনুমতি দেবেন?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"আপনি শেয়ার, রেকর্ড বা কাস্ট করার সময় স্ক্রিনে দৃশ্যমান বা ডিভাইসে চালানো হয়েছে এমন সব কিছুই এই অ্যাপ অ্যাক্সেস করতে পারবে। সেই জন্য পাসওয়ার্ড, পেমেন্টের বিবরণ, মেসেজ বা অন্য সংবেদনশীল তথ্য সম্পর্কে সতর্ক থাকুন।"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"কোনও অ্যাপের মাধ্যমে শেয়ার, রেকর্ড বা কাস্ট করার সময়, অ্যাপে দৃশ্যমান বা তাতে চালানো হয়েছে এমন সব কিছুই এই অ্যাপ অ্যাক্সেস করতে পারবে। সেই জন্য পাসওয়ার্ড, পেমেন্টের বিবরণ, মেসেজ বা অন্য সংবেদনশীল তথ্য সম্পর্কে সতর্ক থাকুন।"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"আপনার আইটি অ্যাডমিন ব্লক করেছেন"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"ডিভাইস নীতির কারণে স্ক্রিন ক্যাপচার করার প্রসেস বন্ধ করা আছে"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"সবকিছু সাফ করুন"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"পরিচালনা করুন"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"ইতিহাস"</string>
@@ -511,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"ব্যবহার করতে আনলক করুন"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"আপনার কার্ড সংক্রান্ত তথ্য পেতে সমস্যা হয়েছে, পরে আবার চেষ্টা করুন"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"লক স্ক্রিন সেটিংস"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"QR কোড স্ক্যান করুন"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"কাজের প্রোফাইল"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"বিমান মোড"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"আপনি আপনার পরবর্তী <xliff:g id="WHEN">%1$s</xliff:g> অ্যালার্ম শুনতে পাবেন না"</string>
@@ -794,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"সম্পূর্ণ স্ক্রিন বড় করে দেখা"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"স্ক্রিনের কিছুটা অংশ বড় করুন"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"বদল করুন"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"কোণাকুণি স্ক্রল করার অনুমতি দেওয়া"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"ছোট বড় করা"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"বড় করে দেখার ধরন পরিবর্তন করা"</string>
@@ -1024,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g>-কে ডিভাইসের সব লগ অ্যাক্সেসের অনুমতি দিতে চান?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"এককালীন অ্যাক্সেসের অনুমতি দিন"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"অনুমতি দেবেন না"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"ডিভাইস লগে আপনার ডিভাইসে করা অ্যাক্টিভিটি রেকর্ড করা হয়। অ্যাপ সমস্যা খুঁজে তা সমাধান করতে এইসব লগ ব্যবহার করতে পারে।\n\nকিছু লগে সংবেদনশীল তথ্য থাকতে পারে, তাই বিশ্বাস করেন শুধুমাত্র এমন অ্যাপকেই সব ডিভাইসের লগ অ্যাক্সেসের অনুমতি দিন। \n\nআপনি এই অ্যাপকে ডিভাইসের সব লগ অ্যাক্সেস করার অনুমতি না দিলেও, এটি নিজে লগ অ্যাক্সেস করতে পারবে। ডিভাইস প্রস্তুতকারকও আপনার ডিভাইসের কিছু লগ বা তথ্য হয়ত অ্যাক্সেস করতে পারবে।"</string>
</resources>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index bdb8638715a7..5017716054f8 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -52,7 +52,7 @@
<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 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="usb_debugging_secondary_user_message" msgid="1888835696965417845">"Korisnik koji je trenutno prijavljen na uređaju ne može uključiti opciju za otklanjanje grešaka putem USB-a. Da koristite ovu funkciju, prebacite se na administratora."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Želite li promijeniti jezik sistema u <xliff:g id="LANGUAGE">%1$s</xliff:g>?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Promjenu jezika sistema je zatražio drugi uređaj"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Promijeni jezik"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"Uvijek dozvoli na ovoj mreži"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"Dozvoli"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Bežično otklanjanje grešaka nije dozvoljeno"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"Korisnik koji je trenutno prijavljen na ovaj uređaj ne može uključiti bežično otklanjanje grešaka. Da koristite tu funkciju, prebacite se na primarnog korisnika."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"Korisnik koji je trenutno prijavljen na uređaju ne može uključiti bežično otklanjanje grešaka. Da koristite ovu funkciju prebacite se na administratora."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"USB priključak je onemogućen"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"USB priključak je onemogućen kako bi se vaš uređaj zaštitio od tečnosti i nečistoća i neće detektirati priključene uređaje.\n\nDobit ćete obavještenje kada ponovo bude sigurno koristiti USB priključak."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"USB priključak je omogućen za prepoznavanje punjača i pribora"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Glasovna pomoć"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Novčanik"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"Skener QR koda"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"Otključaj"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"Uređaj je zaključan"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Skeniranje lica"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Pošalji"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"Nije moguće prepoznati lice"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Koristite otisak prsta"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth je povezan."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"Postotak napunjenosti baterije nije poznat"</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"Način rada u avionu."</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN uključen."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"Baterija na <xliff:g id="NUMBER">%d</xliff:g> posto."</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Baterija je na <xliff:g id="PERCENTAGE">%1$s</xliff:g> posto. Na osnovu vaše potrošnje preostalo vam je otprilike <xliff:g id="TIME">%2$s</xliff:g>"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Baterija je na <xliff:g id="PERCENTAGE">%1$d</xliff:g> posto. Na osnovu vaše potrošnje preostalo vam je otprilike <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Punjenje baterije, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"Vidite sva obavještenja"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"Omogućena opcija TeleTypewriter."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Zvuk zvona na vibraciji."</string>
@@ -386,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Kada aplikaciju dijelite, snimate ili emitirate, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ima pristup svemu što se prikazuje ili reproducira u toj aplikaciji. Zato budite oprezni s lozinkama, detaljima o plaćanju, porukama i drugim osjetljivim informacijama."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Nastavi"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Dijelite ili snimite aplikaciju"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Dozvoliti aplikaciji da dijeli ili snima?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Kada dijelite, snimate ili emitirate, aplikacija ima pristup svemu što je vidljivo na ekranu ili što se reproducira na uređaju. Zato budite oprezni s lozinkama, detaljima o plaćanju, porukama i drugim osjetljivim informacijama."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Kada dijelite, snimate ili emitirate aplikaciju, ona ima pristup svemu što se prikazuje ili reproducira u toj aplikaciji. Zato budite oprezni s lozinkama, detaljima o plaćanju, porukama i drugim osjetljivim informacijama."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Blokirao je vaš IT administrator"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"Snimanje ekrana je onemogućeno pravilima uređaja"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Očisti sve"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Upravljajte"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Historija"</string>
@@ -511,7 +511,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Otključajte da koristite"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Došlo je do problema prilikom preuzimanja vaših kartica. Pokušajte ponovo kasnije"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Postavke zaključavanja ekrana"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"Skenirajte QR kôd"</string>
+ <string name="qr_code_scanner_title" msgid="1938155688725760702">"Čitač QR koda"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Profil za posao"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Način rada u avionu"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Nećete čuti sljedeći alarm u <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -794,6 +794,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Uvećavanje prikaza preko cijelog ekrana"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Uvećavanje dijela ekrana"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Prekidač"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Dozvoli dijagonalno klizanje"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Promijeni veličinu"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"Promijeni vrstu uvećavanja"</string>
@@ -1024,4 +1026,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"DDD, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"Dozvoliti aplikaciji <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> da pristupa svim zapisnicima uređaja?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"Dozvoli jednokratan pristup"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Nemoj dozvoliti"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"Zapisnici uređaja bilježe šta se dešava na uređaju. Aplikacije mogu koristiti te zapisnike da pronađu i isprave probleme.\n\nNeki zapisnici mogu sadržavati osjetljive podatke, zato pristup svim zapisnicima uređaja dozvolite samo aplikacijama kojima vjerujete. \n\nAko ne dozvolite ovoj aplikaciji da pristupa svim zapisnicima uređaja, ona i dalje može pristupati svojim zapisnicima. Proizvođač uređaja će možda i dalje biti u stanju pristupiti nekim zapisnicima ili podacima na uređaju."</string>
</resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 484de00b29de..e270685cbac0 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"Dona sempre permís des d\'aquest equip"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"Permet"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"No es permet la depuració per USB"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"L\'usuari que té iniciada la sessió al dispositiu en aquest moment no pot activar la depuració per USB. Per utilitzar aquesta funció, cal canviar a l\'usuari principal."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"L\'usuari que té iniciada la sessió al dispositiu en aquest moment no pot activar la depuració per USB. Per utilitzar aquesta funció, cal canviar a l\'usuari principal."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Vols canviar l\'idioma del sistema a <xliff:g id="LANGUAGE">%1$s</xliff:g>?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Un altre dispositiu ha sol·licitat canviar l\'idioma del sistema"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Canvia l\'idioma"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"Permet sempre en aquesta xarxa"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"Permet"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"No es permet la depuració sense fil"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"L\'usuari que té iniciada la sessió al dispositiu en aquest moment no pot activar la depuració sense fil. Per utilitzar aquesta funció, cal canviar a l\'usuari principal."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"L\'usuari que té iniciada la sessió al dispositiu en aquest moment no pot activar la depuració sense fil. Per utilitzar aquesta funció, cal canviar a l\'usuari principal."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"El port USB està desactivat"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"Per protegir el teu dispositiu dels líquids o de la pols, el port USB s\'ha desactivat i no detectarà cap accessori.\n\nRebràs una notificació quan puguis tornar a utilitzar-lo."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"S\'ha activat el port USB per detectar carregadors i accessoris"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Assistència per veu"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"Escàner de codis QR"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"Desbloqueja"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"Dispositiu bloquejat"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"S\'està escanejant la cara"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Envia"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"No es reconeix la cara"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Utilitza l\'empremta digital"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth connectat."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"Es desconeix el percentatge de bateria."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"Mode d\'avió."</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN activada"</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"<xliff:g id="NUMBER">%d</xliff:g> per cent de bateria."</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> per cent de bateria amb aproximadament <xliff:g id="TIME">%2$s</xliff:g> de temps restant segons l\'ús que en fas"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> per cent de bateria amb aproximadament <xliff:g id="TIME">%2$s</xliff:g> de temps restant segons l\'ús que en fas"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"La bateria s\'està carregant (<xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%)."</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"Mostra totes les notificacions"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"Teletip activat."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Mode vibració."</string>
@@ -305,28 +310,17 @@
<string name="sensor_privacy_mic_unblocked_toast_content" msgid="306555320557065068">"Micròfon disponible"</string>
<string name="sensor_privacy_camera_unblocked_toast_content" msgid="7843105715964332311">"Càmera disponible"</string>
<string name="sensor_privacy_mic_camera_unblocked_toast_content" msgid="7339355093282661115">"Càmera i micròfon disponibles"</string>
- <!-- no translation found for sensor_privacy_mic_turned_on_dialog_title (6348853159838376513) -->
- <skip />
- <!-- no translation found for sensor_privacy_mic_turned_off_dialog_title (5760464281790732849) -->
- <skip />
- <!-- no translation found for sensor_privacy_mic_unblocked_dialog_content (4889961886199270224) -->
- <skip />
- <!-- no translation found for sensor_privacy_mic_blocked_no_exception_dialog_content (5864898470772965394) -->
- <skip />
- <!-- no translation found for sensor_privacy_mic_blocked_with_exception_dialog_content (810289713700437896) -->
- <skip />
- <!-- no translation found for sensor_privacy_camera_turned_on_dialog_title (8039095295100075952) -->
- <skip />
- <!-- no translation found for sensor_privacy_camera_turned_off_dialog_title (1936603903120742696) -->
- <skip />
- <!-- no translation found for sensor_privacy_camera_unblocked_dialog_content (7847190103011782278) -->
- <skip />
- <!-- no translation found for sensor_privacy_camera_blocked_dialog_content (3182428709314874616) -->
- <skip />
- <!-- no translation found for sensor_privacy_htt_blocked_dialog_content (3333321592997666441) -->
- <skip />
- <!-- no translation found for sensor_privacy_dialog_open_settings (1503088305279285048) -->
- <skip />
+ <string name="sensor_privacy_mic_turned_on_dialog_title" msgid="6348853159838376513">"El micròfon s\'ha activat"</string>
+ <string name="sensor_privacy_mic_turned_off_dialog_title" msgid="5760464281790732849">"El micròfon s\'ha desactivat"</string>
+ <string name="sensor_privacy_mic_unblocked_dialog_content" msgid="4889961886199270224">"El micròfon està activat per a totes les aplicacions i serveis."</string>
+ <string name="sensor_privacy_mic_blocked_no_exception_dialog_content" msgid="5864898470772965394">"L\'accés al micròfon està desactivat per a totes les aplicacions i serveis. Pots activar l\'accés al micròfon a Configuració &gt; Privadesa &gt; Micròfon."</string>
+ <string name="sensor_privacy_mic_blocked_with_exception_dialog_content" msgid="810289713700437896">"L\'accés al micròfon està desactivat per a totes les aplicacions i serveis. Pots canviar-ho a Configuració &gt; Privadesa &gt; Micròfon."</string>
+ <string name="sensor_privacy_camera_turned_on_dialog_title" msgid="8039095295100075952">"La càmera s\'ha activat"</string>
+ <string name="sensor_privacy_camera_turned_off_dialog_title" msgid="1936603903120742696">"La càmera s\'ha desactivat"</string>
+ <string name="sensor_privacy_camera_unblocked_dialog_content" msgid="7847190103011782278">"La càmera està activada per a totes les aplicacions i serveis."</string>
+ <string name="sensor_privacy_camera_blocked_dialog_content" msgid="3182428709314874616">"L\'accés a la càmera està desactivat per a totes les aplicacions i serveis."</string>
+ <string name="sensor_privacy_htt_blocked_dialog_content" msgid="3333321592997666441">"Per utilitzar el botó de micròfon, activa l\'accés al micròfon a Configuració."</string>
+ <string name="sensor_privacy_dialog_open_settings" msgid="1503088305279285048">"Obre la configuració."</string>
<string name="media_seamless_other_device" msgid="4654849800789196737">"Un altre dispositiu"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Activa o desactiva Aplicacions recents"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"No t\'interromprà cap so ni cap vibració, tret dels de les alarmes, recordatoris, esdeveniments i trucades de les persones que especifiquis. Continuaràs sentint tot allò que decideixis reproduir, com ara música, vídeos i jocs."</string>
@@ -397,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Quan estàs compartint, gravant o emetent, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> té accés a qualsevol cosa que es vegi a la pantalla o que es reprodueixi a l\'aplicació. Per aquest motiu, ves amb compte amb les contrasenyes, les dades de pagament, els missatges o altra informació sensible."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Continua"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Comparteix o grava una aplicació"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Vols permetre que aquesta aplicació comparteixi o gravi contingut?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Quan estàs compartint, gravant o emetent, aquesta aplicació té accés a qualsevol cosa que es vegi a la pantalla o que es reprodueixi al dispositiu. Per aquest motiu, ves amb compte amb les contrasenyes, les dades de pagament, els missatges o altra informació sensible."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Quan estàs compartint, gravant o emetent, aquesta aplicació té accés a qualsevol cosa que es vegi a la pantalla o que es reprodueixi a l\'aplicació. Per aquest motiu, ves amb compte amb les contrasenyes, les dades de pagament, els missatges o altra informació sensible."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Bloquejat per l\'administrador de TI"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"Les captures de pantalla estan desactivades per la política de dispositius"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Esborra-ho tot"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Gestiona"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Historial"</string>
@@ -452,8 +441,8 @@
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"L\'administrador ha activat el registre de xarxa, que supervisa el trànsit del teu dispositiu."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"L\'administrador ha activat el registre de xarxa, que monitora el trànsit al teu perfil de treball, però no al personal."</string>
<string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Aquest dispositiu es connecta a Internet a través de <xliff:g id="VPN_APP">%1$s</xliff:g>. El teu administrador de TI pot veure l\'activitat de la teva xarxa, inclosos els correus electrònics i les dades de navegació."</string>
- <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Aquest dispositiu es connecta a Internet a través de <xliff:g id="VPN_APP_0">%1$s</xliff:g> i <xliff:g id="VPN_APP_1">%2$s</xliff:g>. El teu administrador de TI pot veure la teva activitat a la xarxa, inclosos els correus electrònics i les dades de navegació."</string>
- <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Les aplicacions de treball es connecten a Internet a través de <xliff:g id="VPN_APP">%1$s</xliff:g>. El teu administrador de TI i el teu proveïdor de VPN poden veure la teva activitat a la xarxa en aplicacions de treball, inclosos els correus electrònics i les dades de navegació."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Aquest dispositiu es connecta a Internet a través de <xliff:g id="VPN_APP_0">%1$s</xliff:g> i <xliff:g id="VPN_APP_1">%2$s</xliff:g>. El teu administrador de TI pot veure la teva activitat de xarxa, inclosos els correus electrònics i les dades de navegació."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Les aplicacions de treball es connecten a Internet a través de <xliff:g id="VPN_APP">%1$s</xliff:g>. El teu administrador de TI i el teu proveïdor de VPN poden veure la teva activitat de xarxa en aplicacions de treball, inclosos els correus electrònics i les dades de navegació."</string>
<string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Les aplicacions personals es connecten a Internet a través de <xliff:g id="VPN_APP">%1$s</xliff:g>. El teu proveïdor de VPN pot veure l\'activitat de la teva xarxa, inclosos els correus electrònics i les dades de navegació."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Obre la configuració de la VPN"</string>
@@ -522,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Desbloqueja per utilitzar"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Hi ha hagut un problema en obtenir les teves targetes; torna-ho a provar més tard"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Configuració de la pantalla de bloqueig"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"Escaneja un codi QR"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Perfil de treball"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Mode d\'avió"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"<xliff:g id="WHEN">%1$s</xliff:g> no sentiràs la pròxima alarma"</string>
@@ -805,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Amplia la pantalla completa"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Amplia una part de la pantalla"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Canvia"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Permet el desplaçament en diagonal"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Canvia la mida"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"Canvia el tipus d\'ampliació"</string>
@@ -1035,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"hh:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"Vols permetre que <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> accedeixi a tots els registres del dispositiu?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"Permet l\'accés únic"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"No permetis"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"Els registres del dispositiu inclouen informació sobre tot allò que passa al teu dispositiu. Les aplicacions poden utilitzar aquests registres per detectar i corregir problemes.\n\nÉs possible que alguns registres continguin informació sensible; per això només has de donar-hi accés a les aplicacions de confiança. \n\nEncara que no permetis que aquesta aplicació pugui accedir a tots els registres del dispositiu, podrà accedir als seus propis registres. És possible que el fabricant del dispositiu també tingui accés a alguns registres o a informació del teu dispositiu."</string>
</resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 71bea8041c9a..02086eada891 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"Vždy povolit z tohoto počítače"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"Povolit"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"Ladění přes USB není povoleno"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"Uživatel aktuálně přihlášený k tomuto zařízení nemůže zapnout ladění přes USB. Chcete-li tuto funkci použít, přepněte na primárního uživatele."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"Uživatel aktuálně přihlášený k tomuto zařízení nemůže zapnout ladění přes USB. Chcete-li tuto funkci používat, přepněte na administrativního uživatele."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Změnit systémový jazyk na <xliff:g id="LANGUAGE">%1$s</xliff:g>?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Jiné zařízení požádalo o změnu systémového jazyka"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Změnit jazyk"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"V této síti vždy povolit"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"Povolit"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Bezdrátové ladění není povoleno"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"Uživatel aktuálně přihlášený k tomuto zařízení nemůže zapnout bezdrátové ladění. Chcete-li tuto funkci použít, přepněte na primárního uživatele."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"Uživatel aktuálně přihlášený k tomuto zařízení nemůže zapnout bezdrátové ladění. Chcete-li tuto funkci používat, přepněte na administrativního uživatele."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"Port USB je deaktivován"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"Kvůli ochraně vašeho zařízení před tekutinami a nečistotami je port USB zakázán a nerozpozná žádné příslušenství.\n\nAž bude opět bezpečné port USB použít, budeme vás informovat."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"Port USB může zjišťovat nabíječky a příslušenství"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Hlasová asistence"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Peněženka"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"Čtečka QR kódů"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"Odemknout"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"Zařízení uzamčeno"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Skenování obličeje"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Odeslat"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"Obličej nelze rozpoznat"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Použijte otisk prstu"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Rozhraní Bluetooth je připojeno."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"Procento baterie není známé."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"Režim Letadlo."</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN je zapnuto."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"Stav baterie: <xliff:g id="NUMBER">%d</xliff:g> procent."</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Baterie je nabitá na <xliff:g id="PERCENTAGE">%1$s</xliff:g> procent, při vašem používání vydrží ještě <xliff:g id="TIME">%2$s</xliff:g>"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Baterie je nabitá na <xliff:g id="PERCENTAGE">%1$d</xliff:g> procent, při vašem používání vydrží ještě <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Baterie se nabíjí. Nabito: <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> %%"</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"Zobrazit všechna oznámení"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"Rozhraní TeleTypewriter zapnuto."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Vibrační vyzvánění."</string>
@@ -386,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Když sdílíte, nahráváte nebo odesíláte aplikaci, aplikace <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> má přístup k veškerému obsahu, který je v této aplikaci zobrazen nebo přehráván. Dejte proto pozor na hesla, platební údaje, zprávy nebo jiné citlivé informace."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Pokračovat"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Sdílení nebo nahrání aplikace"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Povolit této aplikaci sdílet nebo nahrávat?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Když sdílíte, nahráváte nebo odesíláte obsah, aplikace má přístup ke všemu, co je viditelné na obrazovce nebo se přehrává v zařízení. Dejte proto pozor na hesla, platební údaje, zprávy nebo jiné citlivé informace."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Když sdílíte, nahráváte nebo odesíláte aplikaci, aplikace má přístup ke všemu, co je v této aplikaci zobrazeno nebo se přehrává. Dejte proto pozor na hesla, platební údaje, zprávy nebo jiné citlivé informace."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Blokováno administrátorem IT"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"Záznam obrazovky je zakázán zásadami zařízení"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Smazat vše"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Spravovat"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Historie"</string>
@@ -511,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Odemknout a použít"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Při načítání karet došlo k problému, zkuste to později"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Nastavení obrazovky uzamčení"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"Naskenovat QR kód"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Pracovní profil"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Režim Letadlo"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Svůj další budík <xliff:g id="WHEN">%1$s</xliff:g> neuslyšíte"</string>
@@ -794,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Zvětšit celou obrazovku"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Zvětšit část obrazovky"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Přepnout"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Povolit diagonální posouvání"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Změnit velikost"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"Změnit typ zvětšení"</string>
@@ -1024,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE d. MMMM"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"H:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"Povolit aplikaci <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> přístup ke všem protokolům zařízení?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"Povolit jednorázový přístup"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Nepovolovat"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"Do protokolů zařízení se zaznamenává, co se na zařízení děje. Aplikace tyto protokoly mohou používat k vyhledání a odstranění problémů.\n\nNěkteré protokoly mohou zahrnovat citlivé údaje. Přístup k protokolům zařízení proto povolte pouze aplikacím, kterým důvěřujete. \n\nPokud této aplikaci nepovolíte přístup ke všem protokolům zařízení, bude mít stále přístup ke svým vlastním protokolům. Výrobce zařízení může mít stále přístup k některým protokolům nebo informacím na vašem zařízení."</string>
</resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 0eb3d952067a..1140d3d0e229 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"Tillad altid fra denne computer"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"Tillad"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"USB-fejlretning er ikke tilladt"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"Den bruger, der i øjeblikket er logget ind på denne enhed, kan ikke aktivere USB-fejlretning. Skift til den primære bruger for at bruge denne funktion."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"Den bruger, der i øjeblikket er logget ind på denne enhed, kan ikke aktivere USB-fejlretning. Skift til en administrator for at bruge denne funktion."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Vil du ændre systemsproget til <xliff:g id="LANGUAGE">%1$s</xliff:g>?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"En anden enhed har anmodet om en ændring af systemsproget"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Skift sprog"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"Tillad altid på dette netværk"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"Tillad"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Trådløs fejlretning er ikke tilladt"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"Den bruger, der i øjeblikket er logget ind på denne enhed, kan ikke aktivere trådløs fejlretning. Skift til den primære bruger for at bruge denne funktion."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"Den bruger, der i øjeblikket er logget ind på denne enhed, kan ikke aktivere trådløs fejlretning. Skift til en administrator for at bruge denne funktion."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"USB-porten er deaktiveret"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"USB-porten er blevet deaktiveret for at beskytte din enhed mod væske og snavs. Den kan derfor ikke registrere noget tilbehør.\n\nDu får besked, når du kan bruge USB-porten igen."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"USB-porten er aktiveret for at registrere opladere og tilbehør"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Taleassistent"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"QR-kodescanner"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"Lås op"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"Enheden er låst"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Scanner ansigt"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Send"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"Ansigt kan ikke genkendes"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Brug fingeraftryk i stedet"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth tilsluttet."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"Batteriniveauet er ukendt."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"Flytilstand."</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN er slået til."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"Batteri <xliff:g id="NUMBER">%d</xliff:g> procent."</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Batteriniveauet er på <xliff:g id="PERCENTAGE">%1$s</xliff:g> procent, så du har ca. <xliff:g id="TIME">%2$s</xliff:g> tilbage, alt efter hvordan du bruger enheden"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Batteriniveauet er på <xliff:g id="PERCENTAGE">%1$d</xliff:g> procent, så du har ca. <xliff:g id="TIME">%2$s</xliff:g> tilbage, alt efter hvordan du bruger enheden"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Batteriet oplades. <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> %%."</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"Se alle notifikationer"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"TeleTypewriter aktiveret."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Ringervibration."</string>
@@ -386,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Når du deler, optager eller caster en app, har <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> adgang til alt, der vises eller afspilles i den pågældende app. Vær derfor forsigtig med adgangskoder, betalingsoplysninger, beskeder og andre følsomme oplysninger."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Fortsæt"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Del eller optag en app"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Vil du tillade, at denne app deler eller optager?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Når du deler, optager eller caster, har denne app adgang til alt, der vises på din skærm eller afspilles på din enhed. Vær derfor forsigtig med adgangskoder, betalingsoplysninger, beskeder og andre følsomme oplysninger."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Når du deler, optager eller caster en app, har denne app adgang til alt, der vises eller afspilles i den pågældende app. Vær derfor forsigtig med adgangskoder, betalingsoplysninger, beskeder og andre følsomme oplysninger."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Blokeret af din it-administrator"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"Screenshots er deaktiveret af enhedspolitikken"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Ryd alle"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Administrer"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Historik"</string>
@@ -511,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Lås op for at bruge"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Dine kort kunne ikke hentes. Prøv igen senere."</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Lås skærmindstillinger"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"Scan QR-kode"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Arbejdsprofil"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Flytilstand"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Du vil ikke kunne høre din næste alarm <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -794,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Forstør hele skærmen"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Forstør en del af skærmen"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Skift"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Tillad diagonal rulning"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Juster"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"Skift forstørrelsestype"</string>
@@ -1024,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE d. MMM"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"tt.mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk.mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"Vil du give <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> adgang til alle enhedslogs?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"Tillad engangsadgang"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Tillad ikke"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"Enhedslogs registrerer, hvad der sker på din enhed. Apps kan bruge disse logs til at finde og løse problemer.\n\nNogle logs kan indeholde følsomme oplysninger, så giv kun apps, du har tillid til, adgang til alle enhedslogs. \n\nSelvom du ikke giver denne app adgang til alle enhedslogs, kan den stadig tilgå sine egne logs. Producenten af din enhed kan muligvis fortsat tilgå visse logs eller oplysninger på din enhed."</string>
</resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 2829950e246e..5f60e64ae50b 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"Von diesem Computer immer zulassen"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"Erlauben"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"USB-Debugging nicht zulässig"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"Der momentan auf diesem Gerät angemeldete Nutzer kann das USB-Debugging nicht aktivieren. Um diese Funktion verwenden zu können, wechsle zum primären Nutzer."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"Der momentan auf diesem Gerät angemeldete Nutzer kann das USB-Debugging nicht aktivieren. Um diese Funktion zu verwenden, muss sich ein Administrator anmelden."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Möchtest du die Systemsprache in <xliff:g id="LANGUAGE">%1$s</xliff:g> ändern?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Von einem anderen Gerät wurde eine Änderung der Systemsprache angefordert"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Sprache ändern"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"Immer in diesem Netzwerk zulassen"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"Zulassen"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"\"Debugging über WLAN\" nicht zulässig"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"Der momentan auf diesem Gerät angemeldete Nutzer kann \"Debugging über WLAN\" nicht aktivieren. Um diese Funktion verwenden zu können, wechsle zum Hauptnutzer."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"Der momentan auf diesem Gerät angemeldete Nutzer kann das Debugging über WLAN nicht aktivieren. Um diese Funktion zu verwenden, muss sich ein Administrator anmelden."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"USB-Port deaktiviert"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"Zum Schutz deines Geräts vor Flüssigkeiten oder Fremdkörpern ist der USB-Port zurzeit deaktiviert und erkennt kein Zubehör.\n\nDu wirst benachrichtigt, wenn der USB-Port wieder verwendet werden kann."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"Erkennung von Ladegeräten und Zubehör am USB-Port aktiviert"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Sprachassistent"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"QR-Code-Scanner"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"Entsperren"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"Gerät gesperrt"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Gesicht wird gescannt"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Senden"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"Gesicht nicht erkannt"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Fingerabdruck verwenden"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Mit Bluetooth verbunden"</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"Akkustand unbekannt."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"Flugmodus"</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN an."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"Akku bei <xliff:g id="NUMBER">%d</xliff:g> Prozent."</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Akku bei <xliff:g id="PERCENTAGE">%1$s</xliff:g> Prozent. Bei deinem Nutzungsmuster hast du noch Strom für etwa <xliff:g id="TIME">%2$s</xliff:g>"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Akku bei <xliff:g id="PERCENTAGE">%1$d</xliff:g> Prozent. Bei deinem Nutzungsmuster hast du noch Strom für etwa <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Akku wird aufgeladen, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> Prozent."</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"Alle Benachrichtigungen ansehen"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"Schreibtelefonie aktiviert"</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Klingeltonmodus \"Vibration\""</string>
@@ -386,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Beim Teilen, Aufnehmen oder Übertragen einer App hat <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> Zugriff auf alle Inhalte, die in dieser App sichtbar sind oder wiedergegeben werden. Sei daher mit Passwörtern, Zahlungsdetails, Nachrichten oder anderen vertraulichen Informationen vorsichtig."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Weiter"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"App teilen oder aufnehmen"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Dieser App das Teilen oder Aufnehmen erlauben?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Beim Teilen, Aufnehmen oder Übertragen hat diese App Zugriff auf alle Inhalte, die auf dem Bildschirm sichtbar sind oder auf dem Gerät wiedergegeben werden. Sei daher mit Passwörtern, Zahlungsdetails, Nachrichten oder anderen vertraulichen Informationen vorsichtig."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Beim Teilen, Aufnehmen oder Übertragen einer App hat diese App Zugriff auf alle Inhalte, die in dieser App sichtbar sind oder wiedergegeben werden. Sei daher mit Passwörtern, Zahlungsdetails, Nachrichten oder anderen vertraulichen Informationen vorsichtig."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Vom IT-Administrator blockiert"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"Bildschirmaufnahme ist durch die Geräterichtlinien deaktiviert"</string>
<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>
@@ -511,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Zum Verwenden entsperren"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Beim Abrufen deiner Karten ist ein Fehler aufgetreten – bitte versuch es später noch einmal"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Einstellungen für den Sperrbildschirm"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"QR-Code scannen"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Arbeitsprofil"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Flugmodus"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Lautloser Weckruf <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -794,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Ganzen Bildschirm vergrößern"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Teil des Bildschirms vergrößern"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Schalter"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Diagonales Scrollen erlauben"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Größe ändern"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"Art der Vergrößerung ändern"</string>
@@ -1024,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d. MMM"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> den Zugriff auf alle Geräteprotokolle erlauben?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"Einmaligen Zugriff erlauben"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Nicht erlauben"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"In Geräteprotokollen wird aufgezeichnet, welche Aktionen auf deinem Gerät ausgeführt werden. Apps können diese Protokolle verwenden, um Probleme zu finden und zu beheben.\n\nEinige Protokolle enthalten unter Umständen vertrauliche Informationen. Daher solltest du nur vertrauenswürdigen Apps den Zugriff auf alle Geräteprotokolle erlauben. \n\nWenn du dieser App keinen Zugriff auf alle Geräteprotokolle gewährst, kann sie trotzdem auf ihre eigenen Protokolle zugreifen. Dein Gerätehersteller hat möglicherweise auch Zugriff auf einige Protokolle oder Informationen auf deinem Gerät."</string>
</resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 51af1f3f1e4b..f2341d681118 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"Να επιτρέπεται πάντα από αυτόν τον υπολογιστή"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"Να επιτρέπεται"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"Δεν επιτρέπεται ο εντοπισμός σφαλμάτων USB"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"Ο χρήστης που είναι συνδεδεμένος αυτήν τη στιγμή σε αυτήν τη συσκευή δεν μπορεί να ενεργοποιήσει τον εντοπισμό σφαλμάτων USB. Για να χρησιμοποιήσετε αυτήν τη λειτουργία, κάντε εναλλαγή στον κύριο χρήστη."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"Ο χρήστης που είναι συνδεδεμένος αυτήν τη στιγμή σε αυτήν τη συσκευή δεν μπορεί να ενεργοποιήσει τον εντοπισμό σφαλμάτων USB. Για να χρησιμοποιήσετε αυτήν τη λειτουργία, κάντε εναλλαγή σε έναν χρήστη με δικαιώματα διαχειριστή."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Θέλετε να αλλάξετε τη γλώσσα συστήματος σε <xliff:g id="LANGUAGE">%1$s</xliff:g>;"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Ζητήθηκε αλλαγή της γλώσσας συστήματος από άλλη συσκευή"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Αλλαγή γλώσσας"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"Να επιτρέπεται πάντα σε αυτό το δίκτυο"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"Να επιτρέπεται"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Ο ασύρματος εντοπισμός σφαλμάτων δεν επιτρέπεται"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"Ο χρήστης που είναι συνδεδεμένος αυτήν τη στιγμή στη συγκεκριμένη συσκευή δεν μπορεί να ενεργοποιήσει τον ασύρματο εντοπισμό σφαλμάτων. Για να χρησιμοποιήσετε αυτήν τη λειτουργία, κάντε εναλλαγή στον κύριο χρήστη."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"Ο χρήστης που είναι συνδεδεμένος αυτήν τη στιγμή στη συγκεκριμένη συσκευή δεν μπορεί να ενεργοποιήσει τον ασύρματο εντοπισμό σφαλμάτων. Για να χρησιμοποιήσετε αυτήν τη λειτουργία, κάντε εναλλαγή σε έναν χρήστη με δικαιώματα διαχειριστή."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"Η θύρα USB απενεργοποιήθηκε"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"Για την προστασία της συσκευής σας από υγρασία ή ακαθαρσίες, η θύρα USB έχει απενεργοποιηθεί και δεν θα εντοπίζει τυχόν αξεσουάρ.\n\nΘα ειδοποιηθείτε όταν θα μπορείτε να χρησιμοποιήσετε ξανά τη θύρα USB."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"Η θύρα USB ενεργοποιήθηκε για τον εντοπισμό φορτιστών και αξεσουάρ"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Φωνητική υποβοήθηση"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Πορτοφόλι"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"Σάρωση κωδικών QR"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"Ξεκλείδωμα"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"Η συσκευή κλειδώθηκε"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Σάρωση προσώπου"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Αποστολή"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"Αδύνατη η αναγν. προσώπου"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Χρησιμ. δακτυλ. αποτύπ."</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Το Bluetooth είναι συνδεδεμένο."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"Άγνωστο ποσοστό μπαταρίας."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"Λειτουργία πτήσης."</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN ενεργό."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"Μπαταρία <xliff:g id="NUMBER">%d</xliff:g> τοις εκατό."</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Μπαταρία στο <xliff:g id="PERCENTAGE">%1$s</xliff:g> τοις εκατό. Περίπου <xliff:g id="TIME">%2$s</xliff:g> ακόμη, βάσει της χρήσης σας"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Μπαταρία στο <xliff:g id="PERCENTAGE">%1$d</xliff:g> τοις εκατό. Περίπου <xliff:g id="TIME">%2$s</xliff:g> ακόμη, βάσει της χρήσης σας"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Φόρτιση μπαταρίας: <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"Δείτε όλες τις ειδοποιήσεις"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"Το TeleTypewriter ενεργοποιήθηκε."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Δόνηση ειδοποίησης ήχου."</string>
@@ -386,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Όταν κάνετε κοινοποίηση, εγγραφή ή μετάδοση μιας εφαρμογής, η εφαρμογή <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> έχει πρόσβαση σε οτιδήποτε είναι ορατό ή αναπαράγεται στη συγκεκριμένη εφαρμογή. Επομένως, να είστε προσεκτικοί με τους κωδικούς πρόσβασης, τα στοιχεία πληρωμής, τα μηνύματα ή άλλες ευαίσθητες πληροφορίες."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Συνέχεια"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Κοινοποίηση ή εγγραφή εφαρμογής"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Να επιτρέπεται σε αυτήν την εφαρμογή η κοινή χρήση ή εγγραφή;"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Όταν κάνετε κοινοποίηση, εγγραφή ή μετάδοση, αυτή η εφαρμογή έχει πρόσβαση σε οτιδήποτε είναι ορατό στην οθόνη σας ή αναπαράγεται στη συσκευή σας. Επομένως, να είστε προσεκτικοί με τους κωδικούς πρόσβασης, τα στοιχεία πληρωμής, τα μηνύματα ή άλλες ευαίσθητες πληροφορίες."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Όταν κάνετε κοινοποίηση, εγγραφή ή μετάδοση μιας εφαρμογής, αυτή η εφαρμογή έχει πρόσβαση σε οτιδήποτε είναι ορατό ή αναπαράγεται στη συγκεκριμένη εφαρμογή. Επομένως, να είστε προσεκτικοί με τους κωδικούς πρόσβασης, τα στοιχεία πληρωμής, τα μηνύματα ή άλλες ευαίσθητες πληροφορίες."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Αποκλείστηκε από τον διαχειριστή IT"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"Η καταγραφή οθόνης έχει απενεργοποιηθεί από την πολιτική χρήσης συσκευής."</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Διαγραφή όλων"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Διαχείριση"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Ιστορικό"</string>
@@ -511,7 +511,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Ξεκλείδωμα για χρήση"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Παρουσιάστηκε πρόβλημα με τη λήψη των καρτών σας. Δοκιμάστε ξανά αργότερα"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Ρυθμίσεις κλειδώματος οθόνης"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"Σάρωση κωδικού QR"</string>
+ <string name="qr_code_scanner_title" msgid="1938155688725760702">"Σάρωση κωδικών QR"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Προφίλ εργασίας"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Λειτουργία πτήσης"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Δεν θα ακούσετε το επόμενο ξυπνητήρι σας <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -794,6 +794,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Μεγέθυνση πλήρους οθόνης"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Μεγέθυνση μέρους της οθόνης"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Εναλλαγή"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Να επιτρέπεται η διαγώνια κύλιση"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Αλλαγή μεγέθους"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"Αλλαγή τύπου μεγιστοποίησης"</string>
@@ -1024,4 +1026,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"ΗΗΗ, ΜΜΜ η"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"ώ:λλ"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:λλ"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"Να επιτρέπεται στο <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> η πρόσβαση σε όλα τα αρχεία καταγραφής συσκευής;"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"Να επιτρέπεται η πρόσβαση για μία φορά"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Να μην επιτρέπεται"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"Τα αρχεία καταγραφής συσκευής καταγράφουν ό,τι συμβαίνει στη συσκευή σας. Οι εφαρμογές μπορούν να χρησιμοποιούν αυτά τα αρχεία καταγραφής για να εντοπίζουν και να διορθώνουν ζητήματα.\n\nΟρισμένα αρχεία καταγραφής ενδέχεται να περιέχουν ευαίσθητες πληροφορίες. Ως εκ τούτου, επιτρέψτε την πρόσβαση σε όλα τα αρχεία καταγραφής συσκευής μόνο στις εφαρμογές που εμπιστεύεστε. \n\nΕάν δεν επιτρέψετε σε αυτήν την εφαρμογή την πρόσβαση σε όλα τα αρχεία καταγραφής συσκευής, η εφαρμογή εξακολουθεί να έχει πρόσβαση στα δικά της αρχεία καταγραφής. Ο κατασκευαστής της συσκευής σας ενδέχεται να εξακολουθεί να έχει πρόσβαση σε ορισμένα αρχεία καταγραφής ή ορισμένες πληροφορίες στη συσκευή σας."</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index c23bfe607cb8..d036b882361c 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"Always allow from this computer"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"Allow"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"USB debugging not allowed"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"The user currently signed in to this device can\'t turn on USB debugging. To use this feature, switch to the primary user."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"The user currently signed in to this device can\'t turn on USB debugging. To use this feature, switch to an admin user."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Do you want to change the system language to <xliff:g id="LANGUAGE">%1$s</xliff:g>?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"System language change requested by another device"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Change language"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"Always allow on this network"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"Allow"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Wireless debugging not allowed"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"The user currently signed in to this device can’t turn on wireless debugging. To use this feature, switch to the primary user."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"The user currently signed in to this device can’t turn on wireless debugging. To use this feature, switch to an admin user."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"USB port disabled"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"To protect your device from liquid or debris, the USB port is disabled and won’t detect any accessories.\n\nYou’ll be notified when it’s OK to use the USB port again."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"USB port enabled to detect chargers and accessories"</string>
@@ -125,7 +125,7 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Voice Assist"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"QR code scanner"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"Unlock"</string>
+ <string name="accessibility_unlock_button" msgid="3613812140816244310">"Unlocked"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"Device locked"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Scanning face"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Send"</string>
@@ -168,7 +168,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"Can’t recognise face"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Use fingerprint instead"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth connected."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"Battery percentage unknown."</string>
@@ -180,8 +180,10 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"Aeroplane mode"</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN on."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"Battery <xliff:g id="NUMBER">%d</xliff:g> per cent."</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Battery <xliff:g id="PERCENTAGE">%1$s</xliff:g> percentage, about <xliff:g id="TIME">%2$s</xliff:g> left based on your usage"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Battery <xliff:g id="PERCENTAGE">%1$d</xliff:g> percentage, about <xliff:g id="TIME">%2$s</xliff:g> left based on your usage"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Battery charging, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> percent."</string>
+ <string name="accessibility_battery_level_charging_paused" msgid="1716051308782906917">"Battery <xliff:g id="PERCENTAGE">%d</xliff:g> per cent. Charging paused for battery protection."</string>
+ <string name="accessibility_battery_level_charging_paused_with_estimate" msgid="4006089349465741762">"Battery <xliff:g id="PERCENTAGE">%1$d</xliff:g> per cent, about <xliff:g id="TIME">%2$s</xliff:g> left based on your usage. Charging paused for battery protection."</string>
<string name="accessibility_overflow_action" msgid="8555835828182509104">"See all notifications"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"TeleTypewriter enabled."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Ringer vibrate."</string>
@@ -506,7 +508,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Unlock to use"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"There was a problem getting your cards. Please try again later."</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Lock screen settings"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"Scan QR code"</string>
+ <string name="qr_code_scanner_title" msgid="1938155688725760702">"QR code scanner"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Work profile"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Aeroplane mode"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"You won\'t hear your next alarm <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -789,6 +791,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Magnify full screen"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Magnify part of screen"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Switch"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Allow diagonal scrolling"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Resize"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"Change magnification type"</string>
@@ -1019,4 +1023,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"Allow <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> to access all device logs?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"Allow one-time access"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Don’t allow"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"Device logs record what happens on your device. Apps can use these logs to find and fix issues.\n\nSome logs may contain sensitive info, so only allow apps that you trust to access all device logs. \n\nIf you don’t allow this app to access all device logs, it can still access its own logs. Your device manufacturer may still be able to access some logs or info on your device."</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index 7c1f8fddae30..b25bcb5701b4 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -21,8 +21,8 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"System UI"</string>
<string name="battery_low_title" msgid="5319680173344341779">"Turn on Battery Saver?"</string>
- <string name="battery_low_description" msgid="3282977755476423966">"You have <xliff:g id="PERCENTAGE">%s</xliff:g> battery left. Battery Saver turns on Dark theme, restricts background activity and delays notifications."</string>
- <string name="battery_low_intro" msgid="5148725009653088790">"Battery Saver turns on Dark theme, restricts background activity and delays notifications."</string>
+ <string name="battery_low_description" msgid="3282977755476423966">"You have <xliff:g id="PERCENTAGE">%s</xliff:g> battery left. Battery Saver turns on Dark theme, restricts background activity, and delays notifications."</string>
+ <string name="battery_low_intro" msgid="5148725009653088790">"Battery Saver turns on Dark theme, restricts background activity, and delays notifications."</string>
<string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> remaining"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"Can\'t charge via USB"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"Use the charger that came with your device"</string>
@@ -30,7 +30,7 @@
<string name="battery_saver_confirmation_title_generic" msgid="2299231884234959849">"About Battery Saver"</string>
<string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Turn on"</string>
<string name="battery_saver_start_action" msgid="8353766979886287140">"Turn on"</string>
- <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"No, thanks"</string>
+ <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"No thanks"</string>
<string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Auto-rotate screen"</string>
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"Allow <xliff:g id="APPLICATION">%1$s</xliff:g> to access <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Allow <xliff:g id="APPLICATION">%1$s</xliff:g> to access <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nThis app has not been granted record permission but could capture audio through this USB device."</string>
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"Always allow from this computer"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"Allow"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"USB debugging not allowed"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"The user currently signed in to this device can\'t turn on USB debugging. To use this feature, switch to the primary user."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"The user currently signed in to this device can\'t turn on USB debugging. To use this feature, switch to an admin user."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Do you want to change the system language to <xliff:g id="LANGUAGE">%1$s</xliff:g>?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"System language change requested by another device"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Change language"</string>
@@ -62,9 +62,9 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"Always allow on this network"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"Allow"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Wireless debugging not allowed"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"The user currently signed in to this device can’t turn on wireless debugging. To use this feature, switch to the primary user."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"The user currently signed in to this device can’t turn on wireless debugging. To use this feature, switch to an admin user."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"USB port disabled"</string>
- <string name="usb_contaminant_message" msgid="7730476585174719805">"To protect your device from liquid or debris, the USB port is disabled and won’t detect any accessories.\n\nYou’ll be notified when it’s OK to use the USB port again."</string>
+ <string name="usb_contaminant_message" msgid="7730476585174719805">"To protect your device from liquid or debris, the USB port is disabled and won’t detect any accessories.\n\nYou’ll be notified when it’s okay to use the USB port again."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"USB port enabled to detect chargers and accessories"</string>
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Enable USB"</string>
<string name="learn_more" msgid="4690632085667273811">"Learn more"</string>
@@ -85,23 +85,23 @@
<string name="screenshot_scroll_label" msgid="2930198809899329367">"Capture more"</string>
<string name="screenshot_dismiss_description" msgid="4702341245899508786">"Dismiss screenshot"</string>
<string name="screenshot_preview_description" msgid="7606510140714080474">"Screenshot preview"</string>
- <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Top boundary <xliff:g id="PERCENT">%1$d</xliff:g> per cent"</string>
- <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Bottom boundary <xliff:g id="PERCENT">%1$d</xliff:g> per cent"</string>
- <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Left boundary <xliff:g id="PERCENT">%1$d</xliff:g> per cent"</string>
- <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Right boundary <xliff:g id="PERCENT">%1$d</xliff:g> per cent"</string>
+ <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Top boundary <xliff:g id="PERCENT">%1$d</xliff:g> percent"</string>
+ <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Bottom boundary <xliff:g id="PERCENT">%1$d</xliff:g> percent"</string>
+ <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Left boundary <xliff:g id="PERCENT">%1$d</xliff:g> percent"</string>
+ <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Right boundary <xliff:g id="PERCENT">%1$d</xliff:g> percent"</string>
<string name="screenrecord_name" msgid="2596401223859996572">"Screen Recorder"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Processing screen recording"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Ongoing notification for a screen record session"</string>
- <string name="screenrecord_start_label" msgid="1750350278888217473">"Start recording?"</string>
- <string name="screenrecord_description" msgid="1123231719680353736">"While recording, the Android System can capture any sensitive information that’s visible on your screen or played on your device. This includes passwords, payment info, photos, messages and audio."</string>
+ <string name="screenrecord_start_label" msgid="1750350278888217473">"Start Recording?"</string>
+ <string name="screenrecord_description" msgid="1123231719680353736">"While recording, Android System can capture any sensitive information that’s visible on your screen or played on your device. This includes passwords, payment info, photos, messages, and audio."</string>
<string name="screenrecord_option_entire_screen" msgid="1732437834603426934">"Record entire screen"</string>
<string name="screenrecord_option_single_app" msgid="5954863081500035825">"Record a single app"</string>
- <string name="screenrecord_warning_entire_screen" msgid="8141407178104195610">"While you\'re recording, Android has access to anything visible on your screen or played on your device. So be careful with passwords, payment details, messages or other sensitive information."</string>
- <string name="screenrecord_warning_single_app" msgid="7760723997065948283">"While you\'re recording an app, Android has access to anything shown or played on that app. So, be careful with passwords, payment details, messages or other sensitive information."</string>
+ <string name="screenrecord_warning_entire_screen" msgid="8141407178104195610">"While you\'re recording, Android has access to anything visible on your screen or played on your device. So be careful with passwords, payment details, messages, or other sensitive information."</string>
+ <string name="screenrecord_warning_single_app" msgid="7760723997065948283">"While you\'re recording an app, Android has access to anything shown or played on that app. So be careful with passwords, payment details, messages, or other sensitive information."</string>
<string name="screenrecord_start_recording" msgid="348286842544768740">"Start recording"</string>
<string name="screenrecord_audio_label" msgid="6183558856175159629">"Record audio"</string>
<string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Device audio"</string>
- <string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Sound from your device, like music, calls and ringtones"</string>
+ <string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Sound from your device, like music, calls, and ringtones"</string>
<string name="screenrecord_mic_label" msgid="2111264835791332350">"Microphone"</string>
<string name="screenrecord_device_audio_and_mic_label" msgid="1831323771978646841">"Device audio and microphone"</string>
<string name="screenrecord_start" msgid="330991441575775004">"Start"</string>
@@ -124,8 +124,8 @@
<string name="accessibility_phone_button" msgid="4256353121703100427">"Phone"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Voice Assist"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string>
- <string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"QR code scanner"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"Unlock"</string>
+ <string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"QR Code Scanner"</string>
+ <string name="accessibility_unlock_button" msgid="3613812140816244310">"Unlocked"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"Device locked"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Scanning face"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Send"</string>
@@ -140,8 +140,8 @@
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Tap Confirm to complete"</string>
<string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Unlocked by face. Press the unlock icon to continue."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Unlocked by face. Press to continue."</string>
- <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Face recognised. Press to continue."</string>
- <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Face recognised. Press the unlock icon to continue."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Face recognized. Press to continue."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Face recognized. Press the unlock icon to continue."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Authenticated"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Use PIN"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Use pattern"</string>
@@ -163,12 +163,12 @@
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"If you enter an incorrect password on the next attempt, your work profile and its data will be deleted."</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Touch the fingerprint sensor"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Fingerprint icon"</string>
- <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Can’t recognise face. Use fingerprint instead."</string>
+ <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Can’t recognize face. Use fingerprint instead."</string>
<!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
<skip />
- <string name="keyguard_face_failed" msgid="9044619102286917151">"Can’t recognise face"</string>
+ <string name="keyguard_face_failed" msgid="9044619102286917151">"Can’t recognize face"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Use fingerprint instead"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth connected."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"Battery percentage unknown."</string>
@@ -179,9 +179,11 @@
<string name="cell_data_off" msgid="4886198950247099526">"Off"</string>
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"Airplane mode."</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN on."</string>
- <string name="accessibility_battery_level" msgid="5143715405241138822">"Battery <xliff:g id="NUMBER">%d</xliff:g> per cent."</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Battery <xliff:g id="PERCENTAGE">%1$s</xliff:g> percentage, about <xliff:g id="TIME">%2$s</xliff:g> left based on your usage"</string>
+ <string name="accessibility_battery_level" msgid="5143715405241138822">"Battery <xliff:g id="NUMBER">%d</xliff:g> percent."</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Battery <xliff:g id="PERCENTAGE">%1$d</xliff:g> percent, about <xliff:g id="TIME">%2$s</xliff:g> left based on your usage"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Battery charging, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> percent."</string>
+ <string name="accessibility_battery_level_charging_paused" msgid="1716051308782906917">"Battery <xliff:g id="PERCENTAGE">%d</xliff:g> percent. Charging paused for battery protection."</string>
+ <string name="accessibility_battery_level_charging_paused_with_estimate" msgid="4006089349465741762">"Battery <xliff:g id="PERCENTAGE">%1$d</xliff:g> percent, about <xliff:g id="TIME">%2$s</xliff:g> left based on your usage. Charging paused for battery protection."</string>
<string name="accessibility_overflow_action" msgid="8555835828182509104">"See all notifications"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"TeleTypewriter enabled."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Ringer vibrate."</string>
@@ -196,7 +198,7 @@
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"total silence"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"alarms only"</string>
<string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Do Not Disturb."</string>
- <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth"</string>
+ <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth on."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Alarm set for <xliff:g id="TIME">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_more_time" msgid="7646479831704665284">"More time."</string>
@@ -205,12 +207,12 @@
<string name="accessibility_brightness" msgid="5391187016177823721">"Display brightness"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="2286843518689837719">"Mobile data is paused"</string>
<string name="data_usage_disabled_dialog_title" msgid="9131615296036724838">"Data is paused"</string>
- <string name="data_usage_disabled_dialog" msgid="7933201635215099780">"The data limit that you set has been reached. You are no longer using mobile data.\n\nIf you resume, charges may apply for data usage."</string>
+ <string name="data_usage_disabled_dialog" msgid="7933201635215099780">"The data limit you set has been reached. You are no longer using mobile data.\n\nIf you resume, charges may apply for data usage."</string>
<string name="data_usage_disabled_dialog_enable" msgid="2796648546086408937">"Resume"</string>
<string name="accessibility_location_active" msgid="2845747916764660369">"Location requests active"</string>
<string name="accessibility_sensors_off_active" msgid="2619725434618911551">"Sensors off active"</string>
<string name="accessibility_clear_all" msgid="970525598287244592">"Clear all notifications."</string>
- <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+<xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{# more notification inside.}other{# more notifications inside.}}"</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"Screen is locked in landscape orientation."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"Screen is locked in portrait orientation."</string>
@@ -229,7 +231,7 @@
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Auto-rotate"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Auto-rotate screen"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Location"</string>
- <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Screensaver"</string>
+ <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Screen saver"</string>
<string name="quick_settings_camera_label" msgid="5612076679385269339">"Camera access"</string>
<string name="quick_settings_mic_label" msgid="8392773746295266375">"Mic access"</string>
<string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Available"</string>
@@ -248,8 +250,8 @@
<string name="quick_settings_cast_detail_empty_text" msgid="2846282280014617785">"No devices available"</string>
<string name="quick_settings_cast_no_wifi" msgid="6980194769795014875">"Wi‑Fi not connected"</string>
<string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Brightness"</string>
- <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Colour inversion"</string>
- <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Colour correction"</string>
+ <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Color inversion"</string>
+ <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Color correction"</string>
<string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Manage users"</string>
<string name="quick_settings_done" msgid="2163641301648855793">"Done"</string>
<string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Close"</string>
@@ -318,11 +320,11 @@
<string name="sensor_privacy_dialog_open_settings" msgid="1503088305279285048">"Open settings."</string>
<string name="media_seamless_other_device" msgid="4654849800789196737">"Other device"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Toggle Overview"</string>
- <string name="zen_priority_introduction" msgid="3159291973383796646">"You won\'t be disturbed by sounds and vibrations, except from alarms, reminders, events and callers you specify. You\'ll still hear anything you choose to play including music, videos and games."</string>
- <string name="zen_alarms_introduction" msgid="3987266042682300470">"You won\'t be disturbed by sounds and vibrations, except from alarms. You\'ll still hear anything you choose to play including music, videos and games."</string>
- <string name="zen_priority_customize_button" msgid="4119213187257195047">"Customise"</string>
+ <string name="zen_priority_introduction" msgid="3159291973383796646">"You won\'t be disturbed by sounds and vibrations, except from alarms, reminders, events, and callers you specify. You\'ll still hear anything you choose to play including music, videos, and games."</string>
+ <string name="zen_alarms_introduction" msgid="3987266042682300470">"You won\'t be disturbed by sounds and vibrations, except from alarms. You\'ll still hear anything you choose to play including music, videos, and games."</string>
+ <string name="zen_priority_customize_button" msgid="4119213187257195047">"Customize"</string>
<string name="zen_silence_introduction_voice" msgid="853573681302712348">"This blocks ALL sounds and vibrations, including from alarms, music, videos, and games. You\'ll still be able to make phone calls."</string>
- <string name="zen_silence_introduction" msgid="6117517737057344014">"This blocks ALL sounds and vibrations, including from alarms, music, videos and games."</string>
+ <string name="zen_silence_introduction" msgid="6117517737057344014">"This blocks ALL sounds and vibrations, including from alarms, music, videos, and games."</string>
<string name="notification_tap_again" msgid="4477318164947497249">"Tap again to open"</string>
<string name="tap_again" msgid="1315420114387908655">"Tap again"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Swipe up to open"</string>
@@ -330,10 +332,10 @@
<string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Unlocked by face. Swipe up to open."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Unlocked by face. Press the unlock icon to open."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Unlocked by face. Press to open."</string>
- <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Face recognised. Press to open."</string>
- <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Face recognised. Press the unlock icon to open."</string>
+ <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Face recognized. Press to open."</string>
+ <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Face recognized. Press the unlock icon to open."</string>
<string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Unlocked by face"</string>
- <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Face recognised"</string>
+ <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Face recognized"</string>
<string-array name="udfps_accessibility_touch_hints">
<item msgid="1901953991150295169">"Move left"</item>
<item msgid="5558598599408514296">"Move down"</item>
@@ -365,7 +367,7 @@
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"All apps and data in this session will be deleted."</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Welcome back, guest!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Do you want to continue your session?"</string>
- <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Start again"</string>
+ <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Start over"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Yes, continue"</string>
<string name="guest_notification_app_name" msgid="2110425506754205509">"Guest mode"</string>
<string name="guest_notification_session_active" msgid="5567273684713471450">"You are in guest mode"</string>
@@ -375,20 +377,20 @@
<string name="user_remove_user_title" msgid="9124124694835811874">"Remove user?"</string>
<string name="user_remove_user_message" msgid="6702834122128031833">"All apps and data of this user will be deleted."</string>
<string name="user_remove_user_remove" msgid="8387386066949061256">"Remove"</string>
- <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> will have access to all of the information that is visible on your screen or played from your device while recording or casting. This includes information such as passwords, payment details, photos, messages and audio that you play."</string>
- <string name="media_projection_dialog_service_text" msgid="958000992162214611">"The service providing this function will have access to all of the information that is visible on your screen or played from your device while recording or casting. This includes information such as passwords, payment details, photos, messages and audio that you play."</string>
+ <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> will have access to all of the information that is visible on your screen or played from your device while recording or casting. This includes information such as passwords, payment details, photos, messages, and audio that you play."</string>
+ <string name="media_projection_dialog_service_text" msgid="958000992162214611">"The service providing this function will have access to all of the information that is visible on your screen or played from your device while recording or casting. This includes information such as passwords, payment details, photos, messages, and audio that you play."</string>
<string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Start recording or casting?"</string>
<string name="media_projection_dialog_title" msgid="3316063622495360646">"Start recording or casting with <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
<string name="media_projection_permission_dialog_title" msgid="7130975432309482596">"Allow <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> to share or record?"</string>
<string name="media_projection_permission_dialog_option_entire_screen" msgid="392086473225692983">"Entire screen"</string>
<string name="media_projection_permission_dialog_option_single_app" msgid="1591110238124910521">"A single app"</string>
- <string name="media_projection_permission_dialog_warning_entire_screen" msgid="3989078820637452717">"When you\'re sharing, recording or casting, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> has access to anything visible on your screen or played on your device. So be careful with passwords, payment details, messages or other sensitive information."</string>
- <string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"When you\'re sharing, recording or casting an app, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> has access to anything shown or played on that app. So, be careful with passwords, payment details, messages or other sensitive information."</string>
+ <string name="media_projection_permission_dialog_warning_entire_screen" msgid="3989078820637452717">"When you\'re sharing, recording, or casting, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> has access to anything visible on your screen or played on your device. So be careful with passwords, payment details, messages, or other sensitive information."</string>
+ <string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"When you\'re sharing, recording, or casting an app, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> has access to anything shown or played on that app. So be careful with passwords, payment details, messages, or other sensitive information."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Continue"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Share or record an app"</string>
<string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Allow this app to share or record?"</string>
- <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"When you\'re sharing, recording or casting, this app has access to anything visible on your screen or played on your device. So be careful with passwords, payment details, messages or other sensitive information."</string>
- <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"When you\'re sharing, recording or casting an app, this app has access to anything shown or played on that app. So be careful with passwords, payment details, messages or other sensitive information."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"When you\'re sharing, recording, or casting, this app has access to anything visible on your screen or played on your device. So be careful with passwords, payment details, messages, or other sensitive information."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"When you\'re sharing, recording, or casting an app, this app has access to anything shown or played on that app. So be careful with passwords, payment details, messages, or other sensitive information."</string>
<string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Blocked by your IT admin"</string>
<string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"Screen capturing is disabled by device policy"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Clear all"</string>
@@ -407,19 +409,19 @@
<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_financed_disclosure_named_management" msgid="2307703784594859524">"This device is provided by <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"This device belongs to your organization and is connected to the internet through <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"This device belongs to <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> and is connected to the Internet through <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"This device belongs to <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> and is connected to the internet through <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="929181757984262902">"This device belongs to your organization and is connected to the internet through VPNs"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"This device belongs to <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> and is connected to the Internet through VPNs"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"This device belongs to <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> and is connected to the internet through 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_managed_profile_network_activity" msgid="2636594621387832827">"Work profile network activity is visible to your IT admin"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Network may be monitored"</string>
- <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"This device is connected to the Internet through VPNs"</string>
- <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Your work apps are connected to the Internet through <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Your personal apps are connected to the Internet through <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"This device is connected to the Internet through <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"This device is connected to the internet through VPNs"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Your work apps are connected to the internet through <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Your personal apps are connected to the internet through <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"This device is connected to the internet through <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"This device is provided by <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Device management"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -428,22 +430,22 @@
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"View Policies"</string>
<string name="monitoring_button_view_controls" msgid="8316440345340701117">"View controls"</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_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> may be able to access data associated with this device, manage apps and change this device\'s settings.\n\nIf you have questions, contact <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>."</string>
+ <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> may be able to access data associated with this device, manage apps, and change this devices settings.\n\nIf you have questions, contact <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>."</string>
<string name="monitoring_description_management" msgid="4308879039175729014">"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>
<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>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Your admin has turned on network logging, which monitors traffic on your device."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Your admin has turned on network logging, which monitors traffic in your work profile but not in your personal profile."</string>
- <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"This device is connected to the Internet through <xliff:g id="VPN_APP">%1$s</xliff:g>. Your network activity, including emails and browsing data, is visible to your IT admin."</string>
- <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"This device is connected to the Internet through <xliff:g id="VPN_APP_0">%1$s</xliff:g> and <xliff:g id="VPN_APP_1">%2$s</xliff:g>. Your network activity, including emails and browsing data, is visible to your IT admin."</string>
- <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Your work apps are connected to the Internet through <xliff:g id="VPN_APP">%1$s</xliff:g>. Your network activity in work apps, including emails and browsing data, is visible to your IT admin and VPN provider."</string>
- <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Your personal apps are connected to the Internet through <xliff:g id="VPN_APP">%1$s</xliff:g>. Your network activity, including emails and browsing data, is visible to your VPN provider."</string>
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"This device is connected to the internet through <xliff:g id="VPN_APP">%1$s</xliff:g>. Your network activity, including emails and browsing data, is visible to your IT admin."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"This device is connected to the internet through <xliff:g id="VPN_APP_0">%1$s</xliff:g> and <xliff:g id="VPN_APP_1">%2$s</xliff:g>. Your network activity, including emails and browsing data, is visible to your IT admin."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Your work apps are connected to the internet through <xliff:g id="VPN_APP">%1$s</xliff:g>. Your network activity in work apps, including emails and browsing data, is visible to your IT admin and VPN provider."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Your personal apps are connected to the internet through <xliff:g id="VPN_APP">%1$s</xliff:g>. Your network activity, including emails and browsing data, is visible to your VPN provider."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Open VPN settings"</string>
- <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"This device is managed by your parent. Your parent can see and manage information such as the apps that you use, your location and your screen time."</string>
+ <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"This device is managed by your parent. Your parent can see and manage information such as the apps you use, your location, and your screen time."</string>
<string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
- <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"Kept unlocked by trust agent"</string>
+ <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"Kept unlocked by TrustAgent"</string>
<string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="accessibility_volume_settings" msgid="1458961116951564784">"Sound settings"</string>
<string name="volume_odi_captions_tip" msgid="8825655463280990941">"Automatically caption media"</string>
@@ -451,21 +453,21 @@
<string name="volume_odi_captions_content_description" msgid="4172765742046013630">"Captions overlay"</string>
<string name="volume_odi_captions_hint_enable" msgid="2073091194012843195">"enable"</string>
<string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"disable"</string>
- <string name="sound_settings" msgid="8874581353127418308">"Sound and vibration"</string>
+ <string name="sound_settings" msgid="8874581353127418308">"Sound &amp; vibration"</string>
<string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Settings"</string>
<string name="screen_pinning_title" msgid="9058007390337841305">"App is pinned"</string>
<string name="screen_pinning_description" msgid="8699395373875667743">"This keeps it in view until you unpin. Touch &amp; hold Back and Overview to unpin."</string>
<string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"This keeps it in view until you unpin. Touch &amp; hold Back and Home to unpin."</string>
- <string name="screen_pinning_description_gestural" msgid="7246323931831232068">"This keeps it in view until you unpin. Swipe up and hold to unpin."</string>
+ <string name="screen_pinning_description_gestural" msgid="7246323931831232068">"This keeps it in view until you unpin. Swipe up &amp; hold to unpin."</string>
<string name="screen_pinning_description_accessible" msgid="7386449191953535332">"This keeps it in view until you unpin. Touch &amp; hold Overview to unpin."</string>
<string name="screen_pinning_description_recents_invisible_accessible" msgid="2857071808674481986">"This keeps it in view until you unpin. Touch &amp; hold Home to unpin."</string>
- <string name="screen_pinning_exposes_personal_data" msgid="8189852022981524789">"Personal data may be accessible, such as contacts and email content."</string>
+ <string name="screen_pinning_exposes_personal_data" msgid="8189852022981524789">"Personal data may be accessible (such as contacts and email content)."</string>
<string name="screen_pinning_can_open_other_apps" msgid="7529756813231421455">"Pinned app may open other apps."</string>
- <string name="screen_pinning_toast" msgid="8177286912533744328">"To unpin this app, touch and hold Back and Overview buttons"</string>
- <string name="screen_pinning_toast_recents_invisible" msgid="6850978077443052594">"To unpin this app, touch and hold Back and Home buttons"</string>
- <string name="screen_pinning_toast_gesture_nav" msgid="170699893395336705">"To unpin this app, swipe up and hold"</string>
+ <string name="screen_pinning_toast" msgid="8177286912533744328">"To unpin this app, touch &amp; hold Back and Overview buttons"</string>
+ <string name="screen_pinning_toast_recents_invisible" msgid="6850978077443052594">"To unpin this app, touch &amp; hold Back and Home buttons"</string>
+ <string name="screen_pinning_toast_gesture_nav" msgid="170699893395336705">"To unpin this app, swipe up &amp; hold"</string>
<string name="screen_pinning_positive" msgid="3285785989665266984">"Got it"</string>
- <string name="screen_pinning_negative" msgid="6882816864569211666">"No, thanks"</string>
+ <string name="screen_pinning_negative" msgid="6882816864569211666">"No thanks"</string>
<string name="screen_pinning_start" msgid="7483998671383371313">"App pinned"</string>
<string name="screen_pinning_exit" msgid="4553787518387346893">"App unpinned"</string>
<string name="stream_voice_call" msgid="7468348170702375660">"Call"</string>
@@ -475,7 +477,7 @@
<string name="stream_alarm" msgid="16058075093011694">"Alarm"</string>
<string name="stream_notification" msgid="7930294049046243939">"Notification"</string>
<string name="stream_bluetooth_sco" msgid="6234562365528664331">"Bluetooth"</string>
- <string name="stream_dtmf" msgid="7322536356554673067">"Dual multi-tone frequency"</string>
+ <string name="stream_dtmf" msgid="7322536356554673067">"Dual multi tone frequency"</string>
<string name="stream_accessibility" msgid="3873610336741987152">"Accessibility"</string>
<string name="volume_ringer_status_normal" msgid="1339039682222461143">"Ring"</string>
<string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibrate"</string>
@@ -504,9 +506,9 @@
<string name="wallet_secondary_label_no_card" msgid="8488069304491125713">"Tap to open"</string>
<string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Updating"</string>
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Unlock to use"</string>
- <string name="wallet_error_generic" msgid="257704570182963611">"There was a problem getting your cards. Please try again later."</string>
+ <string name="wallet_error_generic" msgid="257704570182963611">"There was a problem getting your cards, please try again later"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Lock screen settings"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"Scan QR code"</string>
+ <string name="qr_code_scanner_title" msgid="1938155688725760702">"QR code scanner"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Work profile"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Airplane mode"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"You won\'t hear your next alarm <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -515,17 +517,17 @@
<string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Hotspot"</string>
<string name="accessibility_managed_profile" msgid="4703836746209377356">"Work profile"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Fun for some but not for all"</string>
- <string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner gives you extra ways to tweak and customise the Android user interface. These experimental features may change, break or disappear in future releases. Proceed with caution."</string>
- <string name="tuner_persistent_warning" msgid="230466285569307806">"These experimental features may change, break or disappear in future releases. Proceed with caution."</string>
+ <string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner gives you extra ways to tweak and customize the Android user interface. These experimental features may change, break, or disappear in future releases. Proceed with caution."</string>
+ <string name="tuner_persistent_warning" msgid="230466285569307806">"These experimental features may change, break, or disappear in future releases. Proceed with caution."</string>
<string name="got_it" msgid="477119182261892069">"Got it"</string>
<string name="tuner_toast" msgid="3812684836514766951">"Congrats! System UI Tuner has been added to Settings"</string>
- <string name="remove_from_settings" msgid="633775561782209994">"Remove from settings"</string>
+ <string name="remove_from_settings" msgid="633775561782209994">"Remove from Settings"</string>
<string name="remove_from_settings_prompt" msgid="551565437265615426">"Remove System UI Tuner from Settings and stop using all of its features?"</string>
<string name="enable_bluetooth_title" msgid="866883307336662596">"Turn on Bluetooth?"</string>
<string name="enable_bluetooth_message" msgid="6740938333772779717">"To connect your keyboard with your tablet, you first have to turn on Bluetooth."</string>
<string name="enable_bluetooth_confirmation_ok" msgid="2866408183324184876">"Turn on"</string>
<string name="tuner_full_importance_settings" msgid="1388025816553459059">"Power notification controls"</string>
- <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"On – Face-based"</string>
+ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"On - Face-based"</string>
<string name="power_notification_controls_description" msgid="1334963837572708952">"With power notification controls, you can set an importance level from 0 to 5 for an app\'s notifications. \n\n"<b>"Level 5"</b>" \n- Show at the top of the notification list \n- Allow full screen interruption \n- Always peek \n\n"<b>"Level 4"</b>" \n- Prevent full screen interruption \n- Always peek \n\n"<b>"Level 3"</b>" \n- Prevent full screen interruption \n- Never peek \n\n"<b>"Level 2"</b>" \n- Prevent full screen interruption \n- Never peek \n- Never make sound and vibration \n\n"<b>"Level 1"</b>" \n- Prevent full screen interruption \n- Never peek \n- Never make sound or vibrate \n- Hide from lock screen and status bar \n- Show at the bottom of the notification list \n\n"<b>"Level 0"</b>" \n- Block all notifications from the app"</string>
<string name="inline_done_button" msgid="6043094985588909584">"Done"</string>
<string name="inline_ok_button" msgid="603075490581280343">"Apply"</string>
@@ -538,10 +540,10 @@
<string name="notification_channel_summary_default" msgid="3282930979307248890">"May ring or vibrate based on phone settings"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="1782419896613644568">"May ring or vibrate based on phone settings. Conversations from <xliff:g id="APP_NAME">%1$s</xliff:g> bubble by default."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Have the system determine if this notification should make sound or vibration"</string>
- <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"&lt;b&gt;Status:&lt;/b&gt; promoted to default"</string>
- <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"&lt;b&gt;Status:&lt;/b&gt; demoted to silent"</string>
- <string name="notification_channel_summary_automatic_promoted" msgid="1301710305149590426">"&lt;b&gt;Status:&lt;/b&gt; ranked higher"</string>
- <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Status:&lt;/b&gt; ranked lower"</string>
+ <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"&lt;b&gt;Status:&lt;/b&gt; Promoted to Default"</string>
+ <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"&lt;b&gt;Status:&lt;/b&gt; Demoted to Silent"</string>
+ <string name="notification_channel_summary_automatic_promoted" msgid="1301710305149590426">"&lt;b&gt;Status:&lt;/b&gt; Ranked Higher"</string>
+ <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Status:&lt;/b&gt; Ranked Lower"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Shows at the top of conversation notifications and as a profile picture on lock screen"</string>
<string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Shows at the top of conversation notifications and as a profile picture on lock screen, appears as a bubble"</string>
<string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Shows at the top of conversation notifications and as a profile picture on lock screen, interrupts Do Not Disturb"</string>
@@ -554,15 +556,15 @@
<string name="notification_delegate_header" msgid="1264510071031479920">"Proxied notification"</string>
<string name="notification_channel_dialog_title" msgid="6856514143093200019">"All <xliff:g id="APP_NAME">%1$s</xliff:g> notifications"</string>
<string name="see_more_title" msgid="7409317011708185729">"See more"</string>
- <string name="feedback_alerted" msgid="5192459808484271208">"This notification was automatically &lt;b&gt;promoted to default&lt;/b&gt; by the system."</string>
- <string name="feedback_silenced" msgid="9116540317466126457">"This notification was automatically &lt;b&gt;demoted to silent&lt;/b&gt; by the system."</string>
+ <string name="feedback_alerted" msgid="5192459808484271208">"This notification was automatically &lt;b&gt;promoted to Default&lt;/b&gt; by the system."</string>
+ <string name="feedback_silenced" msgid="9116540317466126457">"This notification was automatically &lt;b&gt;demoted to Silent&lt;/b&gt; by the system."</string>
<string name="feedback_promoted" msgid="2125562787759780807">"This notification was automatically &lt;b&gt;ranked higher&lt;/b&gt; in your shade."</string>
<string name="feedback_demoted" msgid="951884763467110604">"This notification was automatically &lt;b&gt;ranked lower&lt;/b&gt; in your shade."</string>
<string name="feedback_prompt" msgid="3656728972307896379">"Let the developer know your feedback. Was this correct?"</string>
<string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"Notification controls for <xliff:g id="APP_NAME">%1$s</xliff:g> opened"</string>
<string name="notification_channel_controls_closed_accessibility" msgid="1561909368876911701">"Notification controls for <xliff:g id="APP_NAME">%1$s</xliff:g> closed"</string>
<string name="notification_more_settings" msgid="4936228656989201793">"More settings"</string>
- <string name="notification_app_settings" msgid="8963648463858039377">"Customise"</string>
+ <string name="notification_app_settings" msgid="8963648463858039377">"Customize"</string>
<string name="notification_conversation_bubble" msgid="2242180995373949022">"Show bubble"</string>
<string name="notification_conversation_unbubble" msgid="6908427185031099868">"Remove bubbles"</string>
<string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
@@ -581,7 +583,7 @@
<string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Down"</string>
<string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Left"</string>
<string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Right"</string>
- <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Centre"</string>
+ <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Center"</string>
<string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
<string name="keyboard_key_space" msgid="6980847564173394012">"Space"</string>
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
@@ -591,7 +593,7 @@
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Next"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Previous"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Rewind"</string>
- <string name="keyboard_key_media_fast_forward" msgid="3572444327046911822">"Fast-Forward"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3572444327046911822">"Fast Forward"</string>
<string name="keyboard_key_page_up" msgid="173914303254199845">"Page Up"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Page Down"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Delete"</string>
@@ -603,10 +605,10 @@
<string name="notif_inline_reply_remove_attachment_description" msgid="7954075334095405429">"Remove attachment"</string>
<string name="keyboard_shortcut_group_system" msgid="1583416273777875970">"System"</string>
<string name="keyboard_shortcut_group_system_home" msgid="7465138628692109907">"Home"</string>
- <string name="keyboard_shortcut_group_system_recents" msgid="8628108256824616927">"Recent"</string>
+ <string name="keyboard_shortcut_group_system_recents" msgid="8628108256824616927">"Recents"</string>
<string name="keyboard_shortcut_group_system_back" msgid="1055709713218453863">"Back"</string>
<string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Notifications"</string>
- <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Keyboard shortcuts"</string>
+ <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Keyboard Shortcuts"</string>
<string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Switch keyboard layout"</string>
<string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Applications"</string>
<string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Assist"</string>
@@ -648,7 +650,7 @@
<string name="save" msgid="3392754183673848006">"Save"</string>
<string name="reset" msgid="8715144064608810383">"Reset"</string>
<string name="clipboard" msgid="8517342737534284617">"Clipboard"</string>
- <string name="accessibility_key" msgid="3471162841552818281">"Customised navigation button"</string>
+ <string name="accessibility_key" msgid="3471162841552818281">"Custom navigation button"</string>
<string name="left_keycode" msgid="8211040899126637342">"Left keycode"</string>
<string name="right_keycode" msgid="2480715509844798438">"Right keycode"</string>
<string name="left_icon" msgid="5036278531966897006">"Left icon"</string>
@@ -660,7 +662,7 @@
<string name="qs_edit" msgid="5583565172803472437">"Edit"</string>
<string name="tuner_time" msgid="2450785840990529997">"Time"</string>
<string-array name="clock_options">
- <item msgid="3986445361435142273">"Show hours, minutes and seconds"</item>
+ <item msgid="3986445361435142273">"Show hours, minutes, and seconds"</item>
<item msgid="1271006222031257266">"Show hours and minutes (default)"</item>
<item msgid="6135970080453877218">"Don\'t show this icon"</item>
</string-array>
@@ -687,7 +689,7 @@
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Close quick settings."</string>
<string name="accessibility_quick_settings_user" msgid="505821942882668619">"Signed in as <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"choose user"</string>
- <string name="data_connection_no_internet" msgid="691058178914184544">"No Internet"</string>
+ <string name="data_connection_no_internet" msgid="691058178914184544">"No internet"</string>
<string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Open <xliff:g id="ID_1">%s</xliff:g> settings."</string>
<string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Edit order of settings."</string>
<string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Power menu"</string>
@@ -695,14 +697,14 @@
<string name="tuner_lock_screen" msgid="2267383813241144544">"Lock screen"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"Phone turned off due to heat"</string>
<string name="thermal_shutdown_message" msgid="6142269839066172984">"Your phone is now running normally.\nTap for more info"</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>
+ <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>
<string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"See care steps"</string>
<string name="high_temp_title" msgid="2218333576838496100">"Phone is getting warm"</string>
- <string name="high_temp_notif_message" msgid="1277346543068257549">"Some features are limited while phone cools down.\nTap for more info"</string>
- <string name="high_temp_dialog_message" msgid="3793606072661253968">"Your phone will automatically try to cool down. You can still use your phone, but it may run more slowly.\n\nOnce your phone has cooled down, it will run normally."</string>
+ <string name="high_temp_notif_message" msgid="1277346543068257549">"Some features limited while phone cools down.\nTap for more info"</string>
+ <string name="high_temp_dialog_message" msgid="3793606072661253968">"Your phone will automatically try to cool down. You can still use your phone, but it may run slower.\n\nOnce your phone has cooled down, it will run normally."</string>
<string name="high_temp_dialog_help_text" msgid="7380171287943345858">"See care steps"</string>
<string name="high_temp_alarm_title" msgid="8654754369605452169">"Unplug your device"</string>
- <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"Your device is getting warm near the charging port. If it’s connected to a charger or USB accessory, unplug it and take care as the cable may also be warm."</string>
+ <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"Your device is getting warm near the charging port. If it’s connected to a charger or USB accessory, unplug it, and take care as the cable may also be warm."</string>
<string name="high_temp_alarm_help_care_steps" msgid="5017002218341329566">"See care steps"</string>
<string name="lockscreen_shortcut_left" msgid="1238765178956067599">"Left shortcut"</string>
<string name="lockscreen_shortcut_right" msgid="4138414674531853719">"Right shortcut"</string>
@@ -728,11 +730,11 @@
<string name="instant_apps" msgid="8337185853050247304">"Instant Apps"</string>
<string name="instant_apps_title" msgid="8942706782103036910">"<xliff:g id="APP">%1$s</xliff:g> running"</string>
<string name="instant_apps_message" msgid="6112428971833011754">"App opened without being installed."</string>
- <string name="instant_apps_message_with_help" msgid="1816952263531203932">"App opened without being installed. Tap to find out more."</string>
+ <string name="instant_apps_message_with_help" msgid="1816952263531203932">"App opened without being installed. Tap to learn more."</string>
<string name="app_info" msgid="5153758994129963243">"App info"</string>
<string name="go_to_web" msgid="636673528981366511">"Go to browser"</string>
<string name="mobile_data" msgid="4564407557775397216">"Mobile data"</string>
- <string name="mobile_data_text_format" msgid="6806501540022589786">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
+ <string name="mobile_data_text_format" msgid="6806501540022589786">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi is off"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth is off"</string>
@@ -743,22 +745,22 @@
<string name="running_foreground_services_title" msgid="5137313173431186685">"Apps running in background"</string>
<string name="running_foreground_services_msg" msgid="3009459259222695385">"Tap for details on battery and data usage"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"Turn off mobile data?"</string>
- <string name="mobile_data_disable_message" msgid="8604966027899770415">"You won\'t have access to data or the Internet through <xliff:g id="CARRIER">%s</xliff:g>. Internet will only be available via Wi-Fi."</string>
+ <string name="mobile_data_disable_message" msgid="8604966027899770415">"You wont have access to data or the internet through <xliff:g id="CARRIER">%s</xliff:g>. Internet will only be available via Wi-Fi."</string>
<string name="mobile_data_disable_message_default_carrier" msgid="6496033312431658238">"your carrier"</string>
<string name="auto_data_switch_disable_title" msgid="5146527155665190652">"Switch back to <xliff:g id="CARRIER">%s</xliff:g>?"</string>
- <string name="auto_data_switch_disable_message" msgid="5885533647399535852">"Mobile data won\'t automatically switch based on availability"</string>
+ <string name="auto_data_switch_disable_message" msgid="5885533647399535852">"Mobile data wont automatically switch based on availability"</string>
<string name="auto_data_switch_dialog_negative_button" msgid="2370876875999891444">"No thanks"</string>
<string name="auto_data_switch_dialog_positive_button" msgid="8531782041263087564">"Yes, switch"</string>
<string name="touch_filtered_warning" msgid="8119511393338714836">"Because an app is obscuring a permission request, Settings can’t verify your response."</string>
<string name="slice_permission_title" msgid="3262615140094151017">"Allow <xliff:g id="APP_0">%1$s</xliff:g> to show <xliff:g id="APP_2">%2$s</xliff:g> slices?"</string>
- <string name="slice_permission_text_1" msgid="6675965177075443714">"– It can read information from <xliff:g id="APP">%1$s</xliff:g>"</string>
- <string name="slice_permission_text_2" msgid="6758906940360746983">"– It can take actions inside <xliff:g id="APP">%1$s</xliff:g>"</string>
+ <string name="slice_permission_text_1" msgid="6675965177075443714">"- It can read information from <xliff:g id="APP">%1$s</xliff:g>"</string>
+ <string name="slice_permission_text_2" msgid="6758906940360746983">"- It can take actions inside <xliff:g id="APP">%1$s</xliff:g>"</string>
<string name="slice_permission_checkbox" msgid="4242888137592298523">"Allow <xliff:g id="APP">%1$s</xliff:g> to show slices from any app"</string>
<string name="slice_permission_allow" msgid="6340449521277951123">"Allow"</string>
<string name="slice_permission_deny" msgid="6870256451658176895">"Deny"</string>
<string name="auto_saver_title" msgid="6873691178754086596">"Tap to schedule Battery Saver"</string>
<string name="auto_saver_text" msgid="3214960308353838764">"Turn on when battery is likely to run out"</string>
- <string name="no_auto_saver_action" msgid="7467924389609773835">"No, thanks"</string>
+ <string name="no_auto_saver_action" msgid="7467924389609773835">"No thanks"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
<string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"In use"</string>
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Applications are using your <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
@@ -777,8 +779,8 @@
<string name="privacy_type_media_projection" msgid="8136723828804251547">"screen recording"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"No title"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Standby"</string>
- <string name="magnification_window_title" msgid="4863914360847258333">"Magnification window"</string>
- <string name="magnification_controls_title" msgid="8421106606708891519">"Magnification window controls"</string>
+ <string name="magnification_window_title" msgid="4863914360847258333">"Magnification Window"</string>
+ <string name="magnification_controls_title" msgid="8421106606708891519">"Magnification Window Controls"</string>
<string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Zoom in"</string>
<string name="accessibility_control_zoom_out" msgid="69578832020304084">"Zoom out"</string>
<string name="accessibility_control_move_up" msgid="6622825494014720136">"Move up"</string>
@@ -789,6 +791,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Magnify full screen"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Magnify part of screen"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Switch"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Allow diagonal scrolling"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Resize"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"Change magnification type"</string>
@@ -805,7 +809,7 @@
<string name="accessibility_magnification_close" msgid="1099965835844673375">"Close"</string>
<string name="accessibility_magnifier_edit" msgid="1522877239671820636">"Edit"</string>
<string name="accessibility_magnification_magnifier_window_settings" msgid="2834685072221468434">"Magnifier window settings"</string>
- <string name="accessibility_floating_button_migration_tooltip" msgid="5217151214439341902">"Tap to open accessibility features. Customise or replace this button in Settings.\n\n"<annotation id="link">"View settings"</annotation></string>
+ <string name="accessibility_floating_button_migration_tooltip" msgid="5217151214439341902">"Tap to open accessibility features. Customize or replace this button in Settings.\n\n"<annotation id="link">"View settings"</annotation></string>
<string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Move button to the edge to hide it temporarily"</string>
<string name="accessibility_floating_button_undo" msgid="511112888715708241">"Undo"</string>
<string name="accessibility_floating_button_undo_message_text" msgid="3044079592757099698">"{count,plural, =1{{label} shortcut removed}other{# shortcuts removed}}"</string>
@@ -821,15 +825,15 @@
<string name="controls_providers_title" msgid="6879775889857085056">"Choose app to add controls"</string>
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# control added.}other{# controls added.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Removed"</string>
- <string name="accessibility_control_favorite" msgid="8694362691985545985">"Favourited"</string>
- <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Favourited, position <xliff:g id="NUMBER">%d</xliff:g>"</string>
- <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Unfavourited"</string>
- <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"favourite"</string>
- <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"unfavourite"</string>
+ <string name="accessibility_control_favorite" msgid="8694362691985545985">"Favorited"</string>
+ <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Favorited, position <xliff:g id="NUMBER">%d</xliff:g>"</string>
+ <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Unfavorited"</string>
+ <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"favorite"</string>
+ <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"unfavorite"</string>
<string name="accessibility_control_move" msgid="8980344493796647792">"Move to position <xliff:g id="NUMBER">%d</xliff:g>"</string>
<string name="controls_favorite_default_title" msgid="967742178688938137">"Controls"</string>
<string name="controls_favorite_subtitle" msgid="6481675111056961083">"Choose controls to access from Quick Settings"</string>
- <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Hold and drag to rearrange controls"</string>
+ <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_see_other_apps" msgid="7709087332255283460">"See other apps"</string>
@@ -840,11 +844,11 @@
<string name="controls_dialog_ok" msgid="2770230012857881822">"Add"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"Suggested by <xliff:g id="APP">%s</xliff:g>"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"Device locked"</string>
- <string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Show and control devices from the lock screen?"</string>
- <string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"You can add controls for your external devices to the lock screen.\n\nYour device app may allow you to control some devices without unlocking your phone or tablet.\n\nYou can make changes at any time in Settings."</string>
- <string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Control devices from the lock screen?"</string>
+ <string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Show and control devices from lock screen?"</string>
+ <string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"You can add controls for your external devices to the lock screen.\n\nYour device app may allow you to control some devices without unlocking your phone or tablet.\n\nYou can make changes any time in Settings."</string>
+ <string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Control devices from lock screen?"</string>
<string name="controls_settings_trivial_controls_dialog_message" msgid="237183787721917586">"You can control some devices without unlocking your phone or tablet.\n\nYour device app determines which devices can be controlled in this way."</string>
- <string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"No, thanks"</string>
+ <string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"No thanks"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Yes"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN contains letters or symbols"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"Verify <xliff:g id="DEVICE">%s</xliff:g>"</string>
@@ -879,7 +883,7 @@
<string name="controls_error_timeout" msgid="794197289772728958">"Inactive, check app"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Not found"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"Control is unavailable"</string>
- <string name="controls_error_removed_message" msgid="2885911717034750542">"Couldn’t access <xliff:g id="DEVICE">%1$s</xliff:g>. Check the <xliff:g id="APPLICATION">%2$s</xliff:g> app to make sure that the control is still available and that the app settings haven’t changed."</string>
+ <string name="controls_error_removed_message" msgid="2885911717034750542">"Couldn’t access <xliff:g id="DEVICE">%1$s</xliff:g>. Check the <xliff:g id="APPLICATION">%2$s</xliff:g> app to make sure the control is still available and that the app settings haven’t changed."</string>
<string name="controls_open_app" msgid="483650971094300141">"Open app"</string>
<string name="controls_error_generic" msgid="352500456918362905">"Can’t load status"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Error, try again"</string>
@@ -887,7 +891,7 @@
<string name="controls_menu_edit" msgid="890623986951347062">"Edit controls"</string>
<string name="media_output_dialog_add_output" msgid="5642703238877329518">"Add outputs"</string>
<string name="media_output_dialog_group" msgid="5571251347877452212">"Group"</string>
- <string name="media_output_dialog_single_device" msgid="3102758980643351058">"One device selected"</string>
+ <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 device selected"</string>
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> devices selected"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(disconnected)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Can\'t switch. Tap to try again."</string>
@@ -899,9 +903,9 @@
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Volume"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"How broadcasting works"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"Broadcast"</string>
- <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"People near you with compatible Bluetooth devices can listen to the media that you\'re broadcasting"</string>
+ <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"People near you with compatible Bluetooth devices can listen to the media you\'re broadcasting"</string>
<string name="media_output_broadcasting_message" msgid="4150299923404886073">"To listen to your broadcast, people nearby with compatible Bluetooth devices can scan your QR code or use your broadcast name and password"</string>
- <string name="media_output_broadcast_name" msgid="8786127091542624618">"Broadcast name"</string>
+ <string name="media_output_broadcast_name" msgid="8786127091542624618">"Broadcast Name"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"Password"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Save"</string>
<string name="media_output_broadcast_starting" msgid="8130153654166235557">"Starting…"</string>
@@ -912,21 +916,21 @@
<string name="build_number_copy_toast" msgid="877720921605503046">"Build number copied to clipboard."</string>
<string name="basic_status" msgid="2315371112182658176">"Open conversation"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Conversation widgets"</string>
- <string name="select_conversation_text" msgid="3376048251434956013">"Tap a conversation to add it to your home screen"</string>
+ <string name="select_conversation_text" msgid="3376048251434956013">"Tap a conversation to add it to your Home screen"</string>
<string name="no_conversations_text" msgid="5354115541282395015">"Your recent conversations will show up here"</string>
<string name="priority_conversations" msgid="3967482288896653039">"Priority conversations"</string>
<string name="recent_conversations" msgid="8531874684782574622">"Recent conversations"</string>
<string name="days_timestamp" msgid="5821854736213214331">"<xliff:g id="DURATION">%1$s</xliff:g> days ago"</string>
<string name="one_week_timestamp" msgid="4925600765473875590">"1 week ago"</string>
<string name="two_weeks_timestamp" msgid="9111801081871962155">"2 weeks ago"</string>
- <string name="over_one_week_timestamp" msgid="3770560704420807142">"More than 1 week ago"</string>
- <string name="over_two_weeks_timestamp" msgid="6300507859007874050">"More than 2 weeks ago"</string>
+ <string name="over_one_week_timestamp" msgid="3770560704420807142">"Over 1 week ago"</string>
+ <string name="over_two_weeks_timestamp" msgid="6300507859007874050">"Over 2 weeks ago"</string>
<string name="birthday_status" msgid="2596961629465396761">"Birthday"</string>
- <string name="birthday_status_content_description" msgid="682836371128282925">"It\'s <xliff:g id="NAME">%1$s</xliff:g>\'s birthday"</string>
+ <string name="birthday_status_content_description" msgid="682836371128282925">"It\'s <xliff:g id="NAME">%1$s</xliff:g>s birthday"</string>
<string name="upcoming_birthday_status" msgid="2005452239256870351">"Birthday soon"</string>
- <string name="upcoming_birthday_status_content_description" msgid="2165036816803797148">"It\'s <xliff:g id="NAME">%1$s</xliff:g>\'s birthday soon"</string>
+ <string name="upcoming_birthday_status_content_description" msgid="2165036816803797148">"It\'s <xliff:g id="NAME">%1$s</xliff:g>s birthday soon"</string>
<string name="anniversary_status" msgid="1790034157507590838">"Anniversary"</string>
- <string name="anniversary_status_content_description" msgid="8212171790843327442">"It\'s <xliff:g id="NAME">%1$s</xliff:g>\'s anniversary"</string>
+ <string name="anniversary_status_content_description" msgid="8212171790843327442">"It\'s <xliff:g id="NAME">%1$s</xliff:g>s anniversary"</string>
<string name="location_status" msgid="1294990572202541812">"Sharing location"</string>
<string name="location_status_content_description" msgid="2982386178160071305">"<xliff:g id="NAME">%1$s</xliff:g> is sharing location"</string>
<string name="new_story_status" msgid="9012195158584846525">"New story"</string>
@@ -939,7 +943,7 @@
<string name="status_before_loading" msgid="1500477307859631381">"Content will show up soon"</string>
<string name="missed_call" msgid="4228016077700161689">"Missed call"</string>
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
- <string name="people_tile_description" msgid="8154966188085545556">"See recent messages, missed calls and status updates"</string>
+ <string name="people_tile_description" msgid="8154966188085545556">"See recent messages, missed calls, and status updates"</string>
<string name="people_tile_title" msgid="6589377493334871272">"Conversation"</string>
<string name="paused_by_dnd" msgid="7856941866433556428">"Paused by Do Not Disturb"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> sent a message: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
@@ -950,13 +954,13 @@
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Tap for more information"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"No alarm set"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Fingerprint sensor"</string>
- <string name="accessibility_authenticate_hint" msgid="798914151813205721">"Authenticate"</string>
+ <string name="accessibility_authenticate_hint" msgid="798914151813205721">"authenticate"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"enter device"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Use fingerprint to open"</string>
<string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Authentication required. Touch the fingerprint sensor to authenticate."</string>
<string name="ongoing_phone_call_content_description" msgid="5332334388483099947">"Ongoing phone call"</string>
<string name="mobile_data_settings_title" msgid="3955246641380064901">"Mobile data"</string>
- <string name="preference_summary_default_combination" msgid="8453246369903749670">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="NETWORKMODE">%2$s</xliff:g>"</string>
+ <string name="preference_summary_default_combination" msgid="8453246369903749670">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="NETWORKMODE">%2$s</xliff:g>"</string>
<string name="mobile_data_connection_active" msgid="944490013299018227">"Connected"</string>
<string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Temporarily connected"</string>
<string name="mobile_data_poor_connection" msgid="819617772268371434">"Poor connection"</string>
@@ -971,7 +975,7 @@
<string name="wifi_failed_connect_message" msgid="4161863112079000071">"Failed to connect to network"</string>
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Wi‑Fi won’t auto-connect for now"</string>
<string name="see_all_networks" msgid="3773666844913168122">"See all"</string>
- <string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"To switch networks, disconnect Ethernet"</string>
+ <string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"To switch networks, disconnect ethernet"</string>
<string name="wifi_scan_notify_message" msgid="3753839537448621794">"To improve device experience, apps and services can still scan for Wi‑Fi networks at any time, even when Wi‑Fi is off. You can change this in Wi‑Fi scanning settings. "<annotation id="link">"Change"</annotation></string>
<string name="turn_off_airplane_mode" msgid="8425587763226548579">"Turn off Airplane mode"</string>
<string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"<xliff:g id="APPNAME">%1$s</xliff:g> wants to add the following tile to Quick Settings"</string>
@@ -995,13 +999,13 @@
<string name="clipboard_text_copied" msgid="5100836834278976679">"Text copied"</string>
<string name="clipboard_image_copied" msgid="3793365360174328722">"Image copied"</string>
<string name="clipboard_content_copied" msgid="144452398567828145">"Content copied"</string>
- <string name="clipboard_editor" msgid="2971197550401892843">"Clipboard editor"</string>
+ <string name="clipboard_editor" msgid="2971197550401892843">"Clipboard Editor"</string>
<string name="clipboard_overlay_window_name" msgid="6450043652167357664">"Clipboard"</string>
<string name="clipboard_image_preview" msgid="2156475174343538128">"Image preview"</string>
<string name="clipboard_edit" msgid="4500155216174011640">"edit"</string>
<string name="add" msgid="81036585205287996">"Add"</string>
<string name="manage_users" msgid="1823875311934643849">"Manage users"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"This notification does not support dragging to Split screen."</string>
+ <string name="drag_split_not_supported" msgid="4326847447699729722">"This notification does not support dragging to Splitscreen."</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi unavailable"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Priority mode"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm set"</string>
@@ -1019,4 +1023,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"Allow <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> to access all device logs?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"Allow one-time access"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Don’t allow"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"Device logs record what happens on your device. Apps can use these logs to find and fix issues.\n\nSome logs may contain sensitive info, so only allow apps you trust to access all device logs. \n\nIf you don’t allow this app to access all device logs, it can still access its own logs. Your device manufacturer may still be able to access some logs or info on your device."</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index c23bfe607cb8..d036b882361c 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"Always allow from this computer"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"Allow"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"USB debugging not allowed"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"The user currently signed in to this device can\'t turn on USB debugging. To use this feature, switch to the primary user."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"The user currently signed in to this device can\'t turn on USB debugging. To use this feature, switch to an admin user."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Do you want to change the system language to <xliff:g id="LANGUAGE">%1$s</xliff:g>?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"System language change requested by another device"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Change language"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"Always allow on this network"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"Allow"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Wireless debugging not allowed"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"The user currently signed in to this device can’t turn on wireless debugging. To use this feature, switch to the primary user."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"The user currently signed in to this device can’t turn on wireless debugging. To use this feature, switch to an admin user."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"USB port disabled"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"To protect your device from liquid or debris, the USB port is disabled and won’t detect any accessories.\n\nYou’ll be notified when it’s OK to use the USB port again."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"USB port enabled to detect chargers and accessories"</string>
@@ -125,7 +125,7 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Voice Assist"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"QR code scanner"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"Unlock"</string>
+ <string name="accessibility_unlock_button" msgid="3613812140816244310">"Unlocked"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"Device locked"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Scanning face"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Send"</string>
@@ -168,7 +168,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"Can’t recognise face"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Use fingerprint instead"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth connected."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"Battery percentage unknown."</string>
@@ -180,8 +180,10 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"Aeroplane mode"</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN on."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"Battery <xliff:g id="NUMBER">%d</xliff:g> per cent."</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Battery <xliff:g id="PERCENTAGE">%1$s</xliff:g> percentage, about <xliff:g id="TIME">%2$s</xliff:g> left based on your usage"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Battery <xliff:g id="PERCENTAGE">%1$d</xliff:g> percentage, about <xliff:g id="TIME">%2$s</xliff:g> left based on your usage"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Battery charging, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> percent."</string>
+ <string name="accessibility_battery_level_charging_paused" msgid="1716051308782906917">"Battery <xliff:g id="PERCENTAGE">%d</xliff:g> per cent. Charging paused for battery protection."</string>
+ <string name="accessibility_battery_level_charging_paused_with_estimate" msgid="4006089349465741762">"Battery <xliff:g id="PERCENTAGE">%1$d</xliff:g> per cent, about <xliff:g id="TIME">%2$s</xliff:g> left based on your usage. Charging paused for battery protection."</string>
<string name="accessibility_overflow_action" msgid="8555835828182509104">"See all notifications"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"TeleTypewriter enabled."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Ringer vibrate."</string>
@@ -506,7 +508,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Unlock to use"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"There was a problem getting your cards. Please try again later."</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Lock screen settings"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"Scan QR code"</string>
+ <string name="qr_code_scanner_title" msgid="1938155688725760702">"QR code scanner"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Work profile"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Aeroplane mode"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"You won\'t hear your next alarm <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -789,6 +791,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Magnify full screen"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Magnify part of screen"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Switch"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Allow diagonal scrolling"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Resize"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"Change magnification type"</string>
@@ -1019,4 +1023,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"Allow <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> to access all device logs?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"Allow one-time access"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Don’t allow"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"Device logs record what happens on your device. Apps can use these logs to find and fix issues.\n\nSome logs may contain sensitive info, so only allow apps that you trust to access all device logs. \n\nIf you don’t allow this app to access all device logs, it can still access its own logs. Your device manufacturer may still be able to access some logs or info on your device."</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index c23bfe607cb8..d036b882361c 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"Always allow from this computer"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"Allow"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"USB debugging not allowed"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"The user currently signed in to this device can\'t turn on USB debugging. To use this feature, switch to the primary user."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"The user currently signed in to this device can\'t turn on USB debugging. To use this feature, switch to an admin user."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Do you want to change the system language to <xliff:g id="LANGUAGE">%1$s</xliff:g>?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"System language change requested by another device"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Change language"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"Always allow on this network"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"Allow"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Wireless debugging not allowed"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"The user currently signed in to this device can’t turn on wireless debugging. To use this feature, switch to the primary user."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"The user currently signed in to this device can’t turn on wireless debugging. To use this feature, switch to an admin user."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"USB port disabled"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"To protect your device from liquid or debris, the USB port is disabled and won’t detect any accessories.\n\nYou’ll be notified when it’s OK to use the USB port again."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"USB port enabled to detect chargers and accessories"</string>
@@ -125,7 +125,7 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Voice Assist"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"QR code scanner"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"Unlock"</string>
+ <string name="accessibility_unlock_button" msgid="3613812140816244310">"Unlocked"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"Device locked"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Scanning face"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Send"</string>
@@ -168,7 +168,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"Can’t recognise face"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Use fingerprint instead"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth connected."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"Battery percentage unknown."</string>
@@ -180,8 +180,10 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"Aeroplane mode"</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN on."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"Battery <xliff:g id="NUMBER">%d</xliff:g> per cent."</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Battery <xliff:g id="PERCENTAGE">%1$s</xliff:g> percentage, about <xliff:g id="TIME">%2$s</xliff:g> left based on your usage"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Battery <xliff:g id="PERCENTAGE">%1$d</xliff:g> percentage, about <xliff:g id="TIME">%2$s</xliff:g> left based on your usage"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Battery charging, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> percent."</string>
+ <string name="accessibility_battery_level_charging_paused" msgid="1716051308782906917">"Battery <xliff:g id="PERCENTAGE">%d</xliff:g> per cent. Charging paused for battery protection."</string>
+ <string name="accessibility_battery_level_charging_paused_with_estimate" msgid="4006089349465741762">"Battery <xliff:g id="PERCENTAGE">%1$d</xliff:g> per cent, about <xliff:g id="TIME">%2$s</xliff:g> left based on your usage. Charging paused for battery protection."</string>
<string name="accessibility_overflow_action" msgid="8555835828182509104">"See all notifications"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"TeleTypewriter enabled."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Ringer vibrate."</string>
@@ -506,7 +508,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Unlock to use"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"There was a problem getting your cards. Please try again later."</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Lock screen settings"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"Scan QR code"</string>
+ <string name="qr_code_scanner_title" msgid="1938155688725760702">"QR code scanner"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Work profile"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Aeroplane mode"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"You won\'t hear your next alarm <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -789,6 +791,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Magnify full screen"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Magnify part of screen"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Switch"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Allow diagonal scrolling"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Resize"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"Change magnification type"</string>
@@ -1019,4 +1023,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"Allow <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> to access all device logs?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"Allow one-time access"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Don’t allow"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"Device logs record what happens on your device. Apps can use these logs to find and fix issues.\n\nSome logs may contain sensitive info, so only allow apps that you trust to access all device logs. \n\nIf you don’t allow this app to access all device logs, it can still access its own logs. Your device manufacturer may still be able to access some logs or info on your device."</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index 06b9f451827a..4896ad455b8e 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‏‏‎‎‎‏‏‎‏‏‏‏‏‎‎‏‎‎‎‎‏‎‎‏‎‎‏‎‏‎‎‎‏‏‎‎‏‏‎‏‏‏‏‎‏‎‏‏‎‎‏‎‏‏‏‎‎‎Always allow from this computer‎‏‎‎‏‎"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‏‏‏‏‎‏‎‎‎‎‎‎‎‏‏‏‏‎‏‏‏‎‏‏‎‎‎‏‏‏‏‏‏‏‎‎‎‎‎‏‎‏‏‏‏‏‏‎‎‏‏‏‏‎‎‎‎‎Allow‎‏‎‎‏‎"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‎‏‏‎‎‎‎‎‎‏‏‏‎‎‏‏‏‏‎‏‎‏‎‏‏‎‎‏‏‎‏‎‏‎‎‎‎‎‏‏‏‏‎‎‏‎‏‏‎‏‏‏‏‎‎USB debugging not allowed‎‏‎‎‏‎"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‏‏‏‏‎‏‎‎‎‎‏‏‎‎‎‏‎‏‎‎‎‏‎‏‏‎‏‏‎‏‎‏‏‎‎‏‏‏‏‏‎‎‎‎‏‎‎‏‎‏‎‏‎‏‏‎‎‎The user currently signed in to this device can\'t turn on USB debugging. To use this feature, switch to the primary user.‎‏‎‎‏‎"</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‎‎‎‏‏‎‏‏‎‎‏‏‏‏‏‏‎‎‎‎‎‏‏‏‏‎‎‎‏‎‏‎‎‏‎‏‏‎‎‏‏‎‏‏‏‏‎‏‏‎‏‏‏‎‏‎‏‎The user currently signed in to this device can\'t turn on USB debugging. To use this feature, switch to an admin user.‎‏‎‎‏‎"</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‏‎‏‏‏‏‎‏‏‏‎‎‏‎‏‎‏‏‏‏‏‏‎‎‏‏‎‎‏‏‏‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‏‏‏‏‎‎Do you want to change the system language to ‎‏‎‎‏‏‎<xliff:g id="LANGUAGE">%1$s</xliff:g>‎‏‎‎‏‏‏‎?‎‏‎‎‏‎"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‏‏‎‎‏‏‎‎‎‏‎‎‎‎‏‏‏‏‏‏‏‎‎‏‎‎‎‎‏‏‎‎‏‏‏‏‎‏‏‎‏‎‎‎‏‎‎‎‏‏‎‏‏‎System language change requested by another device‎‏‎‎‏‎"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‎‏‏‏‎‎‎‏‎‎‏‏‎‏‎‏‏‎‎‏‏‏‏‏‎‎‏‎‎‏‎‎‎‏‏‏‎‎‎‎‏‎‎‎‎‎‏‏‏‏‎‏‎‏‎‏‎‎Change language‎‏‎‎‏‎"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‏‎‎‏‏‎‎‎‏‏‏‎‏‎‎‎‏‎‏‎‏‎‏‏‎‏‎‏‎‎‏‏‏‎‏‎‎‏‎‏‏‎‎‎‏‎‎‏‎‎‏‏‏‎‎‏‏‎Always allow on this network‎‏‎‎‏‎"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‏‎‏‏‏‎‏‎‏‏‎‏‏‏‎‎‎‏‏‎‏‎‏‏‏‎‎‏‎‎‏‎‏‏‎‎‎‏‎‏‎‏‎‏‎‏‎‏‏‏‏‏‎‎Allow‎‏‎‎‏‎"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‎‏‎‎‏‏‎‎‏‏‎‏‎‎‎‎‏‏‎‎‎‏‎‎‎‎‏‏‎‎‎‏‏‎‏‎‏‎‏‏‎‏‎‎‎‎‎‎‎‎‏‎‏‏‏‎‏‎Wireless debugging not allowed‎‏‎‎‏‎"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‎‎‏‎‏‏‎‎‎‎‎‏‎‎‏‏‎‏‎‎‏‏‎‏‎‏‎‏‎‎‏‏‎‏‏‏‏‎‏‏‎‏‏‎‎‏‎‎‎‎‎‎‎‎‏‏‏‎The user currently signed in to this device can’t turn on wireless debugging. To use this feature, switch to the primary user.‎‏‎‎‏‎"</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‏‏‏‎‎‏‎‏‏‎‎‎‎‏‏‎‎‏‎‏‏‎‏‏‎‎‎‏‏‏‎‎‏‏‎‎‏‎‎‏‎‏‎‎‎‏‎‎‎‎‏‎The user currently signed in to this device can’t turn on wireless debugging. To use this feature, switch to an admin user.‎‏‎‎‏‎"</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‎‎‏‏‎‏‎‎‎‎‏‎‏‎‎‎‎‎‎‎‎‎‏‏‎‏‎‎‎‏‎‎‏‎‎‏‎‏‏‏‎‎‏‏‏‏‎‏‏‎‏‎‎‎‎‎‏‎USB port disabled‎‏‎‎‏‎"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‎‎‏‎‎‎‎‎‏‎‏‎‏‏‎‏‏‏‏‏‏‏‎‎‎‏‎‎‏‏‏‏‎‏‎‎‎‎‎‏‎‏‏‏‎‏‎‎‏‏‏‏‎‏‎To protect your device from liquid or debris, the USB port is disabled and won’t detect any accessories.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎You’ll be notified when it’s okay to use the USB port again.‎‏‎‎‏‎"</string>
<string name="usb_port_enabled" msgid="531823867664717018">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‏‎‏‏‎‎‎‎‏‎‏‏‎‏‎‏‎‏‏‏‏‏‏‎‏‎‏‏‎‏‎‏‏‎‎‏‏‏‎‏‎‏‏‎‏‎‏‎‎‏‏‎‏‏‎‏‎‎USB port enabled to detect chargers and accessories‎‏‎‎‏‎"</string>
@@ -125,7 +125,7 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‎‎‏‎‏‏‎‎‎‏‏‏‏‏‎‏‏‎‏‏‏‏‎‏‏‎‎‏‏‎‎‎‏‎‎‎‎‎‏‎‎‏‎‏‏‏‎‏‏‎‎‎‏‏‏‎‎Voice Assist‎‏‎‎‏‎"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‎‎‎‏‏‏‏‎‎‏‏‎‎‎‏‏‎‏‎‏‎‎‎‏‏‎‎‏‎‏‎‏‎‏‏‎‎‎‎‏‎‎‏‏‏‏‎‏‎‏‏‏‏‎‎‏‏‎Wallet‎‏‎‎‏‎"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‏‏‎‎‎‎‎‏‏‏‏‎‎‏‎‎‏‏‎‏‏‎‏‎‎‎‎‎‎‎‏‎‎‎‏‏‏‏‏‎‏‎‎‎‎‎‎‏‏‎‎‏‎‏‏‎QR Code Scanner‎‏‎‎‏‎"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‎‏‏‏‎‏‏‎‏‎‎‎‎‏‏‏‎‎‎‏‎‏‏‎‎‏‎‎‎‎‎‏‏‏‎‎‏‎‏‎‎‏‎‏‎‎‎‏‏‎‎‎‏‏‎‏‏‎‏‎Unlock‎‏‎‎‏‎"</string>
+ <string name="accessibility_unlock_button" msgid="3613812140816244310">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‎‎‎‏‎‎‏‏‎‏‏‎‏‎‏‏‎‏‏‏‏‏‏‏‎‏‏‎‎‏‎‏‎‎‏‎‏‏‎‎‎‏‎‎‏‏‏‏‎‎‏‎‏‎‏‏‎‎Unlocked‎‏‎‎‏‎"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‏‎‎‏‎‏‏‏‎‎‎‎‏‏‎‎‎‎‎‏‏‏‏‎‎‎‏‎‎‎‏‎‏‏‏‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‎‏‏‏‏‏‏‎Device locked‎‏‎‎‏‎"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‎‏‏‏‎‏‏‏‏‎‏‏‏‏‏‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‏‏‎‎‎‏‏‎‎‎‏‏‎‏‎‎‎‎‏‎‏‏‎Scanning face‎‏‎‎‏‎"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‎‏‏‎‏‏‏‏‏‏‎‎‏‏‎‏‏‎‎‏‏‏‏‎‎‏‎‎‏‎‎‏‏‎‏‎‏‎‎‎‎‏‎‎‏‏‎‏‎‎‏‎‏‎Send‎‏‎‎‏‎"</string>
@@ -168,7 +168,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‏‎‎‏‏‏‏‎‎‎‏‎‎‏‎‎‏‏‏‎‎‏‏‎‎‎‎‏‎‎‎‎‏‏‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‏‏‎Can’t recognize face‎‏‎‎‏‎"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‏‎‎‎‏‏‏‏‎‎‎‎‏‎‎‏‏‎‎‏‏‎‏‎‎‎‎‎‏‏‎‎‏‎‏‎‎‏‏‏‎‏‎‎‎‎‏‏‏‎‎‎‎‎Use fingerprint instead‎‏‎‎‏‎"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‏‎‏‏‎‏‎‎‏‎‏‎‎‏‏‎‏‏‎‏‎‏‎‏‎‎‏‎‎‎‎‏‏‏‎‏‎‎‏‏‎‏‏‏‏‎‏‏‏‎‎‎‏‎‏‎Bluetooth connected.‎‏‎‎‏‎"</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‏‎‎‎‏‎‏‏‎‏‎‎‎‏‏‏‏‎‎‎‎‎‏‎‏‏‎‎‏‎‏‏‏‏‎‏‎‏‎‏‎‏‎‎‎‎‏‏‎‎‏‏‏‏‎‎‎‎Battery percentage unknown.‎‏‎‎‏‎"</string>
@@ -180,8 +180,10 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‎‎‏‎‏‏‏‎‎‎‏‏‏‏‎‏‏‏‏‎‎‎‎‎‏‏‎‎‎‏‎‏‏‏‎‏‏‎‎‎‎‎‏‎‎‏‏‎‏‏‎‏‎‏‎‎‏‎Airplane mode.‎‏‎‎‏‎"</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‎‎‏‎‏‏‎‎‎‏‏‏‎‎‏‏‎‏‏‏‎‏‎‎‏‎‎‎‏‎‎‎‎‎‏‎‏‏‎‎‏‎‏‎‎‎‎‎‎‏‏‎‏‏‎VPN on.‎‏‎‎‏‎"</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‏‎‏‏‎‎‎‏‎‎‎‏‎‎‏‎‏‏‏‏‎‏‎‎‎‏‎‎‏‎‎‏‏‎‎‎‏‏‎‏‎‎‎‏‏‏‏‏‎‏‎‎‎‎‏‏‎‎Battery ‎‏‎‎‏‏‎<xliff:g id="NUMBER">%d</xliff:g>‎‏‎‎‏‏‏‎ percent.‎‏‎‎‏‎"</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎‎‏‏‎‏‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‏‎‏‏‎‏‎‏‎‎‎‏‎‏‏‎‎‎‏‎‎‎‎‎‎‎‎‏‎‏‏‏‎‎‎Battery ‎‏‎‎‏‏‎<xliff:g id="PERCENTAGE">%1$s</xliff:g>‎‏‎‎‏‏‏‎ percent, about ‎‏‎‎‏‏‎<xliff:g id="TIME">%2$s</xliff:g>‎‏‎‎‏‏‏‎ left based on your usage‎‏‎‎‏‎"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎‎‏‏‎‏‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‏‎‏‏‎‏‎‏‎‎‎‏‎‏‏‎‎‎‏‎‎‎‎‎‎‎‎‏‎‏‏‏‎‎‎Battery ‎‏‎‎‏‏‎<xliff:g id="PERCENTAGE">%1$d</xliff:g>‎‏‎‎‏‏‏‎ percent, about ‎‏‎‎‏‏‎<xliff:g id="TIME">%2$s</xliff:g>‎‏‎‎‏‏‏‎ left based on your usage‎‏‎‎‏‎"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‎‏‏‏‎‏‏‎‏‎‎‎‏‏‎‎‎‎‏‏‎‏‏‎‏‎‏‎‎‎‎‏‎‏‎‏‎‏‎‏‎‎‏‎‎‏‏‎‎‏‎‎‎Battery charging, ‎‏‎‎‏‏‎<xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>‎‏‎‎‏‏‏‎ percent.‎‏‎‎‏‎"</string>
+ <string name="accessibility_battery_level_charging_paused" msgid="1716051308782906917">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‏‏‏‎‏‎‎‎‎‏‎‏‎‎‎‏‏‏‎‎‏‎‎‏‎‏‏‎‎‎‏‎‎‎‏‎‏‏‎‎‏‎‏‏‎‏‏‏‎‎‎‏‎‎‏‎‏‎Battery ‎‏‎‎‏‏‎<xliff:g id="PERCENTAGE">%d</xliff:g>‎‏‎‎‏‏‏‎ percent. Charging paused for battery protection.‎‏‎‎‏‎"</string>
+ <string name="accessibility_battery_level_charging_paused_with_estimate" msgid="4006089349465741762">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‏‏‎‎‏‏‎‎‎‎‏‏‏‏‏‎‏‎‎‎‎‏‎‎‏‏‏‎‎‎‏‎‏‎‏‏‎‎‎‎‏‏‎‎‏‏‎‎‏‏‏‎‎‎‎‏‎‎Battery ‎‏‎‎‏‏‎<xliff:g id="PERCENTAGE">%1$d</xliff:g>‎‏‎‎‏‏‏‎ percent, about ‎‏‎‎‏‏‎<xliff:g id="TIME">%2$s</xliff:g>‎‏‎‎‏‏‏‎ left based on your usage. Charging paused for battery protection.‎‏‎‎‏‎"</string>
<string name="accessibility_overflow_action" msgid="8555835828182509104">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‏‏‏‎‎‎‏‏‎‏‏‏‏‎‏‎‏‏‎‏‎‏‏‎‏‏‏‏‏‎‏‏‎‎‎‎‎‏‏‏‎‎‏‏‎‎‎‏‏‎‎‎‎‎See all notifications‎‏‎‎‏‎"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‏‏‎‎‏‎‏‏‎‎‏‎‏‎‏‏‎‏‎‎‏‏‏‎‎‏‏‎‏‏‏‏‎‏‎‎‎‎‎‎‎‏‎‏‏‎‏‎‎‎‏‏‏‏‏‏‎‎TeleTypewriter enabled.‎‏‎‎‏‎"</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‏‏‎‎‏‏‎‏‎‎‎‎‏‏‏‎‏‎‏‏‏‏‎‎‏‎‎‎‏‏‏‎‎‏‏‎‏‎‎‏‎‏‎‎‏‎‎‏‏‎‏‎‏‎‎‎Ringer vibrate.‎‏‎‎‏‎"</string>
@@ -506,7 +508,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‏‏‏‎‏‎‏‎‎‎‏‎‏‏‎‏‏‎‎‎‏‎‏‎‏‎‏‏‎‎‎‎‎‎‏‏‎‎‏‏‏‎‏‎‏‏‏‏‎‏‎‎‎‏‎‏‎‎Unlock to use‎‏‎‎‏‎"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‏‏‎‎‏‎‎‏‏‏‎‎‎‏‏‎‎‏‏‏‏‎‎‎‎‏‏‏‏‎‎‏‎‏‏‎‎‎‎‎‎‎‎‎‏‎‎‎‏‏‎‎‏‏‎‏‏‎There was a problem getting your cards, please try again later‎‏‎‎‏‎"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‏‎‎‎‏‏‏‎‏‎‏‏‎‏‏‎‏‏‎‎‎‎‏‎‏‎‎‏‎‏‎‎‏‎‎‎‏‎‏‎‎‏‏‎‎‎‏‏‏‏‏‎‏‎‎‏‎‎Lock screen settings‎‏‎‎‏‎"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‏‎‏‏‎‏‎‏‎‏‎‎‏‎‎‎‏‏‏‎‏‎‏‎‎‎‏‏‎‏‏‏‎‏‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‎‎‏‎Scan QR code‎‏‎‎‏‎"</string>
+ <string name="qr_code_scanner_title" msgid="1938155688725760702">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‎‏‏‏‎‎‏‎‏‏‎‏‏‎‏‏‎‎‏‎‏‎‏‎‎‏‎‎‎‎‎‎‏‏‏‏‎‎‏‏‎‏‏‎‎‏‎‏‎‏‎‏‏‏‏‏‎‎QR code scanner‎‏‎‎‏‎"</string>
<string name="status_bar_work" msgid="5238641949837091056">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‎‏‏‎‎‏‏‎‏‏‎‎‏‎‏‎‎‎‏‏‎‎‏‎‎‎‎‏‏‎‏‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‏‏‎‎‎‎‎Work profile‎‏‎‎‏‎"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎‏‎‎‏‎‏‎‎‎‎‎‏‏‎‏‎‎‏‏‏‏‎‏‏‏‏‏‏‎‏‏‏‎‏‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‎‎‎‏‎Airplane mode‎‏‎‎‏‎"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‎‏‏‏‎‎‏‎‎‏‎‎‎‎‎‎‏‏‏‏‎‎‎‎‎‎‏‎‎‎‎‏‏‏‎‏‎‎‎‏‏‏‎‏‏‏‏‏‎‏‏‏‏‏‎You won\'t hear your next alarm ‎‏‎‎‏‏‎<xliff:g id="WHEN">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
@@ -789,6 +791,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‎‎‏‎‎‏‏‎‏‏‏‎‏‏‎‎‎‏‎‏‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‏‎‏‎‎‏‎‏‎‏‏‏‎‏‎‎‎‎‎‏‎Magnify full screen‎‏‎‎‏‎"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‎‏‏‏‏‎‎‎‎‏‎‎‏‎‎‏‎‎‎‎‎‏‎‏‎‏‎‏‏‎‏‏‏‏‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‏‎‏‎Magnify part of screen‎‏‎‎‏‎"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‎‏‎‏‎‏‎‏‎‏‎‎‏‎‏‎‏‎‏‎‏‎‎‏‏‏‎‎‏‏‎‏‏‏‎‎‎‎‎‏‎‎‎‏‏‎‎‎‏‏‏‎‏‎‏‏‏‎Switch‎‏‎‎‏‎"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‏‎‎‏‏‎‏‏‎‏‏‏‎‏‎‏‏‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‏‏‏‎‎‏‎‏‏‎‎‎‎‎‏‎‏‏‎‎‏‏‏‎‎Allow diagonal scrolling‎‏‎‎‏‎"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‏‎‎‏‎‎‏‎‎‏‏‎‎‏‏‏‏‎‎‎‏‏‏‎‎‏‎‏‎‏‎‎‏‎‏‏‏‎‏‎‏‏‎‏‏‎‏‎‏‏‎‏‏‏‏‏‎Resize‎‏‎‎‏‎"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‏‎‎‏‏‏‏‏‎‎‎‎‏‏‎‏‏‏‎‎‎‏‏‎‎‎‏‏‏‏‎‏‏‎‏‏‎‏‎‏‏‏‎‎‏‏‎‎‎‎‏‏‎‎‏‎‏‎Change magnification type‎‏‎‎‏‎"</string>
@@ -1019,4 +1023,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‏‎‏‎‏‏‎‏‎‎‎‏‎‏‎‎‎‎‎‏‎‎‏‎‎‏‏‎‎‏‏‎‎‎‏‏‏‎‏‎‎‎‏‏‏‏‏‎‎‎‎‎‏‎‎‎‎EEE, MMM d‎‏‎‎‏‎"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‎‎‏‏‎‏‎‎‏‏‏‏‎‏‏‎‏‎‎‎‎‏‎‎‏‎‏‎‏‎‏‎‏‏‎‎‎‎‏‎‏‎‎‏‏‏‏‎‏‎‎‏‎‎‏‎h:mm‎‏‎‎‏‎"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‎‏‏‎‏‏‎‎‏‎‏‏‎‏‎‎‎‏‏‎‏‎‏‏‎‏‏‎‏‎‎‏‎‏‎‎‏‎‏‎‏‎‎‏‏‏‎‎‏‏‎‏‏‎‏‎kk:mm‎‏‎‎‏‎"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎‎‏‏‎‏‏‏‏‏‎‎‎‏‎‏‏‏‏‏‏‎‏‎‏‎‏‎‏‏‏‏‏‎‏‎‏‎‏‎‏‎‎‎‏‎‏‏‏‏‏‎‎‎‏‏‎Allow ‎‏‎‎‏‏‎<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g>‎‏‎‎‏‏‏‎ to access all device logs?‎‏‎‎‏‎"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‎‎‏‏‏‎‎‎‎‎‎‏‎‏‎‏‎‎‏‏‏‏‏‏‎‏‎‏‏‏‏‎‎‏‏‎‏‎‏‎‏‎‎‏‎‎‎‎‏‎‎‎‏‏‎‎‎‎Allow one-time access‎‏‎‎‏‎"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‏‎‎‏‎‏‎‎‏‎‎‎‏‎‎‏‎‏‎‎‏‎‎‏‎‎‎‎‎‏‏‎‏‏‏‎‏‏‎‎‎‏‎‏‎‎‏‎‏‎‎‎‎‎‎‏‏‎Don’t allow‎‏‎‎‏‎"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‎‎‎‎‏‎‏‎‏‏‏‎‎‎‏‎‎‎‎‏‏‏‎‎‏‎‏‏‏‎‎‏‎‎‏‏‏‏‏‏‎‎‎‏‏‏‎‏‎‏‏‏‎‏‎‎Device logs record what happens on your device. Apps can use these logs to find and fix issues.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Some logs may contain sensitive info, so only allow apps you trust to access all device logs. ‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎If you don’t allow this app to access all device logs, it can still access its own logs. Your device manufacturer may still be able to access some logs or info on your device.‎‏‎‎‏‎"</string>
</resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index d6f9a5e4733f..247f74e486aa 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"Permitir siempre desde esta computadora"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"Permitir"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"No tienes permitida la depuración por USB"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"El usuario al que accediste en este dispositivo no puede activar la depuración por USB. Para usar esta función, debes cambiar al usuario principal."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"El usuario al que accediste en este dispositivo no puede activar la depuración por USB. Para usar esa función, debes cambiar a un usuario administrador."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"¿Quiere cambiar el idioma del sistema a <xliff:g id="LANGUAGE">%1$s</xliff:g>?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Cambio de idioma del sistema solicitado por otro dispositivo"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Cambiar idioma"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"Permitir siempre en esta red"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"Permitir"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"No tienes permitida la depuración inalámbrica"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"El usuario al que accediste en este dispositivo no puede activar la depuración inalámbrica. Para usar esta función, debes cambiar al usuario principal."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"El usuario al que accediste en este dispositivo no puede activar la depuración inalámbrica. Para usar esa función, debes cambiar a un usuario administrador."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"Puerto USB inhabilitado"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"Para proteger tu dispositivo de líquidos o suciedad, el puerto USB está inhabilitado y no detectará ningún accesorio.\n\nTe avisaremos cuando puedas usar el puerto USB de nuevo."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"Se habilitó el puerto USB para detectar cargadores y accesorios"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Asistente voz"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Billetera"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"Escáner de código QR"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"Desbloquear"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"Dispositivo bloqueado"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Escaneando rostro"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Enviar"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"No se reconoce el rostro"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Usa la huella dactilar"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth conectado"</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"Se desconoce el porcentaje de la batería."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"Modo de avión"</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN activada"</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"Batería <xliff:g id="NUMBER">%d</xliff:g> por ciento"</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Batería: <xliff:g id="PERCENTAGE">%1$s</xliff:g> por ciento; tiempo restante: aproximadamente <xliff:g id="TIME">%2$s</xliff:g> en función del uso"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Batería: <xliff:g id="PERCENTAGE">%1$d</xliff:g> por ciento; tiempo restante: aproximadamente <xliff:g id="TIME">%2$s</xliff:g> en función del uso"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Batería cargando: <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%"</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"Ver todas las notificaciones"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"Teletipo habilitado"</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Timbre en vibración"</string>
@@ -386,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Cuando compartas, grabes o transmitas una app, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> podrá acceder a todo el contenido que se muestre o reproduzca en ella. Por lo tanto, debes tener cuidado con contraseñas, detalles de pagos, mensajes y otra información sensible."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Continuar"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Compartir o grabar una app"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"¿Quieres permitir que esta app comparta o grabe tu pantalla?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Cuando compartas, grabes o transmitas contenido, esta app podrá acceder a todo lo que sea visible en la pantalla o que reproduzcas en el dispositivo. Por lo tanto, debes tener cuidado con contraseñas, detalles de pagos, mensajes y otra información sensible que pueda estar visible."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Cuando compartas, grabes o transmitas una app, esta app podrá acceder a todo el contenido que se muestre o reproduzca en ella. Por lo tanto, debes tener cuidado con contraseñas, detalles de pagos, mensajes y otra información sensible que pueda estar visible."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Bloqueada por tu administrador de TI"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"La captura de pantalla está inhabilitada debido a la política del dispositivo"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Borrar todo"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Administrar"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Historial"</string>
@@ -511,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Desbloquear para usar"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Ocurrió un problema al obtener las tarjetas; vuelve a intentarlo más tarde"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Configuración de pantalla de bloqueo"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"Escanear QR"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Perfil de trabajo"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Modo de avión"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"No oirás la próxima alarma a la(s) <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -794,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Ampliar pantalla completa"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Ampliar parte de la pantalla"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Interruptor"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Permitir desplazamiento en diagonal"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Cambiar tamaño"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"Cambiar tipo de ampliación"</string>
@@ -1024,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d de MMM"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"¿Quieres permitir que <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> acceda a todos los registros del dispositivo?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"Permitir acceso por única vez"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"No permitir"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"Los registros del dispositivo permiten documentar lo que sucede en él. Las apps pueden usar estos registros para encontrar y solucionar problemas.\n\nEs posible que algunos registros del dispositivo contengan información sensible, por lo que solo permitimos que accedan a todos ellos apps de tu confianza. \n\nSi no permites que esta app acceda a todos los registros del dispositivo, aún puede acceder a sus propios registros. Además, es posible que el fabricante del dispositivo acceda a algunos registros o información en tu dispositivo."</string>
</resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 9480e4c9a857..615aa4c145ac 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"Permitir siempre desde este ordenador"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"Permitir"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"Depuración USB no permitida"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"El usuario con el que se ha iniciado sesión en este dispositivo no puede activar la depuración USB. Para utilizar esta función, inicia sesión con la cuenta de usuario principal."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"El usuario con el que se ha iniciado sesión en este dispositivo no puede activar la depuración por USB. Para usar esta función, inicia sesión con la cuenta de un usuario administrador."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"¿Quieres cambiar el idioma del sistema a <xliff:g id="LANGUAGE">%1$s</xliff:g>?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Otro dispositivo ha solicitado un cambio en el idioma del sistema"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Cambiar idioma"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"Permitir siempre en esta red"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"Permitir"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Depuración inalámbrica no permitida"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"El usuario con el que se ha iniciado sesión en este dispositivo no puede activar la depuración inalámbrica. Para utilizar esta función, inicia sesión con la cuenta de usuario principal."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"El usuario con el que se ha iniciado sesión en este dispositivo no puede activar la depuración inalámbrica. Para usar esta función, inicia sesión con la cuenta de un usuario administrador."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"Puerto USB inhabilitado"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"Para proteger tu dispositivo de los líquidos y la suciedad, el puerto USB se ha inhabilitado y no detectará ningún accesorio.\n\nRecibirás una notificación cuando puedas volver a usarlo."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"Puerto USB habilitado para detectar cargadores y accesorios"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Asistente voz"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"Escáner de códigos QR"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"Desbloquear"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"Dispositivo bloqueado"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Escaneando cara"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Enviar"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"No se reconoce la cara"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Usa la huella digital"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth conectado"</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"Porcentaje de batería desconocido."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"Modo Avión"</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"La red VPN está activada."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"<xliff:g id="NUMBER">%d</xliff:g> por ciento de batería"</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Queda un <xliff:g id="PERCENTAGE">%1$s</xliff:g> por ciento de batería (<xliff:g id="TIME">%2$s</xliff:g> aproximadamente según tu uso)"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Queda un <xliff:g id="PERCENTAGE">%1$d</xliff:g> por ciento de batería (<xliff:g id="TIME">%2$s</xliff:g> aproximadamente según tu uso)"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Batería cargándose (<xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> %%)."</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"Ver todas las notificaciones"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"Teletipo habilitado"</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Modo vibración"</string>
@@ -386,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Cuando compartas, grabes o envíes una aplicación, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> podrá acceder a todo lo que muestre o reproduzca la aplicación. Debes tener cuidado con contraseñas, detalles de pagos, mensajes o cualquier otra información sensible."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Continuar"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Compartir o grabar una aplicación"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"¿Permitir que esta aplicación que comparta o grabe contenido?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Cuando compartas, grabes o envíes contenido, esta aplicación podrá acceder a todo lo que se vea en tu pantalla o reproduzcas en tu dispositivo. Debes tener cuidado con contraseñas, detalles de pagos, mensajes o cualquier otra información sensible."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Cuando compartas, grabes o envíes contenido, esta aplicación podrá acceder a todo lo que se muestre o reproduzca en ella. Debes tener cuidado con contraseñas, detalles de pagos, mensajes o cualquier otra información sensible."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Bloqueadas por tu administrador de TI"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"Las capturas de pantalla están inhabilitadas debido a la política de dispositivos"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Borrar todo"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Gestionar"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Historial"</string>
@@ -511,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Desbloquear para usar"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Se ha producido un problema al obtener tus tarjetas. Inténtalo de nuevo más tarde."</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Ajustes de pantalla de bloqueo"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"Escanear código QR"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Perfil de trabajo"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Modo Avión"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"No oirás la próxima alarma (<xliff:g id="WHEN">%1$s</xliff:g>)"</string>
@@ -794,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Ampliar pantalla completa"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Ampliar parte de la pantalla"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Cambiar"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Permitir desplazamiento en diagonal"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Cambiar tamaño"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"Cambiar tipo de ampliación"</string>
@@ -1024,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"¿Permitir que <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> acceda a todos los registros del dispositivo?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"Permitir el acceso una vez"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"No permitir"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"Los registros del dispositivo documentan lo que sucede en tu dispositivo. Las aplicaciones pueden usar estos registros para encontrar y solucionar problemas.\n\nComo algunos registros pueden contener información sensible, es mejor que solo permitas que accedan a ellos las aplicaciones en las que confíes. \n\nAunque no permitas que esta aplicación acceda a todos los registros del dispositivo, aún podrá acceder a sus propios registros. El fabricante de tu dispositivo aún puede acceder a algunos registros o información de tu dispositivo."</string>
</resources>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index c5ac0c7f4153..d46694e71431 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"Luba alati sellest arvutist"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"Luba"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"USB-silumine pole lubatud"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"Sellesse seadmesse praegu sisse logitud kasutaja ei saa USB-silumist sisse lülitada. Selle funktsiooni kasutamiseks vahetage peamisele kasutajale."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"Sellesse seadmesse praegu sisse logitud kasutaja ei saa USB-silumist sisse lülitada. Selle funktsiooni kasutamiseks vahetage administraatoriõigustega kasutajale."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Kas soovite süsteemi keeleks määrata järgmise: <xliff:g id="LANGUAGE">%1$s</xliff:g>?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Teine seade taotles süsteemi keele muutmist"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Muuda keelt"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"Luba selles võrgus alati"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"Luba"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Juhtmevaba silumine pole lubatud"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"Sellesse seadmesse praegu sisse logitud kasutaja ei saa juhtmevaba silumist sisse lülitada. Selle funktsiooni kasutamiseks vahetage peamisele kasutajale."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"Sellesse seadmesse praegu sisse logitud kasutaja ei saa juhtmevaba silumist sisse lülitada. Selle funktsiooni kasutamiseks vahetage administraatoriõigustega kasutajale."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"USB-port on keelatud"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"Selleks et kaitsta teie seadet vedeliku või mustuse eest, on USB-port keelatud ja see ei tuvasta lisatarvikuid.\n\nKui USB-porti tohib taas kasutada, saate selle kohta märguande."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"USB-pordil on lubatud tuvastada laadijaid ja tarvikuid"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Häälabi"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"QR-koodi skanner"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"Luku avamine"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"Seade on lukustatud"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Näo skannimine"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Saada"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"Nägu ei õnnestu tuvastada"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Kasutage sõrmejälge"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth on ühendatud."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"Aku laetuse protsent on teadmata."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"Lennukirežiim."</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN on sees."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"Aku: <xliff:g id="NUMBER">%d</xliff:g> protsenti."</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Aku protsent <xliff:g id="PERCENTAGE">%1$s</xliff:g>, teie kasutuse põhjal on jäänud ligikaudu <xliff:g id="TIME">%2$s</xliff:g>"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Aku protsent <xliff:g id="PERCENTAGE">%1$d</xliff:g>, teie kasutuse põhjal on jäänud ligikaudu <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Akut laetakse (<xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%)."</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"Kõikide märguannete kuvamine"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"TeleTypewriter lubatud."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Vibreeriv kõlisti."</string>
@@ -305,28 +310,17 @@
<string name="sensor_privacy_mic_unblocked_toast_content" msgid="306555320557065068">"Mikrofon on saadaval"</string>
<string name="sensor_privacy_camera_unblocked_toast_content" msgid="7843105715964332311">"Kaamera on saadaval"</string>
<string name="sensor_privacy_mic_camera_unblocked_toast_content" msgid="7339355093282661115">"Mikrofon ja kaamera on saadaval"</string>
- <!-- no translation found for sensor_privacy_mic_turned_on_dialog_title (6348853159838376513) -->
- <skip />
- <!-- no translation found for sensor_privacy_mic_turned_off_dialog_title (5760464281790732849) -->
- <skip />
- <!-- no translation found for sensor_privacy_mic_unblocked_dialog_content (4889961886199270224) -->
- <skip />
- <!-- no translation found for sensor_privacy_mic_blocked_no_exception_dialog_content (5864898470772965394) -->
- <skip />
- <!-- no translation found for sensor_privacy_mic_blocked_with_exception_dialog_content (810289713700437896) -->
- <skip />
- <!-- no translation found for sensor_privacy_camera_turned_on_dialog_title (8039095295100075952) -->
- <skip />
- <!-- no translation found for sensor_privacy_camera_turned_off_dialog_title (1936603903120742696) -->
- <skip />
- <!-- no translation found for sensor_privacy_camera_unblocked_dialog_content (7847190103011782278) -->
- <skip />
- <!-- no translation found for sensor_privacy_camera_blocked_dialog_content (3182428709314874616) -->
- <skip />
- <!-- no translation found for sensor_privacy_htt_blocked_dialog_content (3333321592997666441) -->
- <skip />
- <!-- no translation found for sensor_privacy_dialog_open_settings (1503088305279285048) -->
- <skip />
+ <string name="sensor_privacy_mic_turned_on_dialog_title" msgid="6348853159838376513">"Mikrofon lülitati sisse"</string>
+ <string name="sensor_privacy_mic_turned_off_dialog_title" msgid="5760464281790732849">"Mikrofon lülitati välja"</string>
+ <string name="sensor_privacy_mic_unblocked_dialog_content" msgid="4889961886199270224">"Mikrofon on kõigi rakenduste ja teenuste jaoks lubatud."</string>
+ <string name="sensor_privacy_mic_blocked_no_exception_dialog_content" msgid="5864898470772965394">"Juurdepääs mikrofonile on kõigi rakenduste ja teenuste jaoks keelatud. Saate juurdepääsu mikrofonile lubada, tehes valikud Seaded &gt; Privaatsus &gt; Mikrofon."</string>
+ <string name="sensor_privacy_mic_blocked_with_exception_dialog_content" msgid="810289713700437896">"Juurdepääs mikrofonile on kõigi rakenduste ja teenuste jaoks keelatud. Saate seda muuta valikutega Seaded &gt; Privaatsus &gt; Mikrofon."</string>
+ <string name="sensor_privacy_camera_turned_on_dialog_title" msgid="8039095295100075952">"Kaamera lülitati sisse"</string>
+ <string name="sensor_privacy_camera_turned_off_dialog_title" msgid="1936603903120742696">"Kaamera lülitati välja"</string>
+ <string name="sensor_privacy_camera_unblocked_dialog_content" msgid="7847190103011782278">"Kaamera on kõigi rakenduste ja teenuste jaoks lubatud."</string>
+ <string name="sensor_privacy_camera_blocked_dialog_content" msgid="3182428709314874616">"Juurdepääs kaamerale on kõigi rakenduste ja teenuste jaoks keelatud."</string>
+ <string name="sensor_privacy_htt_blocked_dialog_content" msgid="3333321592997666441">"Mikrofoninupu kasutamiseks lubage seadetes juurdepääs mikrofonile."</string>
+ <string name="sensor_privacy_dialog_open_settings" msgid="1503088305279285048">"Avage seaded."</string>
<string name="media_seamless_other_device" msgid="4654849800789196737">"Muu seade"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Lehe Ülevaade sisse- ja väljalülitamine"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Helid ja värinad ei sega teid. Kuulete siiski enda määratud äratusi, meeldetuletusi, sündmusi ja helistajaid. Samuti kuulete kõike, mille esitamise ise valite, sh muusika, videod ja mängud."</string>
@@ -397,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Kui jagate, salvestate või kannate rakendust üle, on rakendusel <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> juurdepääs kõigele, mida selles rakenduses kuvatakse või esitatakse. Seega olge paroolide, makseteabe, sõnumite ja muu tundliku teabega ettevaatlik."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Jätka"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Rakenduse jagamine või salvestamine"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Kas lubada sellel rakendusel jagada või salvestada?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Kui jagate, salvestate või kannate üle, on selle rakendusel juurdepääs kõigele, mis on teie ekraanikuval nähtaval või mida teie seadmes esitatakse. Seega olge paroolide, makseteabe, sõnumite ja muu tundliku teabega ettevaatlik."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Kui jagate, salvestate või kannate rakendust üle, on sellel rakendusel juurdepääs kõigele, mida selles rakenduses kuvatakse või esitatakse. Seega olge paroolide, makseteabe, sõnumite ja muu tundliku teabega ettevaatlik."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Blokeeris teie IT-administraator"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"Ekraanikuva jäädvustamine on seadmereeglitega keelatud"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Tühjenda kõik"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Haldamine"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Ajalugu"</string>
@@ -522,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Avage kasutamiseks"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Teie kaartide hankimisel ilmnes probleem, proovige hiljem uuesti"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Lukustuskuva seaded"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"QR-koodi skannimine"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Tööprofiil"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Lennukirežiim"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Te ei kuule järgmist äratust kell <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -805,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Täisekraani suurendamine"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Ekraanikuva osa suurendamine"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Vaheta"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Luba diagonaalne kerimine"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Muuda suurust"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"Muuda suurenduse tüüpi"</string>
@@ -1035,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d. MMM"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"Kas anda rakendusele <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> juurdepääs kõigile seadmelogidele?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"Luba ühekordne juurdepääs"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Ära luba"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"Seadmelogid jäädvustavad, mis teie seadmes toimub. Rakendused saavad neid logisid kasutada probleemide tuvastamiseks ja lahendamiseks.\n\nMõned logid võivad sisaldada tundlikku teavet, seega lubage juurdepääs kõigile seadmelogidele ainult rakendustele, mida usaldate. \n\nKui te ei luba sellel rakendusel kõigile seadmelogidele juurde pääseda, pääseb see siiski juurde oma logidele. Teie seadme tootja võib teie seadmes siiski teatud logidele või teabele juurde pääseda."</string>
</resources>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 24618865caee..3af8ce6c6657 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"Eman beti ordenagailu honetatik arazteko baimena"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"Eman baimena"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"Ez da onartzen USB bidezko arazketa"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"Gailu honetan saioa hasita daukan erabiltzaileak ezin du aktibatu USB bidezko arazketa. Eginbide hori erabiltzeko, aldatu erabiltzaile nagusira."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"Gailu honetan saioa hasita daukan erabiltzaileak ezin du aktibatu USB bidezko arazketa. Eginbide hori erabiltzeko, aldatu administratzailea den erabiltzaile batera."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Hizkuntza honetara aldatu nahi duzu sistemaren hizkuntza: <xliff:g id="LANGUAGE">%1$s</xliff:g>?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Beste gailu batek sistemaren hizkuntza aldatzeko eskatu du"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Aldatu hizkuntza"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"Eman baimena beti sare honetan"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"Eman baimena"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Ez da onartzen hari gabeko arazketa"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"Gailu honetan saioa hasita daukan erabiltzaileak ezin du aktibatu hari gabeko arazketa. Eginbide hori erabiltzeko, aldatu erabiltzaile nagusira."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"Gailu honetan saioa hasita daukan erabiltzaileak ezin du aktibatu hari gabeko arazketa. Eginbide hori erabiltzeko, aldatu administratzailea den erabiltzaile batera."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"Desgaitu egin da USB ataka"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"USB ataka desgaitu egin da gailua likido edo zikinkeriengandik babesteko, eta ez du hautemango osagarririk.\n\nJakinarazpen bat jasoko duzu USB ataka berriz erabiltzeko moduan dagoenean."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"USB ataka gaitu da kargagailuak eta osagarriak hautemateko"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Ahots-laguntza"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Diru-zorroa"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"QR kodeen eskanerra"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"Desblokeatu"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"Gailua blokeatuta dago"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Aurpegia eskaneatzen"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Bidali"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"Ezin da ezagutu aurpegia"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Erabili hatz-marka"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetootha konektatuta."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"Bateriaren ehunekoa ezezaguna da."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"Hegaldi-modua"</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN eginbidea aktibatuta."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"Bateriaren karga: <xliff:g id="NUMBER">%d</xliff:g>."</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Bateriak ehuneko <xliff:g id="PERCENTAGE">%1$s</xliff:g> dauka kargatuta. Zure erabilera kontuan izanda, <xliff:g id="TIME">%2$s</xliff:g> inguru gelditzen zaizkio."</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Bateriak ehuneko <xliff:g id="PERCENTAGE">%1$d</xliff:g> dauka kargatuta. Zure erabilera kontuan izanda, <xliff:g id="TIME">%2$s</xliff:g> inguru gelditzen zaizkio."</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Kargatzen ari da bateria. Ehuneko <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> arte kargatu da oraingoz."</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"Ikusi jakinarazpen guztiak"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"TeleTypewriter gaituta."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Tonu-jotzailea dardara moduan."</string>
@@ -386,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Aplikazio bat partekatzen, grabatzen edo igortzen ari zarenean, aplikazio horretan ikusgai dagoen edo bertan erreproduzitzen ari den guztirako sarbidea du <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> aplikazioak. Beraz, kontuz ibili pasahitzekin, ordainketen xehetasunekin, mezuekin edo bestelako kontuzko informazioarekin."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Egin aurrera"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Partekatu edo grabatu aplikazioak"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Edukia partekatzeko edo grabatzeko baimena eman nahi diozu aplikazioari?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Edukia partekatzen, grabatzen edo igortzen ari zarenean, pantailan ikusgai dagoen edo gailuan erreproduzitzen ari den guztirako sarbidea du aplikazioak. Beraz, kontuz ibili pasahitzekin, ordainketen xehetasunekin, mezuekin edo bestelako kontuzko informazioarekin."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Aplikazio bat partekatzen, grabatzen edo igortzen ari zarenean, aplikazio horretan ikusgai dagoen edo bertan erreproduzitzen ari den guztirako sarbidea du aplikazioak. Beraz, kontuz ibili pasahitzekin, ordainketen xehetasunekin, mezuekin edo bestelako kontuzko informazioarekin."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"IKT saileko administratzaileak blokeatu du"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"Pantaila-kapturak egiteko aukera desgaituta dago, gailu-gidalerroei jarraikiz"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Garbitu guztiak"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Kudeatu"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Historia"</string>
@@ -511,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Desblokeatu erabiltzeko"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Arazo bat izan da txartelak eskuratzean. Saiatu berriro geroago."</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Pantaila blokeatuaren ezarpenak"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"Eskaneatu QR kodea"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Work profila"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Hegaldi modua"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Ez duzu entzungo hurrengo alarma (<xliff:g id="WHEN">%1$s</xliff:g>)"</string>
@@ -794,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Handitu pantaila osoa"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Handitu pantailaren zati bat"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Botoia"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Eman diagonalki gora eta behera egiteko aukera erabiltzeko baimena"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Aldatu tamaina"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"Aldatu lupa mota"</string>
@@ -1024,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"Gailuko erregistro guztiak atzitzeko baimena eman nahi diozu <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> aplikazioari?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"Eman behin erabiltzeko baimena"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Ez eman baimenik"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"Gailuko erregistroetan gailuan gertatzen den guztia gordetzen da. Arazoak bilatu eta konpontzeko erabil ditzakete aplikazioek erregistro horiek.\n\nBaliteke erregistro batzuek kontuzko informazioa edukitzea. Beraz, eman gailuko erregistro guztiak atzitzeko baimena fidagarritzat jotzen dituzun aplikazioei bakarrik. \n\nNahiz eta gailuko erregistro guztiak atzitzeko baimena ez eman aplikazio honi, aplikazioak hari dagozkion erregistroak atzitu ahalko ditu. Gainera, baliteke gailuaren fabrikatzaileak gailuko erregistro edo datu batzuk atzitu ahal izatea."</string>
</resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 458b4800a1c7..638d199d2efa 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"همیشه از این رایانه انجام شود"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"اجازه دادن"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"‏اشکال‌زدایی USB مجاز نیست"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"‏کاربری که درحال حاضر در این دستگاه وارد سیستم شده است نمی‌تواند اشکال‌زدایی USB را روشن کند. برای استفاده از این قابلیت، به کاربر اصلی تغییر وضعیت دهید."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"‏کاربری که درحال‌حاضر به سیستم این دستگاه وارد شده است نمی‌تواند اشکال‌زدایی USB را روشن کند. برای استفاده از این ویژگی، به کاربر سرپرست تغییر وضعیت دهید."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"آیا می‌خواهید زبان سیستم به <xliff:g id="LANGUAGE">%1$s</xliff:g> تغییر کند؟"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"دستگاه دیگری درخواست کرده است زبان سیستم تغییر کند"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"تغییر زبان"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"همیشه در این شبکه مجاز شود"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"اجازه دادن"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"اشکال‌زدایی بی‌سیم مجاز نیست"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"کاربری که درحال‌حاضر در این دستگاه به سیستم وارد شده است نمی‌تواند اشکال‌زدایی بی‌سیم را روشن کند. برای استفاده از این ویژگی، به کاربر اصلی بروید."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"کاربری که درحال‌حاضر به سیستم این دستگاه وارد شده است نمی‌تواند اشکال‌زدایی بی‌سیم را روشن کند. برای استفاده از این ویژگی، به کاربر سرپرست تغییر وضعیت دهید."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"‏درگاه USB غیرفعال شده است"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"‏برای محافظت از دستگاهتان دربرابر مایعات یا خاکروبه، درگاه USB غیرفعال شده است و هیچ‌کدام از لوازم جانبی را شناسایی نخواهد کرد.\n\nهرزمان که استفاده از درگاه USB امکان‌پذیر باشد، به شما اطلاع داده می‌شود."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"‏درگاه USB برای تشخیص شارژرها و لوازم جانبی فعال شد"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"دستیار صوتی"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"کیف پول"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"کدخوان پاسخ‌سریع"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"باز کردن قفل"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"دستگاه قفل است"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"درحال اسکن کردن چهره"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"ارسال"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"چهره شناسایی نشد"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"از اثر انگشت استفاده کنید"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"بلوتوث متصل است."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"درصد شارژ باتری مشخص نیست."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"حالت هواپیما."</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"‏VPN روشن است."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"باتری <xliff:g id="NUMBER">%d</xliff:g> درصد."</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"باتری <xliff:g id="PERCENTAGE">%1$s</xliff:g> درصد شارژ دارد، براساس مصرفتان تقریباً <xliff:g id="TIME">%2$s</xliff:g> شارژ باقی‌مانده است"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"باتری <xliff:g id="PERCENTAGE">%1$d</xliff:g> درصد شارژ دارد، براساس مصرفتان تقریباً <xliff:g id="TIME">%2$s</xliff:g> شارژ باقی‌مانده است"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"در حال شارژ باتری، <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> درصد"</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"دیدن همه اعلان‌ها"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"تله‌تایپ فعال شد."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"زنگ لرزشی."</string>
@@ -386,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"وقتی درحال هم‌رسانی، ضبط، یا پخش محتوای برنامه‌ای هستید، <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> به همه محتوایی که در آن برنامه نمایان است یا پخش می‌شود دسترسی دارد. بنابراین مراقب گذرواژه‌ها، جزئیات پرداخت، پیام‌ها، یا دیگر اطلاعات حساس باشید."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"ادامه"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"هم‌رسانی یا ضبط برنامه"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"به این برنامه اجازه هم‌رسانی یا ضبط می‌دهید؟"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"وقتی درحال هم‌رسانی، ضبط، یا پخش محتوا هستید، این برنامه به همه محتوایی که در صفحه‌تان نمایان است یا در دستگاهتان پخش می‌شود دسترسی دارد. بنابراین مراقب گذرواژه‌ها، جزئیات پرداخت، پیام‌ها، یا دیگر اطلاعات حساس باشید."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"وقتی درحال هم‌رسانی، ضبط، یا پخش محتوای برنامه‌ای هستید، این برنامه به همه محتوایی که در آن برنامه نمایان است یا پخش می‌شود دسترسی دارد. بنابراین مراقب گذرواژه‌ها، جزئیات پرداخت، پیام‌ها، یا دیگر اطلاعات حساس باشید."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"سرپرست فناوری اطلاعات آن را مسدود کرده است"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"«ضبط صفحه‌نمایش» به‌دلیل خط‌مشی دستگاه غیرفعال است"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"پاک کردن همه موارد"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"مدیریت"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"سابقه"</string>
@@ -511,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"برای استفاده، قفل را باز کنید"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"هنگام دریافت کارت‌ها مشکلی پیش آمد، لطفاً بعداً دوباره امتحان کنید"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"تنظیمات صفحه قفل"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"اسکن رمزینه پاسخ‌سریع"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"نمایه کاری"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"حالت هواپیما"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"در ساعت <xliff:g id="WHEN">%1$s</xliff:g>، دیگر صدای زنگ ساعت را نمی‌شنوید"</string>
@@ -794,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"درشت‌نمایی تمام‌صفحه"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"درشت‌نمایی بخشی از صفحه"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"کلید"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"مجاز کردن پیمایش قطری"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"تغییر اندازه"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"تغییر نوع درشت‌نمایی"</string>
@@ -1024,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE d MMM"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"به <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> اجازه می‌دهید به همه گزارش‌های دستگاه دسترسی داشته باشد؟"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"مجاز کردن دسترسی یک‌باره"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"اجازه نمی‌دهم"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"گزارش‌های دستگاه آنچه را در دستگاهتان رخ می‌دهد ثبت می‌کند. برنامه‌ها می‌توانند از این گزارش‌ها برای پیدا کردن مشکلات و رفع آن‌ها استفاده کنند.\n\nبرخی‌از گزارش‌ها ممکن است حاوی اطلاعات حساس باشند، بنابراین فقط به برنامه‌های مورداعتمادتان اجازه دسترسی به همه گزارش‌های دستگاه را بدهید. \n\nاگر به این برنامه اجازه ندهید به همه گزارش‌های دستگاه دسترسی داشته باشد، همچنان می‌تواند به گزارش‌های خودش دسترسی داشته باشد. سازنده دستگاه نیز ممکن است همچنان بتواند به برخی‌از گزارش‌ها یا اطلاعات دستگاهتان دسترسی داشته باشد."</string>
</resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 1da012a92295..25af80272e05 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"Salli aina tällä tietokoneella"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"Salli"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"USB-vianetsintää ei sallita"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"Laitteelle tällä hetkellä kirjautunut käyttäjä ei voi ottaa USB-vianetsintää käyttöön. Vaihda käyttäjäksi ensisijainen käyttäjä, jotta voit käyttää tätä ominaisuutta."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"Laitteelle tällä hetkellä kirjautunut käyttäjä ei voi laittaa USB-vianetsintää päälle. Vaihda järjestelmänvalvojaksi, jotta voit käyttää tätä ominaisuutta."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Haluatko, että järjestelmän kieli on jatkossa <xliff:g id="LANGUAGE">%1$s</xliff:g>?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Toiselta laitteelta pyydetty järjestelmän kielen vaihtamista"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Vaihda kieltä"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"Salli aina tässä verkossa"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"Salli"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Langatonta virheenkorjausta ei sallita"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"Laitteelle tällä hetkellä kirjautunut käyttäjä ei voi ottaa langatonta virheenkorjausta käyttöön. Vaihda käyttäjäksi ensisijainen käyttäjä, jotta voit käyttää tätä ominaisuutta."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"Laitteelle tällä hetkellä kirjautunut käyttäjä ei voi laittaa langatonta virheenkorjausta päälle. Vaihda järjestelmänvalvojaksi, jotta voit käyttää tätä ominaisuutta."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"USB-portti poistettu käytöstä"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"Laitteen suojaamiseksi nesteiltä ja lialta USB-portti on poistettu käytöstä, eikä se havaitse lisävarusteita.\n\nSaat ilmoituksen, kun USB-porttia voi taas käyttää."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"USB-portti on käytössä ja voi havaita latureita sekä lisävarusteita"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Ääniapuri"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"QR-koodiskanneri"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"Avaa lukitus"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"Laite lukittu"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Kasvojen skannaus"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Lähetä"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"Kasvoja ei voi tunnistaa"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Käytä sormenjälkeä"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth yhdistetty."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"Akun varaustaso ei tiedossa."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"Lentokonetila."</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN päällä"</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"Akun virta <xliff:g id="NUMBER">%d</xliff:g> prosenttia."</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Akkua jäljellä <xliff:g id="PERCENTAGE">%1$s</xliff:g> prosenttia eli noin <xliff:g id="TIME">%2$s</xliff:g> käyttösi perusteella"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Akkua jäljellä <xliff:g id="PERCENTAGE">%1$d</xliff:g> prosenttia eli noin <xliff:g id="TIME">%2$s</xliff:g> käyttösi perusteella"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Akku latautuu: <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> prosenttia"</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"Näytä kaikki ilmoitukset"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"Tekstipuhelin käytössä."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Soittoääni: värinä."</string>
@@ -386,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Kun jaat, tallennat tai striimaat sovellusta, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> saa pääsyn kaikkeen sovelluksessa näkyvään tai toistettuun sisältöön. Ole siis varovainen, kun lisäät salasanoja, maksutietoja, viestejä tai muita arkaluontoisia tietoja."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Jatka"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Jaa sovellus tai tallenna sen sisältöä"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Sallitko sovelluksen jakaa tai tallentaa sisältöä?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Kun jaat, tallennat tai striimaat sisältöä, sovellus saa pääsyn kaikkeen näytölläsi näkyvään tai laitteellasi toistettuun sisältöön. Ole siis varovainen, kun lisäät salasanoja, maksutietoja, viestejä tai muita arkaluontoisia tietoja."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Kun jaat, tallennat tai striimaat sovellusta, tämä sovellus saa pääsyn kaikkeen sovelluksessa näkyvään tai toistettuun sisältöön. Ole siis varovainen, kun lisäät salasanoja, maksutietoja, viestejä tai muita arkaluontoisia tietoja."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"IT-järjestelmänvalvojasi estämä"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"Kuvakaappaus on poistettu käytöstä laitekäytännön perusteella"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Tyhjennä kaikki"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Muuta asetuksia"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Historia"</string>
@@ -511,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Avaa lukitus ja käytä"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Korttien noutamisessa oli ongelma, yritä myöhemmin uudelleen"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Lukitusnäytön asetukset"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"Skannaa QR-koodi"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Työprofiili"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Lentokonetila"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Et kuule seuraavaa hälytystäsi (<xliff:g id="WHEN">%1$s</xliff:g>)."</string>
@@ -794,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Koko näytön suurennus"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Suurenna osa näytöstä"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Vaihda"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Diagonaalisen vierittämisen salliminen"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Muuta kokoa"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"Suurennustyypin muuttaminen"</string>
@@ -1024,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"VKP, KKK p"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"Saako <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> pääsyn kaikkiin laitelokeihin?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"Salli kertaluonteinen pääsy"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Älä salli"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"Laitteen tapahtumat tallentuvat laitelokeihin. Niiden avulla sovellukset voivat löytää ja korjata ongelmia.\n\nJotkin lokit voivat sisältää arkaluontoista tietoa, joten salli pääsy kaikkiin laitelokeihin vain sovelluksille, joihin luotat. \n\nJos et salli tälle sovellukselle pääsyä kaikkiin laitelokeihin, sillä on kuitenkin pääsy sen omiin lokeihin. Laitteen valmistajalla voi olla pääsy joihinkin lokeihin tai tietoihin laitteella."</string>
</resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index cc8bdb847fc7..19d61a56cd60 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"Toujours autoriser sur cet ordinateur"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"Autoriser"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"Débogage USB non autorisé"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"L\'utilisateur actuellement connecté sur cet appareil ne peut pas activer le débogage USB. Pour utiliser cette fonctionnalité, l\'utilisateur principal doit se connecter."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"L\'utilisateur actuellement connecté sur cet appareil ne peut pas activer le débogage USB. Pour utiliser cette fonctionnalité, l\'utilisateur administrateur doit se connecter."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Voulez-vous changer la langue du système pour : <xliff:g id="LANGUAGE">%1$s</xliff:g>?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Un autre appareil demande de changer la langue du système"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Changer la langue"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"Toujours autoriser sur ce réseau"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"Autoriser"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Débogage sans fil non autorisé"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"L\'utilisateur actuellement connecté sur cet appareil ne peut pas activer le débogage sans fil. Pour utiliser cette fonctionnalité, l\'utilisateur principal doit se connecter."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"L\'utilisateur actuellement connecté sur cet appareil ne peut pas activer le débogage sans fil. Pour utiliser cette fonctionnalité, l\'utilisateur administrateur doit se connecter."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"Le port USB a été désactivé"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"Pour protéger votre appareil des liquides et des débris, le port USB est désactivé et ne pourra pas détecter les accessoires.\n\nVous verrez une notification lorsque vous pourrez utiliser le port USB à nouveau."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"Le port USB a été activé afin de détecté les chargeurs et les accessoires"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Assistance vocale"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Portefeuille"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"Lecteur de code QR"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"Déverrouiller"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"Appareil verrouillé"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Numérisation du visage"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Envoyer"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"Visage non reconnu"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Utiliser l\'empreinte digitale"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth connecté"</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"Pourcentage de la pile inconnu."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"Mode Avion"</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"RPV activé."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"Pile : <xliff:g id="NUMBER">%d</xliff:g> pour cent"</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Pile chargée à <xliff:g id="PERCENTAGE">%1$s</xliff:g> pour cent (environ <xliff:g id="TIME">%2$s</xliff:g> d\'autonomie en fonction de votre usage)"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Pile chargée à <xliff:g id="PERCENTAGE">%1$d</xliff:g> pour cent (environ <xliff:g id="TIME">%2$s</xliff:g> d\'autonomie en fonction de votre usage)"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Pile en charge : <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> %%."</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"Afficher toutes les notifications"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"Téléscripteur activé"</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Sonnerie en mode vibreur"</string>
@@ -386,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Lorsque vous partagez, enregistrez ou diffusez une application, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> a accès à tout ce qui est affiché ou lu sur cette application. Par conséquent, soyez prudent avec les mots de passe, les détails du paiement, les messages ou toute autre information confidentielle."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Continuer"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Partager ou enregistrer une application"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Autoriser cette application à partager ou à enregistrer?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Lorsque vous partagez, enregistrez ou diffusez, cette application a accès à tout ce qui est visible sur votre écran ou lu sur votre appareil. Par conséquent, soyez prudent avec les mots de passe, les détails du paiement, les messages ou toute autre information confidentielle."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Lorsque vous partagez, enregistrez ou diffusez une application, cette application a accès à tout ce qui est affiché ou lu sur cette application. Par conséquent, soyez prudent avec les mots de passe, les détails du paiement, les messages ou toute autre information confidentielle."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Bloquée par votre administrateur informatique"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"La fonctionnalité de capture d\'écran est désactivée par l\'application Device Policy"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Tout effacer"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Gérer"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Historique"</string>
@@ -511,7 +511,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Déverrouiller pour utiliser"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Un problème est survenu lors de la récupération de vos cartes, veuillez réessayer plus tard"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Paramètres de l\'écran de verrouillage"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"Numériser le code QR"</string>
+ <string name="qr_code_scanner_title" msgid="1938155688725760702">"lecteur de code QR"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Profil professionnel"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Mode Avion"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Vous n\'entendrez pas votre prochaine alarme à <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -794,6 +794,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Agrandir la totalité de l\'écran"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Agrandir une partie de l\'écran"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Commutateur"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Autoriser le défilement en diagonale"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Redimensionner"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"Changer le type d\'agrandissement"</string>
@@ -1024,4 +1026,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"Autoriser <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> à accéder à l\'ensemble des journaux de l\'appareil?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"Autoriser un accès unique"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Ne pas autoriser"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"Les journaux de l\'appareil enregistrent ce qui se passe sur celui-ci. Les applications peuvent utiliser ces journaux pour trouver et résoudre des problèmes.\n\nCertains journaux peuvent contenir des renseignements confidentiels. N\'autorisez donc que les applications auxquelles vous faites confiance puisque celles-ci pourront accéder à l\'ensemble des journaux de l\'appareil. \n\nMême si vous n\'autorisez pas cette application à accéder à l\'ensemble des journaux de l\'appareil, elle aura toujours accès à ses propres journaux. Le fabricant de votre appareil pourrait toujours être en mesure d\'accéder à certains journaux ou renseignements sur votre appareil."</string>
</resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 1508b9c3c280..1e3319bad668 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"Toujours autoriser sur cet ordinateur"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"Autoriser"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"Débogage USB non autorisé"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"L\'utilisateur actuellement connecté sur cet appareil ne peut pas activer le débogage USB. Pour utiliser cette fonctionnalité, l\'utilisateur principal doit se connecter."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"L\'utilisateur actuellement connecté sur cet appareil ne peut pas activer le débogage USB. Pour utiliser cette fonctionnalité, un administrateur doit se connecter."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Voulez-vous définir la langue système sur <xliff:g id="LANGUAGE">%1$s</xliff:g> ?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Changement de langue système demandé par un autre appareil"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Changer de langue"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"Toujours autoriser sur ce réseau"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"Autoriser"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Débogage sans fil non autorisé"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"L\'utilisateur actuellement connecté sur cet appareil ne peut pas activer le débogage sans fil. Pour que cette fonctionnalité soit disponible, l\'utilisateur principal doit se connecter."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"L\'utilisateur actuellement connecté sur cet appareil ne peut pas activer le débogage sans fil. Pour utiliser cette fonctionnalité, un administrateur doit se connecter."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"Port USB désactivé"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"Pour protéger votre appareil des liquides et des saletés, le port USB est désactivé et ne détecte plus les accessoires.\n\nVous recevrez une notification lorsque vous pourrez de nouveau utiliser le port USB."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"Port USB activé pour détecter les chargeurs et les accessoires"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Assistance vocale"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"Lecteur de code QR"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"Déverrouiller"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"Appareil verrouillé"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Analyse du visage en cours"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Envoyer"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"Visage non reconnu"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Utilisez empreinte digit."</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth connecté"</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"Pourcentage de la batterie inconnu."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"Mode Avion"</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"Le VPN est activé."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"Batterie : <xliff:g id="NUMBER">%d</xliff:g> pour cent"</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Batterie chargée à <xliff:g id="PERCENTAGE">%1$s</xliff:g> pour cent : il reste environ <xliff:g id="TIME">%2$s</xliff:g> d\'autonomie, selon votre utilisation"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Batterie chargée à <xliff:g id="PERCENTAGE">%1$d</xliff:g> pour cent : il reste environ <xliff:g id="TIME">%2$s</xliff:g> d\'autonomie, selon votre utilisation"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Batterie en charge : <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> %%."</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"Afficher toutes les notifications"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"Téléscripteur activé"</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Sonnerie en mode vibreur"</string>
@@ -386,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Lorsque vous partagez, enregistrez ou castez une appli, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> a accès à tout ce qui est visible sur votre écran ou lu sur votre appareil. Faites donc attention à vos mots de passe, détails de mode de paiement, messages ou autres informations sensibles."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Continuer"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Partager ou enregistrer une appli"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Autoriser cette appli à partager ou enregistrer ?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Lorsque vous partagez, enregistrez ou castez, cette appli a accès à tout ce qui est visible sur votre écran ou lu sur votre appareil. Faites donc attention à vos mots de passe, détails de mode de paiement, messages ou autres informations sensibles."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Lorsque vous partagez, enregistrez ou castez une appli, cette appli a accès à tout ce qui est visible sur votre écran ou lu sur votre appareil. Faites donc attention à vos mots de passe, détails de mode de paiement, messages ou autres informations sensibles."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Bloquée par votre administrateur informatique"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"La capture d\'écran est désactivée conformément aux règles relatives à l\'appareil"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Tout effacer"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Gérer"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Historique"</string>
@@ -511,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Déverrouiller pour utiliser"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Problème de récupération de vos cartes. Réessayez plus tard"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Paramètres de l\'écran de verrouillage"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"Scanner un code QR"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Profil professionnel"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Mode Avion"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Vous n\'entendrez pas votre prochaine alarme <xliff:g id="WHEN">%1$s</xliff:g>."</string>
@@ -794,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Agrandir tout l\'écran"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Agrandir une partie de l\'écran"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Changer"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Autoriser le défilement diagonal"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Redimensionner"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"Modifier le type d\'agrandissement"</string>
@@ -1024,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM j"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"hh:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"Autoriser <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> à accéder à tous les journaux de l\'appareil ?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"Autoriser un accès unique"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Ne pas autoriser"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"Les journaux enregistrent ce qui se passe sur votre appareil. Les applis peuvent les utiliser pour rechercher et résoudre des problèmes.\n\nCertains journaux pouvant contenir des infos sensibles, autorisez uniquement les applis de confiance à accéder à tous les journaux de l\'appareil. \n\nSi vous refusez à cette appli l\'accès à tous les journaux de l\'appareil, elle a quand même accès aux siens. Le fabricant de l\'appareil peut accéder à certains journaux ou certaines infos sur votre appareil."</string>
</resources>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index 3807a87ca838..745c919e4dfa 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"Permitir sempre desde este ordenador"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"Permitir"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"Non se permite a depuración por USB"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"O usuario coa sesión iniciada actualmente neste dispositivo non pode activar a depuración por USB. Para utilizar esta función, cambia ao usuario principal."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"O usuario coa sesión iniciada actualmente neste dispositivo non pode activar a depuración por USB. Para utilizar esta función, cambia ao usuario administrador."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Queres cambiar o idioma do sistema ao <xliff:g id="LANGUAGE">%1$s</xliff:g>?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Outro dispositivo solicitou un cambio do idioma do sistema"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Cambiar idioma"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"Permitir sempre nesta rede"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"Permitir"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Non se permite a depuración sen fíos"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"O usuario coa sesión iniciada actualmente neste dispositivo non pode activar a depuración sen fíos. Para utilizar esta función, cambia ao usuario principal."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"O usuario coa sesión iniciada actualmente neste dispositivo non pode activar a depuración sen fíos. Para utilizar esta función, cambia ao usuario administrador."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"O porto USB está desactivado"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"Para protexer o dispositivo de líquidos ou residuos, desactivouse o porto USB e non detectará ningún accesorio.\n\nRecibirás unha notificación cando o poidas utilizar de novo."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"Activouse o porto USB para detectar cargadores e accesorios"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Asistente de voz"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"Escáner de código QR"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"Desbloquear"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"Dispositivo bloqueado"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Analizando cara"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Enviar"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"Non se recoñeceu a cara"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Usa a impresión dixital"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth conectado"</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"Descoñécese a porcentaxe da batería."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"Modo avión"</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"A VPN está activada."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"Carga da batería: <xliff:g id="NUMBER">%d</xliff:g> por cento."</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Batería: <xliff:g id="PERCENTAGE">%1$s</xliff:g> por cento, durará <xliff:g id="TIME">%2$s</xliff:g> co uso que adoitas darlle"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Batería: <xliff:g id="PERCENTAGE">%1$d</xliff:g> por cento, durará <xliff:g id="TIME">%2$s</xliff:g> co uso que adoitas darlle"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Batería cargando. Nivel: <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> por cento."</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"Ver todas as notificacións"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"Teletipo activado"</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Timbre en vibración"</string>
@@ -386,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Cando compartes, gravas ou emites unha aplicación, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ten acceso a todo o que se vexa ou se reproduza nela. Polo tanto, debes ter coidado cos contrasinais, os detalles de pago, as mensaxes ou outra información confidencial."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Continuar"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Compartir ou gravar unha aplicación"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Queres permitir que esta aplicación comparta ou grave contido?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Cando compartes, gravas ou emites contido, esta aplicación ten acceso a todo o que se vexa na pantalla ou se reproduza no teu dispositivo. Polo tanto, debes ter coidado cos contrasinais, os detalles de pago, as mensaxes ou outra información confidencial."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Cando compartes, gravas ou emites aplicacións, esta aplicación ten acceso a todo o que se vexa ou se reproduza nelas. Polo tanto, debes ter coidado cos contrasinais, os detalles de pago, as mensaxes ou outra información confidencial."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"O teu administrador de TI bloqueou esta aplicación"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"A política do dispositivo desactivou a opción de capturar a pantalla"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Eliminar todas"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Xestionar"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Historial"</string>
@@ -511,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Desbloquear para usar"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Produciuse un problema ao obter as tarxetas. Téntao de novo máis tarde"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Configuración da pantalla de bloqueo"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"Escanear código QR"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Perfil de traballo"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Modo avión"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Non escoitarás a alarma seguinte <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -750,14 +751,10 @@
<string name="mobile_data_disable_title" msgid="5366476131671617790">"Queres desactivar os datos móbiles?"</string>
<string name="mobile_data_disable_message" msgid="8604966027899770415">"Non terás acceso aos datos nin a Internet a través de <xliff:g id="CARRIER">%s</xliff:g>. Internet só estará dispoñible mediante a wifi."</string>
<string name="mobile_data_disable_message_default_carrier" msgid="6496033312431658238">"o teu operador"</string>
- <!-- no translation found for auto_data_switch_disable_title (5146527155665190652) -->
- <skip />
- <!-- no translation found for auto_data_switch_disable_message (5885533647399535852) -->
- <skip />
- <!-- no translation found for auto_data_switch_dialog_negative_button (2370876875999891444) -->
- <skip />
- <!-- no translation found for auto_data_switch_dialog_positive_button (8531782041263087564) -->
- <skip />
+ <string name="auto_data_switch_disable_title" msgid="5146527155665190652">"Seguro que queres cambiar de novo a <xliff:g id="CARRIER">%s</xliff:g>?"</string>
+ <string name="auto_data_switch_disable_message" msgid="5885533647399535852">"O uso de datos móbiles non cambiará automaticamente en función da dispoñibilidade"</string>
+ <string name="auto_data_switch_dialog_negative_button" msgid="2370876875999891444">"Non, grazas"</string>
+ <string name="auto_data_switch_dialog_positive_button" msgid="8531782041263087564">"Si, cambiar"</string>
<string name="touch_filtered_warning" msgid="8119511393338714836">"Dado que unha aplicación se superpón sobre unha solicitude de permiso, a configuración non pode verificar a túa resposta."</string>
<string name="slice_permission_title" msgid="3262615140094151017">"Queres permitir que <xliff:g id="APP_0">%1$s</xliff:g> mostre fragmentos de aplicación de <xliff:g id="APP_2">%2$s</xliff:g>?"</string>
<string name="slice_permission_text_1" msgid="6675965177075443714">"- Pode ler información da aplicación <xliff:g id="APP">%1$s</xliff:g>"</string>
@@ -798,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Ampliar pantalla completa"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Amplía parte da pantalla"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Cambiar"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Permitir desprazamento diagonal"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Cambiar tamaño"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"Cambiar tipo de ampliación"</string>
@@ -816,18 +815,15 @@
<string name="accessibility_magnification_magnifier_window_settings" msgid="2834685072221468434">"Configuración da ventá da lupa"</string>
<string name="accessibility_floating_button_migration_tooltip" msgid="5217151214439341902">"Toca para abrir as funcións de accesibilidade. Cambia este botón en Configuración.\n\n"<annotation id="link">"Ver configuración"</annotation></string>
<string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Para ocultar temporalmente o botón, móveo ata o bordo"</string>
- <!-- no translation found for accessibility_floating_button_undo (511112888715708241) -->
- <skip />
- <!-- no translation found for accessibility_floating_button_undo_message_text (3044079592757099698) -->
- <skip />
+ <string name="accessibility_floating_button_undo" msgid="511112888715708241">"Desfacer"</string>
+ <string name="accessibility_floating_button_undo_message_text" msgid="3044079592757099698">"{count,plural, =1{Quitouse {label} atallo}other{Quitáronse # atallos}}"</string>
<string name="accessibility_floating_button_action_move_top_left" msgid="6253520703618545705">"Mover á parte super. esquerda"</string>
<string name="accessibility_floating_button_action_move_top_right" msgid="6106225581993479711">"Mover á parte superior dereita"</string>
<string name="accessibility_floating_button_action_move_bottom_left" msgid="8063394111137429725">"Mover á parte infer. esquerda"</string>
<string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"Mover á parte inferior dereita"</string>
<string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"Mover ao bordo e ocultar"</string>
<string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"Mover fóra do bordo e mostrar"</string>
- <!-- no translation found for accessibility_floating_button_action_remove_menu (6730432848162552135) -->
- <skip />
+ <string name="accessibility_floating_button_action_remove_menu" msgid="6730432848162552135">"Quitar"</string>
<string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"activar/desactivar"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"Control de dispositivos"</string>
<string name="controls_providers_title" msgid="6879775889857085056">"Escolle unha aplicación para engadir controis"</string>
@@ -970,10 +966,8 @@
<string name="mobile_data_settings_title" msgid="3955246641380064901">"Datos móbiles"</string>
<string name="preference_summary_default_combination" msgid="8453246369903749670">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="NETWORKMODE">%2$s</xliff:g>"</string>
<string name="mobile_data_connection_active" msgid="944490013299018227">"Conectada"</string>
- <!-- no translation found for mobile_data_temp_connection_active (4590222725908806824) -->
- <skip />
- <!-- no translation found for mobile_data_poor_connection (819617772268371434) -->
- <skip />
+ <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Conectada temporalmente"</string>
+ <string name="mobile_data_poor_connection" msgid="819617772268371434">"Conexión deficiente"</string>
<string name="mobile_data_off_summary" msgid="3663995422004150567">"Os datos móbiles non se conectarán automaticamente"</string>
<string name="mobile_data_no_connection" msgid="1713872434869947377">"Sen conexión"</string>
<string name="non_carrier_network_unavailable" msgid="770049357024492372">"Non hai outras redes dispoñibles"</string>
@@ -1033,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"Queres permitir que a aplicación <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> acceda a todos os rexistros do dispositivo?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"Permitir acceso unha soa vez"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Non permitir"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"Os rexistros do dispositivo dan conta do que ocorre neste. As aplicacións poden usalos para buscar problemas e solucionalos.\n\nAlgúns poden conter información confidencial, polo que che recomendamos que só permitas que accedan a todos os rexistros do dispositivo as aplicacións nas que confíes. \n\nEsta aplicación pode acceder aos seus propios rexistros aínda que non lle permitas acceder a todos. É posible que o fabricante do dispositivo teña acceso a algúns rexistros ou á información do teu dispositivo."</string>
</resources>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index d992d6aa0f63..b9c2c7f64c47 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"હંમેશા આ કમ્પ્યુટરથી મંજૂરી આપો"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"મંજૂરી આપો"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"USB ડીબગિંગની મંજૂરી નથી"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"હાલમાં આ ઉપકરણમાં સાઇન ઇન થયેલ વપરાશકર્તા USB ડિબગીંગ ચાલુ કરી શકતા નથી. આ સુવિધાનો ઉપયોગ કરવા માટે પ્રાથમિક વપરાશકર્તા પર સ્વિચ કરો."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"હાલમાં આ ડિવાઇસમાં સાઇન ઇન થયેલા વપરાશકર્તા USB ડિબગિંગ ચાલુ કરી શકતા નથી. આ સુવિધાનો ઉપયોગ કરવા માટે કોઈ ઍડમિન વપરાશકર્તા પર સ્વિચ કરો."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"શું તમે સિસ્ટમની ભાષા બદલીને <xliff:g id="LANGUAGE">%1$s</xliff:g> કરવા માગો છો?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"બીજા ડિવાઇસ દ્વારા સિસ્ટમની ભાષા બદલવાની વિનંતી કરવામાં આવી છે"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"ભાષા બદલો"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"આ નેટવર્ક પર હંમેશા મંજૂરી આપો"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"મંજૂરી આપો"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"વાયરલેસ ડિબગીંગની મંજૂરી નથી"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"હાલમાં આ ડિવાઇસમાં સાઇન ઇન થયેલ વપરાશકર્તા વાયરલેસ ડિબગીંગ ચાલુ કરી શકતાં નથી. આ સુવિધાનો ઉપયોગ કરવા માટે પ્રાથમિક વપરાશકર્તા પર સ્વિચ કરો."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"હાલમાં આ ડિવાઇસમાં સાઇન ઇન થયેલા વપરાશકર્તા વાયરલેસ ડિબગીંગ ચાલુ કરી શકતા નથી. આ સુવિધાનો ઉપયોગ કરવા માટે કોઈ ઍડમિન વપરાશકર્તા પર સ્વિચ કરો."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"USB પોર્ટ બંધ કરવામાં આવ્યો છે"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"પ્રવાહી અથવા ધૂળથી તમારા ડિવાઇસનું રક્ષણ કરવા માટે, USB પોર્ટ બંધ કરવામાં આવ્યો છે અને કોઈ ઍક્સેસરી શોધશે નહીં.\n\nજ્યારે ફરીથી USB પોર્ટને ઉપયોગમાં લેવાનું સુરક્ષિત હશે ત્યારે તમને નોટિફિકેશન આપવામાં આવશે."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"ચાર્જર અને ઍક્સેસરીની ઓળખ માટે USB પોર્ટ ચાલુ કર્યું"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"વૉઇસ સહાય"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"QR કોડ સ્કૅનર"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"અનલૉક કરો"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"ડિવાઇસ લૉક કરેલું છે"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"ચહેરો સ્કૅન કરવો"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"મોકલો"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"ચહેરો ઓળખાતો નથી"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"તો ફિંગરપ્રિન્ટ વાપરો"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"બ્લૂટૂથ કનેક્ટ થયું."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"બૅટરીની ટકાવારી અજાણ છે."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"એરપ્લેન મોડ."</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN ચાલુ છે."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"બૅટરી <xliff:g id="NUMBER">%d</xliff:g> ટકા."</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"તમારા વપરાશના આધારે બૅટરી <xliff:g id="PERCENTAGE">%1$s</xliff:g> ટકા, જે લગભગ <xliff:g id="TIME">%2$s</xliff:g> સુધી ચાલે તેટલી બચી છે"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"તમારા વપરાશના આધારે બૅટરી <xliff:g id="PERCENTAGE">%1$d</xliff:g> ટકા, જે લગભગ <xliff:g id="TIME">%2$s</xliff:g> સુધી ચાલે તેટલી બચી છે"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"બૅટરી ચાર્જ થઈ રહી છે, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"બધી સૂચના જુઓ"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"ટેલિટાઇપરાઇટર સક્ષમ કર્યું."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"રિંગર વાઇબ્રેટ."</string>
@@ -386,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"જ્યારે તમે કોઈ ઍપ શેર, રેકોર્ડ અથવા કાસ્ટ કરી રહ્યાં હો, ત્યારે તે ઍપ પર બતાવવામાં કે ચલાવવામાં આવતી હોય તેવી કોઈપણ વસ્તુનો ઍક્સેસ <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ધરાવે છે. તેથી પાસવર્ડ, ચુકવણીની વિગતો, મેસેજ અથવા અન્ય સંવેદનશીલ માહિતીની બાબતે સાવચેત રહેશો."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"ચાલુ રાખો"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"કોઈ ઍપ શેર કરો અથવા રેકોર્ડ કરો"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"આ ઍપને શેર કે રેકોર્ડ કરવાની મંજૂરી આપીએ?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"જ્યારે તમે શેર, રેકોર્ડ અથવા કાસ્ટ કરી રહ્યાં હો, ત્યારે આ ઍપ પાસે તમારી સ્ક્રીન પર જોઈ શકાતી કે તમારા ડિવાઇસ પર ચલાવવામાં આવતી બધી વસ્તુઓનો ઍક્સેસ હોય છે. તેથી પાસવર્ડ, ચુકવણીની વિગતો, મેસેજ અથવા અન્ય સંવેદનશીલ માહિતીની બાબતે સાવચેત રહેશો."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"જ્યારે તમે કોઈ ઍપને શેર, રેકોર્ડ અથવા કાસ્ટ કરી રહ્યાં હો, ત્યારે તેના પર બતાવવામાં કે ચલાવવામાં આવતી બધી વસ્તુઓનો ઍક્સેસ આ ઍપ પાસે હોય છે. તેથી પાસવર્ડ, ચુકવણીની વિગતો, મેસેજ અથવા અન્ય સંવેદનશીલ માહિતીની બાબતે સાવચેત રહેશો."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"તમારા IT ઍડમિન દ્વારા બ્લૉક કરાયેલી"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"ડિવાઇસ પૉલિસી અનુસાર સ્ક્રીન કૅપ્ચર કરવાની સુવિધા બંધ કરવામાં આવી છે"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"બધુ સાફ કરો"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"મેનેજ કરો"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"ઇતિહાસ"</string>
@@ -511,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"ઉપયોગ કરવા માટે અનલૉક કરો"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"તમારા કાર્ડની માહિતી મેળવવામાં સમસ્યા આવી હતી, કૃપા કરીને થોડા સમય પછી ફરી પ્રયાસ કરો"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"લૉક સ્ક્રીનના સેટિંગ"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"QR કોડ સ્કૅન કરો"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"ઑફિસની પ્રોફાઇલ"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"એરપ્લેન મોડ"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"તમે <xliff:g id="WHEN">%1$s</xliff:g> એ તમારો આગલો એલાર્મ સાંભળશો નહીં"</string>
@@ -794,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"પૂર્ણ સ્ક્રીનને મોટી કરો"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"સ્ક્રીનનો કોઈ ભાગ મોટો કરો"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"સ્વિચ"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"ડાયગોનલ સ્ક્રોલિંગને મંજૂરી આપો"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"કદ બદલો"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"મોટું કરવાનો પ્રકાર બદલો"</string>
@@ -1024,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"શું <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g>ને ડિવાઇસનો બધો લૉગ ઍક્સેસ કરવાની મંજૂરી આપીએ?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"એક-વખતના ઍક્સેસની મંજૂરી આપો"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"મંજૂરી આપશો નહીં"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"તમારા ડિવાઇસ પર થતી કામગીરીને ડિવાઇસ લૉગ રેકોર્ડ કરે છે. ઍપ આ લૉગનો ઉપયોગ સમસ્યાઓ શોધી તેનું નિરાકરણ કરવા માટે કરી શકે છે.\n\nઅમુક લૉગમાં સંવેદનશીલ માહિતી હોઈ શકે, આથી ડિવાઇસનો બધો લૉગ ઍક્સેસ કરવાની મંજૂરી માત્ર તમારી વિશ્વાસપાત્ર ઍપને જ આપો. \n\nજો તમે આ ઍપને ડિવાઇસનો બધો લૉગ ઍક્સેસ કરવાની મંજૂરી ન આપો, તો પણ તે તેના પોતાના લૉગ ઍક્સેસ કરી શકે છે. તમારા ડિવાઇસના નિર્માતા હજી પણ કદાચ તમારા ડિવાઇસ પર અમુક લૉગ અથવા માહિતી ઍક્સેસ કરી શકે છે."</string>
</resources>
diff --git a/packages/SystemUI/res/values-h800dp/dimens.xml b/packages/SystemUI/res/values-h800dp/dimens.xml
index 94fe20955ce6..8efd6f0b7995 100644
--- a/packages/SystemUI/res/values-h800dp/dimens.xml
+++ b/packages/SystemUI/res/values-h800dp/dimens.xml
@@ -15,9 +15,6 @@
-->
<resources>
- <!-- Large clock maximum font size (dp is intentional, to prevent any further scaling) -->
- <dimen name="large_clock_text_size">200dp</dimen>
-
<!-- With the large clock, move up slightly from the center -->
<dimen name="keyguard_large_clock_top_margin">-112dp</dimen>
</resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index e8458dd4b57a..79f96964a694 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"इस कंप्यूटर से हमेशा अनुमति दें"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"अनुमति दें"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"USB डीबगिंग की अनुमति नहीं है"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"अभी इस डिवाइस में जिस उपयोगकर्ता ने साइन इन किया है, वो USB डीबगिंग चालू नहीं कर सकता. इस सुविधा का इस्तेमाल करने के लिए, प्राथमिक उपयोगकर्ता में बदलें."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"फ़िलहाल, इस डिवाइस में जिस उपयोगकर्ता ने साइन इन किया है वह यूएसबी डीबग करने की प्रोसेस चालू नहीं कर सकता. इस सुविधा का इस्तेमाल करने के लिए, कृपया खाते के एडमिन के तौर पर साइन इन करें."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"क्या आपको सिस्टम की भाषा <xliff:g id="LANGUAGE">%1$s</xliff:g> में बदलनी है?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"किसी दूसरे डिवाइस से, सिस्टम की भाषा बदलने का अनुरोध किया गया"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"भाषा बदलें"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"इस नेटवर्क पर हमेशा अनुमति दें"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"अनुमति दें"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"वॉयरलेस डीबगिंग की सुविधा चालू करने की अनुमति नहीं है"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"अभी इस डिवाइस में जिस उपयोगकर्ता ने साइन इन कर रखा है वह वॉयरलेस डीबगिंग की सुविधा चालू नहीं कर सकता. इस सुविधा का इस्तेमाल करने के लिए, मुख्य उपयोगकर्ता के तौर पर साइन इन करें."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"फ़िलहाल, इस डिवाइस में जिस उपयोगकर्ता ने साइन इन किया है वह वॉयरलेस डीबगिंग की सुविधा चालू नहीं कर सकता. इस सुविधा का इस्तेमाल करने के लिए, खाते के एडमिन के तौर पर साइन इन करें."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"यूएसबी पोर्ट बंद है"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"तरल चीज़ या कचरे से आपके डिवाइस की सुरक्षा करने के लिए, यूएसबी पोर्ट को बंद कर दिया गया है. साथ ही, इससे किसी भी एक्सेसरी की पहचान नहीं की जा सकेगी.\n\nयूएसबी पोर्ट का दोबारा इस्तेमाल करना सुरक्षित होने पर आपको सूचित किया जाएगा."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"चार्जर और एक्सेसरी पहचानने के लिए यूएसबी पोर्ट को चालू कर दिया गया है"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"आवाज़ से डिवाइस का इस्तेमाल"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"क्यूआर कोड स्कैनर"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"अनलॉक करें"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"डिवाइस लॉक है"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"डिवाइस अनलॉक करने के लिए चेहरा स्कैन किया जाता है"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"भेजें"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"चेहरे की पहचान नहीं हुई"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"फ़िंगरप्रिंट इस्तेमाल करें"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"ब्लूटूथ कनेक्ट किया गया."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"इस बारे में जानकारी नहीं है कि अभी बैटरी कितने प्रतिशत चार्ज है."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"हवाई जहाज़ मोड."</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN चालू."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"<xliff:g id="NUMBER">%d</xliff:g> प्रति‍शत बैटरी."</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> प्रतिशत बैटरी बची है और आपके इस्तेमाल के हिसाब से यह <xliff:g id="TIME">%2$s</xliff:g> में खत्म हो जाएगी"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> प्रतिशत बैटरी बची है और आपके इस्तेमाल के हिसाब से यह <xliff:g id="TIME">%2$s</xliff:g> में खत्म हो जाएगी"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"बैटरी चार्ज हो रही है, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> प्रतिशत."</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"पूरी सूचनाएं देखें"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"टेलीटाइपराइटर सक्षम."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"रिंगर कंपन (वाइब्रेशन)."</string>
@@ -386,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"शेयर, रिकॉर्ड या कास्ट करते समय, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> के पास उस ऐप्लिकेशन पर दिख रही हर चीज़ या उस पर चल रहे हर मीडिया का ऐक्सेस होता है. इसलिए, शेयर, रिकॉर्ड या कास्ट करते समय, पासवर्ड, पेमेंट के तरीके की जानकारी, मैसेज या किसी और संवेदनशील जानकारी को लेकर खास सावधानी बरतें."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"जारी रखें"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"ऐप्लिकेशन शेयर करें या उसकी रिकॉर्डिंग करें"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"क्या इस ऐप्लिकेशन को शेयर या रिकॉर्ड करने की अनुमति देनी है?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"शेयर, रिकॉर्ड या कास्ट करते समय, इस ऐप्लिकेशन के पास स्क्रीन पर दिख रही हर चीज़ या डिवाइस पर चल रहे सभी मीडिया का ऐक्सेस होता है. इसलिए, इस दौरान पासवर्ड, पेमेंट के तरीके की जानकारी, मैसेज या दूसरी संवेदनशील जानकारी को लेकर खास सावधानी बरतें."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"किसी ऐप्लिकेशन को शेयर, रिकॉर्ड या कास्ट करते समय, इस ऐप्लिकेशन के पास उस ऐप्लिकेशन पर दिख रही हर चीज़ या उस पर चल रहे सभी मीडिया का ऐक्सेस होता है. इसलिए, इस दौरान पासवर्ड, पेमेंट के तरीके की जानकारी, मैसेज या दूसरी संवेदनशील जानकारी को लेकर खास सावधानी बरतें."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"आपके आईटी एडमिन ने स्क्रीन कैप्चर करने की सुविधा पर रोक लगाई है"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"डिवाइस से जुड़ी नीति के तहत स्क्रीन कैप्चर करने की सुविधा बंद है"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"सभी को हटाएं"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"मैनेज करें"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"इतिहास"</string>
@@ -511,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"इस्तेमाल करने के लिए, डिवाइस अनलॉक करें"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"आपके कार्ड की जानकारी पाने में कोई समस्या हुई है. कृपया बाद में कोशिश करें"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"लॉक स्क्रीन की सेटिंग"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"क्यूआर कोड स्कैन करें"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"वर्क प्रोफ़ाइल"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"हवाई जहाज़ मोड"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"आपको <xliff:g id="WHEN">%1$s</xliff:g> पर अपना अगला अलार्म नहीं सुनाई देगा"</string>
@@ -794,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"फ़ुल स्क्रीन को ज़ूम करें"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"स्क्रीन के किसी हिस्से को ज़ूम करें"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"स्विच"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"तिरछी दिशा में स्क्रोल करने की अनुमति दें"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"साइज़ बदलें"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"ज़ूम करने की सुविधा का टाइप बदलें"</string>
@@ -1024,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"क्या <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> को डिवाइस लॉग का ऐक्सेस देना है?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"एक बार ऐक्सेस करने की अनुमति दें"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"अनुमति न दें"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"डिवाइस लॉग में आपके डिवाइस पर की गई कार्रवाइयां रिकॉर्ड होती हैं. ऐप्लिकेशन, इन लॉग का इस्तेमाल गड़बड़ियां ढूंढने और उन्हें सही करने के लिए करता है.\n\nकुछ लॉग में संवेदनशील जानकारी हो सकती है. इसलिए, सिर्फ़ भरोसेमंद ऐप्लिकेशन को डिवाइस के सभी लॉग का ऐक्सेस दें. \n\nअगर इस ऐप्लिकेशन को डिवाइस के सभी लॉग का ऐक्सेस नहीं दिया जाता है, तब भी यह डिवाइस पर मौजूद अपने लॉग ऐक्सेस कर सकता है. डिवाइस को बनाने वाली कंपनी अब भी डिवाइस के कुछ लॉग या जानकारी को ऐक्सेस कर सकती है."</string>
</resources>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index d8fd225a3962..a4680715ccd4 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"Uvijek dopusti s ovog računala"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"Dopusti"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"Otklanjanje pogrešaka putem USB-a nije dopušteno"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"Korisnik koji je trenutačno prijavljen na ovaj uređaj ne može uključiti otklanjanje pogrešaka putem USB-a. Da biste upotrebljavali tu značajku, prijeđite na primarnog korisnika."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"Korisnik koji je trenutačno prijavljen na ovaj uređaj ne može uključiti otklanjanje pogrešaka putem USB-a. Da biste upotrebljavali tu značajku, prijeđite na korisnika s administratorskim pravima."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Želite li promijeniti jezik sustava u <xliff:g id="LANGUAGE">%1$s</xliff:g>?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Drugi uređaj zatražio je promjenu jezika sustava"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Promijeni jezik"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"Uvijek dopusti na ovoj mreži"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"Dopusti"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Bežično otklanjanje pogrešaka nije dopušteno"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"Korisnik koji je trenutačno prijavljen na ovaj uređaj ne može uključiti bežično otklanjanje pogrešaka. Da biste upotrebljavali tu značajku, prijeđite na primarnog korisnika."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"Korisnik koji je trenutačno prijavljen na ovaj uređaj ne može uključiti bežično otklanjanje pogrešaka. Da biste upotrebljavali tu značajku, prijeđite na korisnika s administratorskim pravima."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"Onemogućen je USB priključak"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"Radi zaštite uređaja od tekućine ili prljavštine USB priključak onemogućen je i neće otkrivati pribor.\n\nPrimit ćete obavijest kad upotreba USB priključka ponovo bude sigurna."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"USB priključak omogućen za otkrivanje punjača i opreme"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Glasovna pomoć"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"Čitač QR koda"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"Otključavanje"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"Uređaj je zaključan"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Skeniranje lica"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Pošalji"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"Lice nije prepoznato"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Upotrijebite otisak prsta"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth povezan."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"Postotak baterije nije poznat."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"Način rada u zrakoplovu"</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN uključen."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"Baterija <xliff:g id="NUMBER">%d</xliff:g> posto."</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Baterija je na <xliff:g id="PERCENTAGE">%1$s</xliff:g> posto, još otprilike <xliff:g id="TIME">%2$s</xliff:g> na temelju vaše upotrebe"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Baterija je na <xliff:g id="PERCENTAGE">%1$d</xliff:g> posto, još otprilike <xliff:g id="TIME">%2$s</xliff:g> na temelju vaše upotrebe"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Baterija se puni, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> posto."</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"Pogledajte sve obavijesti"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"TeleTypewriter je omogućen."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Vibracija softvera zvona."</string>
@@ -386,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Kad dijelite, snimate ili emitirate aplikaciju, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ima pristup svemu što se prikazuje ili reproducira u toj aplikaciji. Stoga pazite na zaporke, podatke o plaćanju, poruke i druge osjetljive podatke."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Nastavi"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Dijeljenje ili snimanje pomoću aplikacije"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Želite li ovoj aplikaciji omogućiti dijeljenje ili bilježenje?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Kad dijelite, snimate ili emitirate, ova aplikacija ima pristup svemu što je vidljivo na vašem zaslonu ili se reproducira na vašem uređaju. Stoga pazite na zaporke, podatke o plaćanju, poruke i druge osjetljive podatke."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Kad dijelite, snimate ili emitirate aplikaciju, ova aplikacija ima pristup svemu što se prikazuje ili reproducira u toj aplikaciji. Stoga pazite na zaporke, podatke o plaćanju, poruke i druge osjetljive podatke."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Blokirao vaš IT administrator"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"Snimanje zaslona onemogućeno je u skladu s pravilima za uređaje"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Izbriši sve"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Upravljajte"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Povijest"</string>
@@ -511,7 +511,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Otključajte da biste koristili"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Pojavio se problem prilikom dohvaćanja kartica, pokušajte ponovo kasnije"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Postavke zaključanog zaslona"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"Skeniraj QR kôd"</string>
+ <string name="qr_code_scanner_title" msgid="1938155688725760702">"Čitač QR koda"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Poslovni profil"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Način rada u zrakoplovu"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Nećete čuti sljedeći alarm <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -794,6 +794,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Povećajte cijeli zaslon"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Povećaj dio zaslona"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Prebacivanje"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Dopusti dijagonalno pomicanje"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Promijeni veličinu"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"Promijeni vrstu povećanja"</string>
@@ -1024,4 +1026,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE., d. MMM."</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"Želite li dopustiti aplikaciji <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> da pristupa svim zapisnicima uređaja?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"Omogući jednokratni pristup"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Nemoj dopustiti"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"U zapisnicima uređaja bilježi se što se događa na uređaju. Aplikacije mogu koristiti te zapisnike kako bi pronašle i riješile poteškoće.\n\nNeki zapisnici mogu sadržavati osjetljive podatke, pa pristup svim zapisnicima uređaja odobrite samo pouzdanim aplikacijama. \n\nAko ne dopustite ovoj aplikaciji da pristupa svim zapisnicima uređaja, ona i dalje može pristupati svojim zapisnicima. Proizvođač vašeg uređaja i dalje može pristupati nekim zapisnicima ili podacima na vašem uređaju."</string>
</resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index c1a8dd9de8d6..2c2a96689b64 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"Mindig engedélyezze erről a számítógépről"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"Engedélyezés"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"Az USB hibakeresése nem engedélyezett"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"Az eszközre jelenleg bejelentkezett felhasználó nem engedélyezheti az USB-hibakeresést. A funkció használatához váltson az elsődleges felhasználóra."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"Az eszközre jelenleg bejelentkezett felhasználó nem engedélyezheti az USB-hibakeresést. A funkció használatához váltson adminisztrátor felhasználóra."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Kívánja <xliff:g id="LANGUAGE">%1$s</xliff:g> nyelvre módosítani a rendszer nyelvét?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Egy másik eszköz a rendszer nyelvének módosítását kéri"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Nyelvmódosítás"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"Mindig engedélyezze ezen a hálózaton"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"Engedélyezés"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"A vezeték nélküli hibakeresés nem engedélyezett"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"Az eszközre jelenleg bejelentkezett felhasználó nem engedélyezheti a vezeték nélküli hibakeresést. A funkció használatához váltson az elsődleges felhasználóra."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"Az eszközre jelenleg bejelentkezett felhasználó nem engedélyezheti a vezeték nélküli hibakeresést. A funkció használatához váltson adminisztrátor felhasználóra."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"USB-port letiltva"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"Az eszköz folyadéktól és szennyeződésektől való megóvása érdekében az USB-portot letiltottuk, így az nem észleli a kiegészítőket.\n\nÉrtesítést küldünk, amikor ismét rendben használhatja az USB-portot."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"Az USB-csatlakozó számára engedélyezve van a töltők és más tartozékok észlelése"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Hangsegéd"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"QR-kód-szkennelő"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"Feloldás"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"Az eszköz zárolva van"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Arc keresése"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Küldés"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"Az arc nem ismerhető fel"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Használjon ujjlenyomatot"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth csatlakoztatva."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"Az akkumulátor töltöttségi szintje ismeretlen."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"Repülőgép üzemmód."</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN bekapcsolva."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"Akkumulátor <xliff:g id="NUMBER">%d</xliff:g> százalék."</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Az akkumulátor <xliff:g id="PERCENTAGE">%1$s</xliff:g> százalékon áll, a használati adatok alapján körülbelül <xliff:g id="TIME">%2$s</xliff:g> múlva merül le"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Az akkumulátor <xliff:g id="PERCENTAGE">%1$d</xliff:g> százalékon áll, a használati adatok alapján körülbelül <xliff:g id="TIME">%2$s</xliff:g> múlva merül le"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Tölt az akkumulátor, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> százalék."</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"Összes értesítés megtekintése"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"TeleTypewriter engedélyezve."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Csengő rezeg."</string>
@@ -386,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Amikor Ön megoszt, rögzít vagy átküld egy alkalmazást, a(z) <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> az adott appban látható vagy lejátszott minden tartalomhoz hozzáfér. Ezért legyen elővigyázatos a jelszavakkal, a fizetési adatokkal, az üzenetekkel és más bizalmas információkkal."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Folytatás"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Alkalmazás megosztása és rögzítése"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Engedélyezi ennek az alkalmazásnak a megosztást és a rögzítést?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Amikor Ön megosztást, rögzítést vagy átküldést végez, az alkalmazás a képernyőn látható vagy az eszközön lejátszott minden tartalomhoz hozzáfér. Ezért legyen elővigyázatos a jelszavakkal, a fizetési adatokkal, az üzenetekkel és más bizalmas információkkal."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Amikor Ön megoszt, rögzít vagy átküld egy alkalmazást, az alkalmazás az adott appban látható vagy lejátszott minden tartalomhoz hozzáfér. Ezért legyen elővigyázatos a jelszavakkal, a fizetési adatokkal, az üzenetekkel és más bizalmas információkkal."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Rendszergazda által letiltva"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"A képernyőfelvételt eszközszabályzat tiltja"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Az összes törlése"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Kezelés"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Előzmények"</string>
@@ -511,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Oldja fel a használathoz"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Probléma merült fel a kártyák lekérésekor, próbálja újra később"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Lezárási képernyő beállításai"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"QR-kód beolvasása"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Munkahelyi profil"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Repülős üzemmód"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Nem fogja hallani az ébresztést ekkor: <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -794,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"A teljes képernyő felnagyítása"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Képernyő bizonyos részének nagyítása"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Váltás"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Átlós görgetés engedélyezése"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Átméretezés"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"Nagyítási típus módosítása"</string>
@@ -1024,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, HHH n"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"ó:pp"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"óó:pp"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"Engedélyezi a(z) <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> számára, hogy hozzáférjen az összes eszköznaplóhoz?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"Egyszeri hozzáférés engedélyezése"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Tiltás"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"Az eszköznaplók rögzítik, hogy mi történik az eszközén. Az alkalmazások ezeket a naplókat használhatják a problémák megkeresésére és kijavítására.\n\nBizonyos naplók bizalmas adatokat is tartalmazhatnak, ezért csak olyan alkalmazások számára engedélyezze az összes eszköznaplóhoz való hozzáférést, amelyekben megbízik. \n\nHa nem engedélyezi ennek az alkalmazásnak, hogy hozzáférjen az összes eszköznaplójához, az app továbbra is hozzáférhet a saját naplóihoz. Előfordulhat, hogy az eszköz gyártója továbbra is hozzáfér az eszközön található bizonyos naplókhoz és adatokhoz."</string>
</resources>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 691fe64b6ae7..15b5c6dab50e 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"Միշտ թույլատրել այս համակարգչից"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"Թույլատրել"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"USB-ով վրիպազերծումը թույլատրված չէ"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"Ընթացիկ հաշվի միջոցով չեք կարող միացնել USB-ով վրիպազերծումը: Այս գործառույթը միացնելու համար մուտք գործեք հիմնական օգտատիրոջ հաշիվ:"</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"Ընթացիկ հաշվի օգտատերը չի կարող միացնել USB վրիպազերծումը։ Այս գործառույթը միացնելու համար մուտք գործեք ադմինիստրատորի հաշիվ"</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Դարձնե՞լ համակարգի լեզուն <xliff:g id="LANGUAGE">%1$s</xliff:g>"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Մեկ այլ սարք համակարգի լեզվի փոփոխության հարցում է ուղարկել"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Փոխել լեզուն"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"Միշտ թույլատրել այս ցանցում"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"Թույլատրել"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Անլար վրիպազերծումը թույլատրված չէ"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"Դուք չեք կարող միացնել անլար վրիպազերծումը ընթացիկ հաշվի միջոցով։ Այս գործառույթը միացնելու համար մուտք գործեք հիմնական օգտատիրոջ հաշիվ։"</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"Դուք չեք կարող միացնել անլար վրիպազերծումը ընթացիկ հաշվի միջոցով։ Այս գործառույթը միացնելու համար մուտք գործեք ադմինիստրատորի հաշիվ"</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"USB միացքն անջատված է"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"USB միացքն անջատվել է, որպեսզի ձեր սարքը չթրջվի կամ չաղտոտվի: Այժմ USB միացքի միջոցով հնարավոր չէ միացնել այլ սարքեր:\n\nԴուք ծանուցում կստանաք, երբ այն նորից անվտանգ լինի օգտագործել:"</string>
<string name="usb_port_enabled" msgid="531823867664717018">"USB միացքը միացվել է՝ լիցքավորիչներն ու լրասարքերը հայտնաբերելու համար"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Ձայնային հուշումներ"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"QR կոդերի սկաներ"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"Ապակողպել"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"Սարքը կողպված է"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Դեմքի սկանավորում"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Ուղարկել"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"Դեմքը չի ճանաչվել"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Օգտագործեք մատնահետք"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth-ը միացված է:"</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"Մարտկոցի լիցքի մակարդակն անհայտ է։"</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"Ավիառեժիմ"</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"Միացնել VPN-ը։"</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"Մարտկոցը <xliff:g id="NUMBER">%d</xliff:g> տոկոս է:"</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Մարտկոցի լիցքը <xliff:g id="PERCENTAGE">%1$s</xliff:g> տոկոս է և կբավարարի մոտ <xliff:g id="TIME">%2$s</xliff:g>՝ կախված օգտագործման եղանակից:"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Մարտկոցի լիցքը <xliff:g id="PERCENTAGE">%1$d</xliff:g> տոկոս է և կբավարարի մոտ <xliff:g id="TIME">%2$s</xliff:g>՝ կախված օգտագործման եղանակից:"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Մարտկոցը լիցքավորվում է: Լիցքը <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> տոկոս է:"</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"Տեսնել բոլոր ծանուցումները"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"Հեռատիպը միացված է:"</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Թրթռազանգ:"</string>
@@ -386,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Երբ դուք ցուցադրում, տեսագրում կամ հեռարձակում եք որևէ հավելվածի էկրանը, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> հավելվածին հասանելի է դառնում այն ամենը, ինչ ցուցադրվում է կամ նվագարկվում այդ հավելվածում։ Հիշեք այդ մասին, երբ պատրաստվում եք դիտել կամ մուտքագրել գաղտնաբառեր, վճարային տվյալներ, հաղորդագրություններ և այլ կոնֆիդենցիալ տեղեկություններ։"</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Շարունակել"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Հավելվածի էկրանի ցուցադրում կամ տեսագրում"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Թույլատրե՞լ այս հավելվածին ցուցադրել կամ տեսագրել էկրանը"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Երբ դուք ցուցադրում, տեսագրում կամ հեռարձակում եք էկրանը, այս հավելվածին հասանելի է դառնում այն ամենը, ինչ տեսանելի է էկրանին և նվագարկվում է ձեր սարքում։ Հիշեք այդ մասին, երբ պատրաստվում եք դիտել կամ մուտքագրել գաղտնաբառեր, վճարային տվյալներ, հաղորդագրություններ և այլ կոնֆիդենցիալ տեղեկություններ։"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Երբ դուք ցուցադրում, տեսագրում կամ հեռարձակում եք որևէ հավելվածի էկրանը, այս հավելվածին հասանելի է դառնում այն ամենը, ինչ ցուցադրվում է կամ նվագարկվում այդ հավելվածում։ Հիշեք այդ մասին, երբ պատրաստվում եք դիտել կամ մուտքագրել գաղտնաբառեր, վճարային տվյալներ, հաղորդագրություններ և այլ կոնֆիդենցիալ տեղեկություններ։"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Արգելափակվել է ձեր ՏՏ ադմինիստրատորի կողմից"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"Էկրանի տեսագրումն անջատված է սարքի կանոնների համաձայն"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Մաքրել բոլորը"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Կառավարել"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Պատմություն"</string>
@@ -511,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Ապակողպել՝ օգտագործելու համար"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Չհաջողվեց բեռնել քարտերը։ Նորից փորձեք։"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Կողպէկրանի կարգավորումներ"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"Սկանավորել QR կոդը"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Android for Work-ի պրոֆիլ"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Ավիառեժիմ"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Ժամը <xliff:g id="WHEN">%1$s</xliff:g>-ի զարթուցիչը չի զանգի"</string>
@@ -794,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Խոշորացնել ամբողջ էկրանը"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Խոշորացնել էկրանի որոշակի հատվածը"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Փոխել"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Թույլատրել անկյունագծով ոլորումը"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Փոխել չափը"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"Փոխել խոշորացման տեսակը"</string>
@@ -1024,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"Հասանելի դարձնե՞լ <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> հավելվածին սարքի բոլոր մատյանները"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"Թույլատրել մեկանգամյա մուտքը"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Չթույլատրել"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"Այն, ինչ տեղի է ունենում ձեր սարքում, գրանցվում է սարքի մատյաններում։ Հավելվածները կարող են դրանք օգտագործել անսարքությունները հայտնաբերելու և վերացնելու նպատակով։\n\nՔանի որ որոշ մատյաններ անձնական տեղեկություններ են պարունակում, խորհուրդ ենք տալիս հասանելի դարձնել ձեր սարքի բոլոր մատյանները միայն այն հավելվածներին, որոնց վստահում եք։ \n\nԵթե այս հավելվածին նման թույլտվություն չեք տվել, դրան նախկինի պես հասանելի կլինեն իր մատյանները։ Հնարավոր է՝ ձեր սարքի արտադրողին ևս հասանելի լինեն սարքի որոշ մատյաններ և տեղեկություններ։"</string>
</resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 236ad22bcb9b..31d2b81e7f13 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"Selalu izinkan dari komputer ini"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"Izinkan"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"Debug USB tidak diizinkan"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"Pengguna yang sedang login ke perangkat ini tidak dapat mengaktifkan proses debug USB. Beralihlah ke pengguna utama untuk menggunakan fitur ini."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"Pengguna yang sedang login ke perangkat ini tidak dapat mengaktifkan proses debug USB. Beralihlah ke pengguna admin untuk menggunakan fitur ini."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Ingin mengubah bahasa sistem menjadi <xliff:g id="LANGUAGE">%1$s</xliff:g>?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Perubahan bahasa sistem diminta oleh perangkat lain"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Ubah bahasa"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"Selalu izinkan di jaringan ini"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"Izinkan"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Proses debug nirkabel tidak diizinkan"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"Pengguna yang sedang login ke perangkat ini tidak dapat mengaktifkan proses debug nirkabel. Beralihlah ke pengguna utama untuk menggunakan fitur ini."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"Pengguna yang sedang login ke perangkat ini tidak dapat mengaktifkan proses debug nirkabel. Beralihlah ke pengguna admin untuk menggunakan fitur ini."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"Port USB dinonaktifkan"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"Untuk melindungi perangkat dari cairan atau kotoran, port USB dinonaktifkan dan tidak akan mendeteksi aksesori apa pun.\n\nAnda akan diberi tahu jika port USB sudah dapat digunakan kembali."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"Port USB diaktifkan untuk mendeteksi pengisi daya dan aksesori"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Bantuan Suara"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"Pemindai Kode QR"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"Buka kunci"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"Perangkat terkunci"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Memindai wajah"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Kirim"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"Tidak mengenali wajah"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Gunakan sidik jari"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth terhubung."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"Persentase baterai tidak diketahui."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"Mode pesawat."</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN aktif."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"Baterai <xliff:g id="NUMBER">%d</xliff:g> persen."</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Baterai <xliff:g id="PERCENTAGE">%1$s</xliff:g> persen, sekitar <xliff:g id="TIME">%2$s</xliff:g> lagi berdasarkan penggunaan Anda"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Baterai <xliff:g id="PERCENTAGE">%1$d</xliff:g> persen, sekitar <xliff:g id="TIME">%2$s</xliff:g> lagi berdasarkan penggunaan Anda"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Mengisi daya baterai, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> persen."</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"Lihat semua notifikasi"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"TeleTypewriter diaktifkan."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Pendering bergetar."</string>
@@ -386,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Jika Anda membagikan, merekam, atau mentransmisikan suatu aplikasi, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> akan memiliki akses ke semua hal yang ditampilkan atau yang diputar di aplikasi tersebut. Jadi, berhati-hatilah saat memasukkan sandi, detail pembayaran, pesan, atau informasi sensitif lainnya."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Lanjutkan"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Bagikan atau rekam aplikasi"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Izinkan aplikasi ini membagikan atau merekam?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Jika Anda membagikan, merekam, atau mentransmisikan, aplikasi ini akan memiliki akses ke semua hal yang ditampilkan di layar atau yang diputar di perangkat Anda. Jadi, berhati-hatilah saat memasukkan sandi, detail pembayaran, pesan, atau informasi sensitif lainnya."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Jika Anda membagikan, merekam, atau mentransmisikan suatu aplikasi, aplikasi ini akan memiliki akses ke semua hal yang ditampilkan atau yang diputar di aplikasi tersebut. Jadi, berhati-hatilah saat memasukkan sandi, detail pembayaran, pesan, atau informasi sensitif lainnya."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Diblokir oleh admin IT Anda"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"Pengambilan screenshot dinonaktifkan oleh kebijakan perangkat"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Hapus semua"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Kelola"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Histori"</string>
@@ -511,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Buka kunci untuk menggunakan"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Terjadi error saat mendapatkan kartu Anda, coba lagi nanti"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Setelan layar kunci"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"Pindai kode QR"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Profil kerja"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Mode pesawat"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Anda tidak akan mendengar alarm berikutnya <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -794,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Memperbesar tampilan layar penuh"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Perbesar sebagian layar"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Alihkan"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Izinkan scrolling diagonal"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Ubah ukuran"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"Ubah jenis pembesaran"</string>
@@ -1024,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"Izinkan <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> mengakses semua log perangkat?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"Izinkan akses satu kali"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Jangan izinkan"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"Log perangkat merekam hal-hal yang terjadi di perangkat Anda. Aplikasi dapat menggunakan log ini untuk menemukan dan memperbaiki masalah.\n\nBeberapa log mungkin berisi info sensitif, jadi hanya izinkan aplikasi yang Anda percayai untuk mengakses semua log perangkat. \n\nJika Anda tidak mengizinkan aplikasi ini mengakses semua log perangkat, aplikasi masih dapat mengakses log-nya sendiri. Produsen perangkat masih dapat mengakses beberapa log atau info di perangkat Anda."</string>
</resources>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index 537af36b1918..ff12e9cd3211 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"Leyfa alltaf úr þessari tölvu"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"Leyfa"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"USB-villuleit ekki leyfð"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"Notandinn sem er skráður inn í þetta tæki núna getur ekki kveikt á USB-villuleit. Til þess að nota þennan eiginleika skaltu skipta yfir í aðalnotandann."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"Notandinn sem er skráður inn í þetta tæki núna getur ekki kveikt á USB-villuleit. Skiptu yfir í stjórnanda til að nota þennan eiginleika."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Viltu breyta tungumáli kerfis í <xliff:g id="LANGUAGE">%1$s</xliff:g>?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Beiðni frá öðru tæki um að breyta tungumáli kerfis"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Breyta tungumáli"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"Leyfa alltaf á þessu neti"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"Leyfa"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Þráðlaus villuleit er ekki leyfð"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"Notandinn sem er skráður inn í þetta tæki núna getur ekki kveikt á þráðlausri villuleit. Til að nota þennan eiginleika þarf að skipta yfir í aðalnotanda."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"Notandinn sem er skráður inn í þetta tæki núna getur ekki kveikt á þráðlausri villuleit. Skiptu yfir í stjórnanda til að nota þennan eiginleika."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"USB-tengi gert óvirkt"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"Til að vernda tækið fyrir vökva og óhreinindum er USB-tengið óvirkt og mun ekki greina aukabúnað.\n\nÞú færð tilkynningu þegar öruggt er að nota USB-tengið aftur."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"Kveikt var á USB-tengi til að greina hleðslutæki og aukabúnað"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Raddaðstoð"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Veski"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"QR-kóðaskanni"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"Taka úr lás"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"Tækið er læst"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Andlit skannað"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Senda"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"Andlit þekkist ekki"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Nota fingrafar í staðinn"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth tengt."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"Staða rafhlöðu óþekkt."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"Flugstilling"</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"Kveikt á VPN."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"<xliff:g id="NUMBER">%d</xliff:g> prósent á rafhlöðu."</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Rafhlaða í <xliff:g id="PERCENTAGE">%1$s</xliff:g> prósentum, um það bil <xliff:g id="TIME">%2$s</xliff:g> eftir miðað við notkun þína"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Rafhlaða í <xliff:g id="PERCENTAGE">%1$d</xliff:g> prósentum, um það bil <xliff:g id="TIME">%2$s</xliff:g> eftir miðað við notkun þína"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Rafhlaða í hleðslu, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"Sjá allar tilkynningar"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"Fjarriti virkur."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Titrar við hringingu."</string>
@@ -386,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Þegar þú deilir, tekur upp eða sendir út forrit hefur <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> aðgang að öllu sem sést eða spilast í viðkomandi forriti. Passaðu því upp á aðgangsorð, greiðsluupplýsingar, skilaboð eða aðrar viðkvæmar upplýsingar."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Áfram"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Deila eða taka upp forrit"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Leyfa þessu forriti að deila eða taka upp?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Þegar þú deilir, tekur upp eða sendir út fær þetta forrit aðgang að öllu sem sést á skjánum eða spilast í tækinu. Passaðu því upp á aðgangsorð, greiðsluupplýsingar, skilaboð eða aðrar viðkvæmar upplýsingar."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Þegar þú deilir, tekur upp eða sendir út forrit hefur viðkomandi forrit aðgang að öllu sem sést eða spilast í forritinu. Passaðu því upp á aðgangsorð, greiðsluupplýsingar, skilaboð eða aðrar viðkvæmar upplýsingar."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Útilokað af kerfisstjóra"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"Slökkt er á skjáupptöku í tækjareglum"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Hreinsa allt"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Stjórna"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Ferill"</string>
@@ -511,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Taktu úr lás til að nota"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Vandamál kom upp við að sækja kortin þín. Reyndu aftur síðar"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Stillingar fyrir læstan skjá"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"Skanna QR-kóða"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Vinnusnið"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Flugstilling"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Ekki mun heyrast í vekjaranum <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -794,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Stækka allan skjáinn"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Stækka hluta skjásins"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Rofi"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Leyfa skáflettingu"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Breyta stærð"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"Breyta gerð stækkunar"</string>
@@ -1024,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"k:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"Veita <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> aðgang að öllum annálum í tækinu?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"Leyfa aðgang í eitt skipti"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Ekki leyfa"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"Annálar tækisins skrá það sem gerist í tækinu. Forrit geta notað þessa annála til að finna og lagfæra vandamál.\n\nTilteknir annálar innihalda viðkvæmar upplýsingar og því skaltu einungis veita forritum sem þú treystir aðgang að öllum annálum tækisins. \n\nEf þú veitir þessu forriti ekki aðgang að öllum annálum tækisins hefur það áfram aðgang að eigin annálum. Framleiðandi tækisins getur þó hugsanlega opnað tiltekna annála eða upplýsingar í tækinu."</string>
</resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 255885ec87ec..4a893edf7043 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"Consenti sempre da questo computer"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"Consenti"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"Debug USB non consentito"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"L\'utente che ha eseguito l\'accesso a questo dispositivo non può attivare il debug USB. Per utilizzare questa funzione, passa all\'utente principale."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"L\'utente che ha eseguito l\'accesso a questo dispositivo non può attivare il debug USB. Per usare questa funzionalità, passa a un utente amministratore."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Vuoi cambiare la lingua di sistema con la lingua <xliff:g id="LANGUAGE">%1$s</xliff:g>?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Cambio della lingua di sistema richiesto da un altro dispositivo"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Cambia lingua"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"Consenti sempre su questa rete"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"Consenti"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Debug wireless non consentito"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"L\'utente che ha eseguito l\'accesso a questo dispositivo non può attivare il debug wireless. Per utilizzare questa funzionalità, passa all\'utente principale."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"L\'utente che ha eseguito l\'accesso a questo dispositivo non può attivare il debug wireless. Per usare questa funzionalità, passa a un utente amministratore."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"Porta USB disattivata"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"Per proteggere il dispositivo da liquidi o detriti, la porta USB è stata disattivata e non rileverà gli accessori.\n\nTi avviseremo quando sarà di nuovo possibile utilizzarla."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"Porta USB attivata per rilevare caricabatterie e accessori"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Voice Assist"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"Scanner codici QR"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"Sblocca"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"Dispositivo bloccato"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Scansione del viso"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Invia"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"Volto non riconosciuto"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Usa l\'impronta"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth collegato."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"Percentuale della batteria sconosciuta."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"Modalità aereo."</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN attiva."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"Batteria: <xliff:g id="NUMBER">%d</xliff:g> percento."</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Livello della batteria: <xliff:g id="PERCENTAGE">%1$s</xliff:g> percento. Tempo rimanente in base al tuo utilizzo: <xliff:g id="TIME">%2$s</xliff:g>"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Livello della batteria: <xliff:g id="PERCENTAGE">%1$d</xliff:g> percento. Tempo rimanente in base al tuo utilizzo: <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Batteria in carica, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"Visualizza tutte le notifiche"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"Telescrivente abilitata."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Suoneria vibrazione."</string>
@@ -386,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Quando condividi, registri o trasmetti un\'app, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ha accesso a qualsiasi elemento visualizzato o riprodotto sull\'app. Presta quindi attenzione a password, dati di pagamento, messaggi o altre informazioni sensibili."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Continua"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Condividi o registra un\'app"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Consentire all\'app di condividere o registrare?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Quando condividi, registri o trasmetti, l\'app ha accesso a qualsiasi elemento visibile sul tuo schermo o in riproduzione sul tuo dispositivo. Presta quindi attenzione a password, dati di pagamento, messaggi o altre informazioni sensibili."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Quando condividi, registri o trasmetti un\'app, questa app ha accesso a qualsiasi elemento visualizzato o riprodotto su quell\'app. Presta quindi attenzione a password, dati di pagamento, messaggi o altre informazioni sensibili."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Bloccata dall\'amministratore IT"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"L\'acquisizione schermo è disattivata dai criteri relativi ai dispositivi"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Cancella tutto"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Gestisci"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Cronologia"</string>
@@ -511,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Sblocca per usare"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Si è verificato un problema durante il recupero delle tue carte. Riprova più tardi."</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Impostazioni schermata di blocco"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"Scansiona codice QR"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Profilo di lavoro"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Modalità aereo"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Non sentirai la tua prossima sveglia <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -794,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Ingrandisci l\'intero schermo"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Ingrandisci parte dello schermo"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Opzione"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Consenti lo scorrimento diagonale"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Ridimensiona"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"Modifica il tipo di ingrandimento"</string>
@@ -1024,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM g"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"Vuoi consentire all\'app <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> di accedere a tutti i log del dispositivo?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"Consenti accesso una tantum"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Non consentire"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"I log del dispositivo registrano tutto ciò che succede sul tuo dispositivo. Le app possono usare questi log per individuare problemi e correggerli.\n\nAlcuni log potrebbero contenere informazioni sensibili, quindi concedi l\'accesso a tutti i log del dispositivo soltanto alle app attendibili. \n\nSe le neghi l\'accesso a tutti i log del dispositivo, questa app può comunque accedere ai propri log. Il produttore del tuo dispositivo potrebbe essere comunque in grado di accedere ad alcuni log o informazioni sul dispositivo."</string>
</resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 8611c27270e1..08224156179d 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"אפשר תמיד מהמחשב הזה"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"יש אישור"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"‏לא ניתן לבצע ניפוי באגים ב-USB"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"‏למשתמש המחובר לחשבון במכשיר הזה אין אפשרות להפעיל ניפוי באגים ב-USB. כדי להשתמש בתכונה הזו יש לעבור אל המשתמש הראשי."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"‏למשתמש המחובר לחשבון במכשיר הזה אין אפשרות להפעיל ניפוי באגים ב-USB. כדי להשתמש בתכונה הזו יש לעבור אל משתמש עם הרשאת אדמין."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"רוצה לשנות את שפת המערכת ל<xliff:g id="LANGUAGE">%1$s</xliff:g>?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"התקבלה בקשה ממכשיר אחר לשינוי שפת המערכת"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"שינוי שפה"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"לאשר תמיד ברשת הזו"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"אישור"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"אין הרשאה לניפוי באגים אלחוטי"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"למשתמש המחובר לחשבון במכשיר הזה אין אפשרות להפעיל ניפוי באגים אלחוטי. כדי להשתמש בתכונה הזו, יש לעבור אל המשתמש הראשי."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"למשתמש המחובר לחשבון במכשיר הזה אין אפשרות להפעיל ניפוי באגים אלחוטי. כדי להשתמש בתכונה הזו, יש לעבור אל משתמש עם הרשאת אדמין."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"‏יציאת ה-USB מושבתת"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"‏כדי להגן על המכשיר שלך מנוזלים או חלקיקים, יציאת ה-USB מושבתת ולא מזהה אביזרים כלל.\n\nתתקבל התראה כשניתן יהיה להשתמש ביציאת ה-USB."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"‏יציאת USB הופעלה לזיהוי מטענים ואביזרים"</string>
@@ -125,7 +125,7 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"האסיסטנט"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"ארנק"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"‏סורק קודי QR"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"ביטול נעילה"</string>
+ <string name="accessibility_unlock_button" msgid="3613812140816244310">"הנעילה מבוטלת"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"המכשיר נעול"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"סורק פנים"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"שליחה"</string>
@@ -168,7 +168,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"לא ניתן לזהות את הפנים"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"שימוש בטביעת אצבע במקום זאת"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"‏Bluetooth מחובר."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"אחוז טעינת הסוללה לא ידוע."</string>
@@ -180,8 +180,10 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"מצב טיסה"</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"‏VPN פועל."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"<xliff:g id="NUMBER">%d</xliff:g> אחוזים של סוללה."</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"רמת הטעינה בסוללה: <xliff:g id="PERCENTAGE">%1$s</xliff:g> אחוזים, הזמן הנותר המשוער על סמך השימוש שלך: <xliff:g id="TIME">%2$s</xliff:g>"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"רמת הטעינה בסוללה: <xliff:g id="PERCENTAGE">%1$d</xliff:g> אחוזים, הזמן הנותר המשוער על סמך השימוש שלך: <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"הסוללה בטעינה, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
+ <string name="accessibility_battery_level_charging_paused" msgid="1716051308782906917">"<xliff:g id="PERCENTAGE">%d</xliff:g> אחוזים של סוללה. הטעינה בהשהיה כדי להגן על הסוללה."</string>
+ <string name="accessibility_battery_level_charging_paused_with_estimate" msgid="4006089349465741762">"רמת הטעינה בסוללה: <xliff:g id="PERCENTAGE">%1$d</xliff:g> אחוזים, הזמן הנותר המשוער על סמך השימוש שלך: <xliff:g id="TIME">%2$s</xliff:g>. הטעינה בהשהיה כדי להגן על הסוללה."</string>
<string name="accessibility_overflow_action" msgid="8555835828182509104">"הצגת כל ההתראות"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"‏TeleTypewriter מופעל"</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"צלצול ורטט."</string>
@@ -386,16 +388,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"‏בזמן שיתוף, הקלטה או העברה (cast) של אפליקציה, תהיה ל-<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> גישה לכל מה שגלוי באפליקציה או מופעל מהאפליקציה. כדאי להיזהר עם סיסמאות, פרטי תשלום, הודעות או מידע רגיש אחר."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"המשך"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"שיתוף או הקלטה של אפליקציה"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"לאפשר לאפליקציה הזו לשתף או להקליט?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"‏בזמן שיתוף, הקלטה או העברה (cast) תהיה לאפליקציה הזו גישה לכל הפרטים שגלויים במסך שלך או מופעלים מהמכשיר שלך. כדאי להיזהר ולא לחשוף סיסמאות, פרטי תשלום, הודעות או מידע רגיש אחר."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"‏בזמן שיתוף, הקלטה או העברה (cast) של אפליקציה, תהיה לאפליקציה הזו גישה לכל מה שמוצג בה או מופעל ממנה. כדאי להיזהר ולא לחשוף סיסמאות, פרטי תשלום, הודעות או מידע רגיש אחר."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"‏נחסם על ידי מנהל ה-IT"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"צילום המסך מושבת בגלל מדיניות המכשיר"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"ניקוי הכול"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"ניהול"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"היסטוריה"</string>
@@ -511,7 +508,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"יש לבטל את הנעילה כדי להשתמש"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"הייתה בעיה בקבלת הכרטיסים שלך. כדאי לנסות שוב מאוחר יותר"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"הגדרות מסך הנעילה"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"‏סריקת קוד QR"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"פרופיל עבודה"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"מצב טיסה"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"לא ניתן יהיה לשמוע את ההתראה הבאה שלך <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -794,6 +792,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"הגדלה של המסך המלא"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"הגדלת חלק מהמסך"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"מעבר"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"הפעלת גלילה באלכסון"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"שינוי גודל"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"שינוי סוג ההגדלה"</string>
@@ -1024,4 +1024,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"‏יום EEE,‏ d בMMM"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"לתת לאפליקציה <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> הרשאת גישה לכל יומני המכשיר?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"הרשאת גישה חד-פעמית"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"אין אישור"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"ביומני המכשיר מתועדת הפעילות במכשיר. האפליקציות יכולות להשתמש ביומנים האלה כדי למצוא בעיות ולפתור אותן.\n\nהמידע בחלק מהיומנים יכול להיות רגיש, לכן יש לתת הרשאת גישה לכל היומנים של המכשיר רק לאפליקציות שסומכים עליהן. \n\nגם אם האפליקציה הזו לא תקבל הרשאת גישה לכל יומני המכשיר, היא תוכל לגשת ליומנים שלה. יכול להיות שליצרן המכשיר עדיין תהיה גישה לחלק מהיומנים או למידע במכשיר שלך."</string>
</resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index b0d54379b48f..977d2daae0d3 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"このパソコンからの USB デバッグを常に許可する"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"許可"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"USB デバッグは許可されていません"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"このデバイスに現在ログインしているユーザーでは、USB デバッグを ON にすることはできません。この機能を使用するには、メインユーザーに切り替えてください。"</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"このデバイスに現在ログインしているユーザーは USB デバッグを ON にできません。この機能を使用するには、管理者ユーザーに切り替えてください。"</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"システム言語を<xliff:g id="LANGUAGE">%1$s</xliff:g>に変更しますか?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"他のデバイスからシステム言語の変更が要求されました"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"言語を変更"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"このネットワークで常に許可する"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"許可"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"ワイヤレス デバッグは許可されていません"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"このデバイスに現在ログインしているユーザーでは、ワイヤレス デバッグを ON にすることはできません。この機能を使用するには、メインユーザーに切り替えてください。"</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"このデバイスに現在ログインしているユーザーはワイヤレス デバッグを ON にできません。この機能を使用するには、管理者ユーザーに切り替えてください。"</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"USB ポート無効"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"液体やゴミからデバイスを保護するため、USB ポートは無効になっています。アクセサリの検出は行われません。\n\nUSB ポートを再び安全に使用できるようになりましたらお知らせします。"</string>
<string name="usb_port_enabled" msgid="531823867664717018">"USB ポートが有効になり、充電器やアクセサリを検出できるようになりました"</string>
@@ -125,7 +125,7 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"音声アシスト"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"ウォレット"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"QR コードスキャナ"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"ロック解除"</string>
+ <string name="accessibility_unlock_button" msgid="3613812140816244310">"ロック解除済み"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"デバイスはロックされています"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"顔のスキャン"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"送信"</string>
@@ -168,7 +168,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"顔を認識できません"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"指紋認証をお使いください"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetoothに接続済み。"</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"バッテリー残量は不明です。"</string>
@@ -180,8 +180,10 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"機内モード。"</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN は ON です。"</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"バッテリー残量: <xliff:g id="NUMBER">%d</xliff:g>パーセント"</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"バッテリー残量: <xliff:g id="PERCENTAGE">%1$s</xliff:g>、およそ <xliff:g id="TIME">%2$s</xliff:g> にバッテリー切れ(使用状況に基づく)"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"バッテリー残量: <xliff:g id="PERCENTAGE">%1$d</xliff:g>、およそ <xliff:g id="TIME">%2$s</xliff:g> にバッテリー切れ(使用状況に基づく)"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"電池充電中: <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>パーセント"</string>
+ <string name="accessibility_battery_level_charging_paused" msgid="1716051308782906917">"バッテリー残量: <xliff:g id="PERCENTAGE">%d</xliff:g>%%。バッテリー保護のため、充電を一時停止しました。"</string>
+ <string name="accessibility_battery_level_charging_paused_with_estimate" msgid="4006089349465741762">"バッテリー残量: <xliff:g id="PERCENTAGE">%1$d</xliff:g>%%、およそ <xliff:g id="TIME">%2$s</xliff:g> にバッテリー切れ(使用状況に基づく)。バッテリー保護のため、充電を一時停止しました。"</string>
<string name="accessibility_overflow_action" msgid="8555835828182509104">"通知をすべて表示"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"テレタイプライターが有効です。"</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"バイブレーション着信。"</string>
@@ -386,16 +388,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"アプリの共有、録画、キャスト中は、そのアプリで表示されている内容や再生している内容に <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> がアクセスできるため、パスワード、お支払いの詳細、メッセージなどの機密情報にご注意ください。"</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"続行"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"アプリの共有、録画"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"このアプリに共有や録画を許可しますか?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"共有、録画、キャスト中は、画面に表示されている内容やデバイスで再生している内容にこのアプリがアクセスできるため、パスワード、お支払いの詳細、メッセージなどの機密情報にご注意ください。"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"アプリの共有、録画、キャスト中は、そのアプリで表示されている内容や再生している内容にこのアプリがアクセスできるため、パスワード、お支払いの詳細、メッセージなどの機密情報にご注意ください。"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"IT 管理者によりブロックされました"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"デバイス ポリシーに基づき、画面のキャプチャが無効になりました"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"すべて消去"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"管理"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"履歴"</string>
@@ -456,7 +453,7 @@
<string name="volume_odi_captions_content_description" msgid="4172765742046013630">"字幕のオーバーレイ"</string>
<string name="volume_odi_captions_hint_enable" msgid="2073091194012843195">"有効にする"</string>
<string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"無効にする"</string>
- <string name="sound_settings" msgid="8874581353127418308">"着信音とバイブレーション"</string>
+ <string name="sound_settings" msgid="8874581353127418308">"サウンドとバイブレーション"</string>
<string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"設定"</string>
<string name="screen_pinning_title" msgid="9058007390337841305">"アプリは固定されています"</string>
<string name="screen_pinning_description" msgid="8699395373875667743">"固定を解除するまで画面が常に表示されるようになります。[戻る] と [最近] を同時に押し続けると固定が解除されます。"</string>
@@ -511,7 +508,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"ロックを解除して使用"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"カードの取得中に問題が発生しました。しばらくしてからもう一度お試しください"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"ロック画面の設定"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"QR コードのスキャン"</string>
+ <string name="qr_code_scanner_title" msgid="1938155688725760702">"QR コードスキャナ"</string>
<string name="status_bar_work" msgid="5238641949837091056">"仕事用プロファイル"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"機内モード"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"次回のアラーム(<xliff:g id="WHEN">%1$s</xliff:g>)は鳴りません"</string>
@@ -794,6 +791,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"画面全体を拡大します"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"画面の一部を拡大します"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"スイッチ"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"斜めスクロールを許可"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"サイズ変更"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"拡大の種類を変更"</string>
@@ -1024,4 +1023,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> にすべてのデバイスログへのアクセスを許可しますか?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"1 回限りのアクセスを許可"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"許可しない"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"デバイスのログに、このデバイスで発生したことが記録されます。アプリは問題を検出、修正するためにこれらのログを使用することができます。\n\nログによっては機密性の高い情報が含まれている可能性があるため、すべてのデバイスログへのアクセスは信頼できるアプリにのみ許可してください。\n\nすべてのデバイスログへのアクセスを許可しなかった場合も、このアプリはアプリ独自のログにアクセスできます。また、デバイスのメーカーもデバイスの一部のログや情報にアクセスできる可能性があります。"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index f7725aee466d..486639a384ba 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"ყოველთვის დართე ნება ამ კომპიუტერიდან."</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"დაშვება"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"USB ხარვეზების გამართვა ნებადართული არაა"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"ამ მოწყობილობაზე ამჟამად შესულ მომხმარებელს არ შეუძლია USB ხარვეზების გამართვის ფუნქციის ჩართვა. ამ ფუნქციის გამოსაყენებლად, მიუერთდით მთავარ მომხმარებელს."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"ამ მოწყობილობაზე ამჟამად შესულ მომხმარებელს არ შეუძლია USB ხარვეზების გამართვის ფუნქციის ჩართვა. ამ ფუნქციის გამოსაყენებლად, მიუერთდით ადმინისტრატორ მომხმარებელს."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"გსურთ, სისტემის ენა შეიცვალოს და გახდეს <xliff:g id="LANGUAGE">%1$s</xliff:g>?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"სისტემის ენის შეცვლა მოითხოვა სხვა მოწყობილობამ"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"ენის შეცვლა"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"ყოველთვის დაშვება ამ ქსელში"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"დაშვება"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"შეცდომების უსადენო გამართვა არ არის დაშვებული"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"ამ მოწყობილობაზე ამჟამად შესულ მომხმარებელს არ შეუძლია შეცდომების უსადენო გამართვის ჩართვა. ამ ფუნქციის გამოსაყენებლად, გადაერთეთ მთავარ მომხმარებელზე."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"ამ მოწყობილობაზე ამჟამად შესულ მომხმარებელს არ შეუძლია შეცდომების უსადენო გამართვის ჩართვა. ამ ფუნქციის გამოსაყენებლად, გადაერთეთ ადმინისტრატორ მომხმარებელზე."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"USB პორტი გათიშულია"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"თქვენი მოწყობილობის სითხის ან ნადებისგან დასაცავად, USB პორტი გათიშულია და ვერცერთი აქსესუარის აღმოჩენას ვერ შეძლებს.\n\nთქვენ მიიღებთ შეტყობინებას, როდესაც USB პორტის გამოყენება კვლავ შესაძლებელი იქნება."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"USB პორტი ჩართულია დამტენებისა და აქსესუარების აღმოსაჩენად"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"ხმოვანი დახმარება"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"საფულე"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"QR კოდის სკანერი"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"განბლოკვა"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"მოწყობილობა ჩაკეტილია"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"მიმდინარეობს სახის სკანირება"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"გაგზავნა"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"სახის ამოცნობა შეუძლებ."</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"გამოიყენეთ თითის ანაბეჭდი"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth დაკავშირებულია."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"ბატარეის პროცენტული მაჩვენებელი უცნობია."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"თვითმფრინავის რეჟიმი"</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN ჩართულია."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"ბატარეა: <xliff:g id="NUMBER">%d</xliff:g> პროცენტი."</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"ბატარეა <xliff:g id="PERCENTAGE">%1$s</xliff:g> პროცენტზეა, მოხმარების გათვალისწინებით დარჩა დაახლოებით <xliff:g id="TIME">%2$s</xliff:g>"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"ბატარეა <xliff:g id="PERCENTAGE">%1$d</xliff:g> პროცენტზეა, მოხმარების გათვალისწინებით დარჩა დაახლოებით <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"ბატარეა იტენება. ამჟამად არის <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> პროცენტი."</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"ყველა შეტყობინების ნახვა"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"ტელეტაიპი ჩართულია."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"ვიბრაციის რეჟიმი."</string>
@@ -386,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"აპის გაზიარებისას, ჩაწერისას ან ტრანსლირებისას <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> აქვს წვდომა აქვს ყველაფერზე, რაც ჩანს აპში ან ითამაშეთ. ამიტომ იყავით ფრთხილად პაროლებთან, გადახდის დეტალებთან, შეტყობინებებთან ან სხვა მგრძნობიარე ინფორმაციასთან."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"გაგრძელება"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"გააზიარეთ ან ჩაწერეთ აპი"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"გსურთ ამ აპისთვის გაზიარების ან ჩაწერის უფლების მიცემა?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"როდესაც თქვენ აზიარებთ, იწერთ ან ტრანსლირებთ, ამ აპს აქვს წვდომა ყველაფერზე, რაც ჩანს თქვენს ეკრანზე ან უკრავს თქვენს მოწყობილობაზე. ამიტომ იყავით ფრთხილად პაროლებთან, გადახდის დეტალებთან, შეტყობინებებთან ან სხვა სენსიტიურ ინფორმაციასთან."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"როდესაც თქვენ აზიარებთ, იწერთ ან ტრანსლირებთ, ამ აპს აქვს წვდომა ყველაფერზე, რაც ჩანს თქვენს ეკრანზე ან უკრავს თქვენს მოწყობილობაზე. ამიტომ იყავით ფრთხილად პაროლებთან, გადახდის დეტალებთან, შეტყობინებებთან ან სხვა სენსიტიურ ინფორმაციასთან."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"დაბლოკილია თქვენი IT-ადმინისტრატორის მიერ"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"ეკრანის აღბეჭდვა გამორთულია მოწყობილობის წესების თანახმად"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"ყველას გასუფთავება"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"მართვა"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"ისტორია"</string>
@@ -511,7 +511,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"გამოსაყენებლად განბლოკვა"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"თქვენი ბარათების მიღებისას პრობლემა წარმოიშვა. ცადეთ ხელახლა მოგვიანებით"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"ჩაკეტილი ეკრანის პარამეტრები"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"QR კოდის სკანირება"</string>
+ <string name="qr_code_scanner_title" msgid="1938155688725760702">"QR კოდის სკანერი"</string>
<string name="status_bar_work" msgid="5238641949837091056">"სამსახურის პროფილი"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"თვითმფრინავის რეჟიმი"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"ვერ გაიგონებთ მომდევნო მაღვიძარას <xliff:g id="WHEN">%1$s</xliff:g>-ზე"</string>
@@ -794,6 +794,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"გაადიდეთ სრულ ეკრანზე"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"ეკრანის ნაწილის გადიდება"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"გადართვა"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"დიაგონალური გადახვევის დაშვება"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"ზომის შეცვლა"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"გადიდების ტიპის შეცვლა"</string>
@@ -1024,4 +1026,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"დდდ, თთთ თ"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"სთ:წთ"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"სთ:წთ"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"გსურთ <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g>-ს მიანიჭოთ მოწყობილობის ყველა ჟურნალზე წვდომა?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"ერთჯერადი წვდომის დაშვება"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"არ დაიშვას"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"მოწყობილობის ჟურნალში იწერება, რა ხდება ამ მოწყობილობაზე. აპებს შეუძლია ამ ჟურნალების გამოყენება პრობლემების აღმოსაჩენად და მოსაგვარებლად.\n\nზოგი ჟურნალი შეიძლება სენსიტიური ინფორმაციის მატარებელი იყოს, ამიტომაც მოწყობილობის ყველა ჟურნალზე წვდომა მხოლოდ სანდო აპებს მიანიჭეთ. \n\nთუ ამ აპს მოწყობილობის ყველა ჟურნალზე წვდომას არ მიანიჭებთ, მას მაინც ექნება წვდომა თქვენს ჟურნალებზე. თქვენი მოწყობილობის მწარმოებელს მაინც შეეძლება თქვენი მოწყობილობის ზოგიერთ ჟურნალსა თუ ინფორმაციაზე წვდომა."</string>
</resources>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index ac77719dd1e2..dc57eee8ca54 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"Осы компьютерден әрқашан рұқсат беру"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"Рұқсат беру"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"USB арқылы түзетуге рұқсат етілмеген"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"Бұл құрылғыға қазір кірген пайдаланушы USB арқылы түзетуді іске қосылмайды. Бұл мүмкіндікті пайдалану үшін негізгі пайдаланушыға ауысыңыз."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"Бұл құрылғыға жаңа кірген пайдаланушы USB арқылы түзетуді қоса алмайды. Бұл мүмкіндікті пайдалану үшін әкімші пайдаланушыға ауысыңыз."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Жүйе тілін басқа тілге (<xliff:g id="LANGUAGE">%1$s</xliff:g>) ауыстырғыңыз келе ме?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Басқа құрылғыдан жүйе тілін өзгерту туралы сұрау жіберілді."</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Тілді өзгерту"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"Осы желіде үнемі рұқсат ету"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"Рұқсат ету"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Сымсыз түзетуге рұқсат етілмейді"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"Бұл құрылғыға жаңа кірген пайдаланушы сымсыз түзетуді іске қоса алмайды. Бұл мүмкіндікті пайдалану үшін негізгі пайдаланушыға ауысыңыз."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"Бұл құрылғыға жаңа кірген пайдаланушы сымсыз түзетуді іске қоса алмайды. Бұл мүмкіндікті пайдалану үшін әкімші пайдаланушыға ауысыңыз."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"USB порты өшірілді"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"Құрылғыңызға сұйықтық немесе қоқыс кіріп кетпеуі үшін, USB порты өшірілген және ешқандай керек-жарақты анықтамайды.\n\nUSB портын қайта пайдалануға болатын кезде хабарландыру аласыз."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"Зарядтағыштар мен аксессуарларды анықтау үшін USB порты қосылды."</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Дауыс көмекшісі"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"QR кодын сканерлеу қолданбасы"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"Бекітпесін ашу"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"Құрылғы құлыпталды."</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Бетті сканерлеу"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Жіберу"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"Бет танылмады."</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Орнына саусақ ізін пайдаланыңыз."</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth қосылған."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"Батарея зарядының мөлшері белгісіз."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"Ұшақ режимі."</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN қосулы."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"Батарея <xliff:g id="NUMBER">%d</xliff:g> пайыз."</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Батарея заряды: <xliff:g id="PERCENTAGE">%1$s</xliff:g> пайыз. Пайдалануға байланысты шамамен <xliff:g id="TIME">%2$s</xliff:g> уақытқа жетеді."</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Батарея заряды: <xliff:g id="PERCENTAGE">%1$d</xliff:g> пайыз. Пайдалануға байланысты шамамен <xliff:g id="TIME">%2$s</xliff:g> уақытқа жетеді."</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Батарея зарядталуда, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> %%."</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"Барлық хабарландыруды қарау"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"Телетайп қосылған."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Қоңырау тербелісі."</string>
@@ -386,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Қолданба экранын бөлісу, жазу не трансляциялау кезінде <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> қолданбасы онда көрінетін не ойнатылатын барлық нәрсені пайдалана алады. Сондықтан құпия сөздерді, төлем туралы мәліметті, хабарларды немесе басқа құпия ақпаратты енгізу кезінде сақ болыңыз."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Жалғастыру"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Қолданба экранын бөлісу не жазу"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Қолданбаға бөлісуге не жазып алуға рұқсат берілсін бе?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Экранды бөлісу, жазып алу не трансляциялау кезінде бұл қолданба экраныңызда көрінетін не құрылғыңызда ойнатылатын барлық нәрсені пайдалана алады. Сондықтан құпия сөздерді, төлем туралы мәліметті, хабарларды немесе басқа құпия ақпаратты енгізу кезінде сақ болыңыз."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Қолданбаны бөлісу, жазып алу не трансляциялау кезінде бұл қолданба онда көрінетін не ойнатылатын барлық нәрсені пайдалана алады. Сондықтан құпия сөздерді, төлем туралы мәліметті, хабарларды немесе басқа құпия ақпаратты енгізу кезінде сақ болыңыз."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Әкімшіңіз бөгеген"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"Құрылғы саясатына байланысты экранды түсіру өшірілді."</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Барлығын тазалау"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Басқару"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Тарих"</string>
@@ -511,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Пайдалану үшін құлыпты ашу"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Карталарыңыз алынбады, кейінірек қайталап көріңіз."</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Экран құлпының параметрлері"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"QR кодын сканерлеу"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Жұмыс профилі"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Ұшақ режимі"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Келесі <xliff:g id="WHEN">%1$s</xliff:g> дабылыңызды есітпейсіз"</string>
@@ -794,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Толық экранды ұлғайту"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Экранның бөлігін ұлғайту"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Ауысу"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Диагональ бойынша айналдыруға рұқсат беру"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Өлшемін өзгерту"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"Ұлғайту түрін өзгерту"</string>
@@ -1024,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"d MMM EEEE"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> қолданбасына құрылғының барлық журналын пайдалануға рұқсат берілсін бе?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"Бір рет рұқсат беру"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Рұқсат бермеу"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"Журналдарға құрылғыда не болып жатқаны жазылады. Қолданбалар бұл журналдарды қате тауып, түзету үшін пайдаланады.\n\nКейбір журналдарда құпия ақпарат болуы мүмкін. Сондықтан құрылғының барлық журналын пайдалану рұқсаты тек сенімді қолданбаларға берілуі керек. \n\nБұл қолданбаға құрылғының барлық журналын пайдалануға рұқсат бермесеңіз де, ол өзінің журналдарын пайдалана береді. Құрылғы өндірушісі де құрылғыдағы кейбір журналдарды немесе ақпаратты пайдалануы мүмкін."</string>
</resources>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 650499048c76..11fd0520cd17 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"អនុញ្ញាត​ជា​និច្ច​សម្រាប់​កុំព្យូទ័រ​នេះ"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"អនុញ្ញាត"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"មិនអនុញ្ញាតការកែកំហុសតាម USB ទេ"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"អ្នកប្រើ​ដែលបច្ចុប្បន្ន​បានចូលគណនី​នៅលើឧបករណ៍នេះ​មិនអាចបើកការកែកំហុស USB បានទេ។ ដើម្បីប្រើមុខងារនេះ សូមប្តូរទៅអ្នកប្រើចម្បង។"</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"អ្នកប្រើ​ប្រាស់ដែលបច្ចុប្បន្ន​បានចូលគណនី​នៅលើឧបករណ៍នេះ​មិនអាចបើកការ​ជួសជុលតាម USB បានទេ។ ដើម្បីប្រើប្រាស់មុខងារនេះ សូមប្ដូរទៅអ្នកប្រើប្រាស់​ដែលជាអ្នកគ្រប់គ្រង។"</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"តើអ្នកចង់ប្ដូរ​ភាសាប្រព័ន្ធ​ទៅភាសា​<xliff:g id="LANGUAGE">%1$s</xliff:g>​ដែរទេ?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"ការប្ដូរភាសា​ប្រព័ន្ធដែលបានស្នើសុំ​ដោយ​ឧបករណ៍ផ្សេងទៀត"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"​ប្ដូរ​ភាសា"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"អនុញ្ញាត​នៅលើ​បណ្ដាញ​នេះ​ជានិច្ច"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"អនុញ្ញាត"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"មិន​អនុញ្ញាត​ការជួសជុល​ដោយឥតខ្សែ​ទេ"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"អ្នក​ប្រើប្រាស់​ដែលបច្ចុប្បន្ន​បាន​ចូលគណនី​នៅលើ​ឧបករណ៍​នេះ​មិនអាច​បើក​ការជួសជុល​ដោយឥតខ្សែ​បានទេ។ ដើម្បី​ប្រើ​មុខងារ​នេះ សូម​ប្ដូរ​ទៅ​អ្នក​ប្រើប្រាស់​ចម្បង។"</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"អ្នក​ប្រើប្រាស់​ដែលបច្ចុប្បន្ន​បាន​ចូលគណនី​នៅលើ​ឧបករណ៍​នេះ​មិនអាច​បើក​ការជួសជុល​ដោយឥតខ្សែ​បានទេ។ ដើម្បី​ប្រើប្រាស់​មុខងារ​នេះ សូម​ប្ដូរ​ទៅ​អ្នកប្រើប្រាស់​ដែលជាអ្នកគ្រប់គ្រង។"</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"បានបិទរន្ធ USB"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"ដើម្បី​ការពារ​ឧបករណ៍​របស់អ្នកកុំឱ្យ​ចូលទឹក ឬ​កម្ទេចផ្សេងៗ រន្ធ USB ត្រូវបានបិទ ហើយ​នឹង​មិនស្គាល់​គ្រឿង​បរិក្ខារ​នោះទេ។\n\nអ្នកនឹង​ទទួលបាន​ការជូនដំណឺង នៅពេល​អ្នកអាច​ប្រើប្រាស់​រន្ធ USB ម្ដងទៀត។"</string>
<string name="usb_port_enabled" msgid="531823867664717018">"បាន​បើក​រន្ធ USB ដើម្បី​សម្គាល់​ឆ្នាំងសាក និងគ្រឿងផ្សេងៗ"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"ជំនួយសំឡេង"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"កម្មវិធីស្កេនកូដ QR"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"ដោះ​​សោ"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"បានចាក់សោ​ឧបករណ៍"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"ការ​ស្កេន​មុខ"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"ផ្ញើ"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"មិនអាចសម្គាល់មុខបានទេ"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"ប្រើស្នាមម្រាមដៃជំនួសវិញ​"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"បាន​តភ្ជាប់​ប៊្លូធូស។"</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"មិនដឹងអំពី​ភាគរយថ្មទេ។"</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"ពេល​ជិះ​យន្តហោះ"</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"បើក VPN ។"</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"ថ្ម <xliff:g id="NUMBER">%d</xliff:g> ភាគរយ។"</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"ថ្ម <xliff:g id="PERCENTAGE">%1$s</xliff:g> ភាគរយ អាចប្រើបាន​ប្រហែល <xliff:g id="TIME">%2$s</xliff:g> ទៀត ផ្អែក​លើការ​ប្រើប្រាស់​របស់អ្នក"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"ថ្ម <xliff:g id="PERCENTAGE">%1$d</xliff:g> ភាគរយ អាចប្រើបាន​ប្រហែល <xliff:g id="TIME">%2$s</xliff:g> ទៀត ផ្អែក​លើការ​ប្រើប្រាស់​របស់អ្នក"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"កំពុងសាកថ្ម <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> ភាគរយ"</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"មើល​ការជូនដំណឹង​ទាំងអស់"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"បាន​បើក​ម៉ាស៊ីន​អង្គុលីលេខ​"</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"កម្មវិធី​រោទ៍​ញ័រ។"</string>
@@ -386,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"នៅពេលអ្នកកំពុងចែករំលែក ថត ឬបញ្ជូនកម្មវិធី <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> មានសិទ្ធិចូលប្រើប្រាស់អ្វីៗដែលបង្ហាញ ឬលេងនៅលើកម្មវិធីនោះ។ ដូច្នេះ សូមប្រុងប្រយ័ត្នចំពោះពាក្យសម្ងាត់ ព័ត៌មាន​លម្អិតអំពី​ការ​ទូទាត់ប្រាក់ សារ ឬព័ត៌មានរសើបផ្សេងទៀត។"</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"បន្ត"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"ចែករំលែក ឬថតកម្មវិធី"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"អនុញ្ញាតកម្មវិធីនេះឱ្យចែករំលែក ឬថតឬ?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"នៅពេលអ្នក​កំពុងចែករំលែក ថត ឬបញ្ជូន កម្មវិធីនេះ​មានសិទ្ធិចូលប្រើប្រាស់អ្វីៗ​ដែលបង្ហាញឱ្យឃើញនៅលើ​អេក្រង់របស់អ្នក ឬលេងនៅលើឧបករណ៍របស់អ្នក។ ដូច្នេះ សូមប្រុងប្រយ័ត្នចំពោះពាក្យសម្ងាត់ ព័ត៌មាន​លម្អិតអំពី​ការ​ទូទាត់ប្រាក់ សារ ឬព័ត៌មានរសើបផ្សេងទៀត។"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"នៅពេលអ្នក​កំពុងចែករំលែក ថត ឬបញ្ជូន​កម្មវិធី កម្មវិធីនេះ​មានសិទ្ធិចូលប្រើប្រាស់អ្វីៗ​ដែលបង្ហាញ ឬលេងនៅលើ​កម្មវិធីនោះ។ ដូច្នេះ សូមប្រុងប្រយ័ត្នចំពោះ​ពាក្យសម្ងាត់ ព័ត៌មានលម្អិតអំពីការទូទាត់ប្រាក់ សារ ឬព័ត៌មានរសើប​ផ្សេងទៀត។"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"បានទប់ស្កាត់ដោយអ្នកគ្រប់គ្រង​ផ្នែកព័ត៌មានវិទ្យា​របស់អ្នក"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"ការថតអេក្រង់ត្រូវបានបិទ​ដោយគោលការណ៍ឧបករណ៍"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"សម្អាត​ទាំងអស់"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"គ្រប់គ្រង"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"ប្រវត្តិ"</string>
@@ -511,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"ដោះសោដើម្បីប្រើប្រាស់"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"មានបញ្ហា​ក្នុងការទាញយក​កាត​របស់អ្នក សូម​ព្យាយាមម្ដងទៀត​នៅពេលក្រោយ"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"ការកំណត់អេក្រង់ចាក់សោ"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"ស្កេន​កូដ QR"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"ប្រវត្តិរូបការងារ"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"ពេលជិះយន្តហោះ"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"អ្នកនឹងមិនលឺម៉ោងរោទ៍ <xliff:g id="WHEN">%1$s</xliff:g> បន្ទាប់របស់អ្នកទេ"</string>
@@ -794,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"ពង្រីក​ពេញអេក្រង់"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"ពង្រីក​ផ្នែកនៃ​អេក្រង់"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"ប៊ូតុងបិទបើក"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"អនុញ្ញាត​ការរំកិលបញ្ឆិត"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"ប្ដូរ​ទំហំ"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"ប្ដូរ​ប្រភេទ​ការពង្រីក"</string>
@@ -1024,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"អនុញ្ញាតឱ្យ <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> ចូលប្រើកំណត់ហេតុឧបករណ៍ទាំងអស់ឬ?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"អនុញ្ញាតឱ្យចូលប្រើ​ប្រាស់តែមួយលើក"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"មិនអនុញ្ញាត"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"កំណត់ហេតុឧបករណ៍កត់ត្រាអ្វីដែលកើតឡើងនៅលើឧបករណ៍របស់អ្នក។ កម្មវិធីអាចប្រើកំណត់ហេតុទាំងនេះ ដើម្បីស្វែងរក និងដោះស្រាយបញ្ហាបាន។\n\nកំណត់ហេតុមួយចំនួនអាចមានព័ត៌មានរសើប ដូច្នេះសូមអនុញ្ញាតឱ្យចូលប្រើកំណត់ហេតុឧបករណ៍ទាំងអស់សម្រាប់តែកម្មវិធីដែលអ្នកទុកចិត្តប៉ុណ្ណោះ។ \n\nប្រសិនបើអ្នកមិនអនុញ្ញាតឱ្យកម្មវិធីនេះចូលប្រើកំណត់ហេតុឧបករណ៍ទាំងអស់ទេ កម្មវិធីនេះនៅតែអាចចូលប្រើកំណត់ហេតុរបស់ខ្លួនផ្ទាល់បាន។ ក្រុមហ៊ុន​ផលិត​ឧបករណ៍របស់អ្នក​ប្រហែលជា​នៅតែអាចចូលប្រើ​កំណត់ហេតុ ឬព័ត៌មានមួយចំនួន​នៅលើឧបករណ៍​របស់អ្នក​បានដដែល។"</string>
</resources>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index e1124bbaf7ab..51944a93a134 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"ಈ ಕಂಪ್ಯೂಟರ್‌ನಿಂದ ಯಾವಾಗಲೂ ಅನುಮತಿಸಿ"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"ಅನುಮತಿಸಿ"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"USB ಡೀಬಗ್ ಮಾಡುವಿಕೆಯನ್ನು ಅನುಮತಿಸಲಾಗಿಲ್ಲ"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"ಬಳಕೆದಾರರು ಪ್ರಸ್ತುತ ಈ ಸಾಧನಕ್ಕೆ ಸೈನ್ ಇನ್ ಮಾಡಿದ್ದಾರೆ USB ಡೀಬಗ್ ಮಾಡುವುದನ್ನು ಆನ್ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ. ಈ ವೈಶಿಷ್ಟ್ಯವನ್ನು ಬಳಸಲು, ಪ್ರಾಥಮಿಕ ಬಳಕೆದಾರರಿಗೆ ಬದಲಾಯಿಸಿ."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"ಬಳಕೆದಾರರು ಪ್ರಸ್ತುತ ಈ ಸಾಧನಕ್ಕೆ ಸೈನ್ ಇನ್ ಮಾಡಿದ್ದಾರೆ USB ಡೀಬಗ್ ಮಾಡುವುದನ್ನು ಆನ್ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ. ಈ ಫೀಚರ್ ಅನ್ನು ಬಳಸಲು, ನಿರ್ವಾಹಕ ಬಳಕೆದಾರರಿಗೆ ಬದಲಾಯಿಸಿ."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"ಸಿಸ್ಟಮ್ ಭಾಷೆಯನ್ನು <xliff:g id="LANGUAGE">%1$s</xliff:g> ಭಾಷೆಗೆ ಬದಲಾಯಿಸಲು ನೀವು ಬಯಸುತ್ತೀರಾ?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"ಬೇರೊಂದು ಸಾಧನದಿಂದ ಸಿಸ್ಟಮ್ ಭಾಷೆಯ ಬದಲಾವಣೆಯನ್ನು ವಿನಂತಿಸಲಾಗಿದೆ"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"ಭಾಷೆಯನ್ನು ಬದಲಾಯಿಸಿ"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"ಈ ನೆಟ್‌ವರ್ಕ್‌ನಲ್ಲಿ ಅನುಮತಿಸಿ"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"ಅನುಮತಿಸಿ"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"ವೈರ್‌ಲೆಸ್ ಡೀಬಗ್ ಮಾಡುವಿಕೆಯನ್ನು ಅನುಮತಿಸಲಾಗಿಲ್ಲ"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"ಬಳಕೆದಾರರು ಪ್ರಸ್ತುತ ಈ ಸಾಧನಕ್ಕೆ ಸೈನ್ ಇನ್ ಮಾಡಿದ್ದಾರೆ ವೈರ್‌ಲೆಸ್ ಡೀಬಗ್ ಮಾಡುವುದನ್ನು ಆನ್ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ. ಈ ವೈಶಿಷ್ಟ್ಯವನ್ನು ಬಳಸಲು, ಪ್ರಾಥಮಿಕ ಬಳಕೆದಾರರಿಗೆ ಬದಲಾಯಿಸಿ."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"ಬಳಕೆದಾರರು ಪ್ರಸ್ತುತ ಈ ಸಾಧನಕ್ಕೆ ಸೈನ್ ಇನ್ ಮಾಡಿದ್ದಾರೆ ವೈರ್‌ಲೆಸ್ ಡೀಬಗ್ ಮಾಡುವುದನ್ನು ಆನ್ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ. ಈ ಫೀಚರ್ ಅನ್ನು ಬಳಸಲು, ನಿರ್ವಾಹಕ ಬಳಕೆದಾರರಿಗೆ ಬದಲಾಯಿಸಿ."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"USB ಪೋರ್ಟ್ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"ದ್ರವ ಅಥವಾ ಧೂಳಿನ ಕಣಗಳಿಂದ ನಿಮ್ಮ ಸಾಧನವನ್ನು ರಕ್ಷಿಸಲು, USB ಪೋರ್ಟ್ ಅನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ ಹಾಗಾಗಿ ಅದು ಯಾವುದೇ ಪರಿಕರಗಳನ್ನು ಪತ್ತೆ ಮಾಡುವುದಿಲ್ಲ. \n\n USB ಪೋರ್ಟ್ ಬಳಸಲು ಸುರಕ್ಷಿತವಾಗಿದ್ದಾಗ ಮತ್ತೆ ನಿಮಗೆ ಸೂಚಿಸಲಾಗುವುದು."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"ಚಾರ್ಜರ್‌ಗಳು ಮತ್ತು ಪರಿಕರಗಳನ್ನು ಪತ್ತೆಹಚ್ಚಲು USB ಪೋರ್ಟ್ ಅನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"ಧ್ವನಿ ಸಹಾಯಕ"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"ವಾಲೆಟ್"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"QR ಕೋಡ್ ಸ್ಕ್ಯಾನರ್"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"ಅನ್‌ಲಾಕ್"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"ಸಾಧನ ಲಾಕ್ ಆಗಿದೆ"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"ಮುಖವನ್ನು ಸ್ಕ್ಯಾನ್ ಮಾಡಲಾಗುತ್ತಿದೆ"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"ಕಳುಹಿಸಿ"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"ಮುಖ ಗುರುತಿಸಲಾಗುತ್ತಿಲ್ಲ"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"ಬದಲಿಗೆ ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಬಳಸಿ"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"ಬ್ಲೂಟೂತ್‌‌ ಸಂಪರ್ಕಗೊಂಡಿದೆ."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"ಬ್ಯಾಟರಿ ಶೇಕಡಾವಾರು ತಿಳಿದಿಲ್ಲ."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"ಏರೋಪ್ಲೇನ್‌ ಮೋಡ್‌"</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"ನಲ್ಲಿ VPN"</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"ಬ್ಯಾಟರಿ <xliff:g id="NUMBER">%d</xliff:g> ಪ್ರತಿಶತ."</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"ನಿಮ್ಮ ಬಳಕೆಯ ಆಧಾರದ ಮೇಲೆ ಬ್ಯಾಟರಿಯು ಪ್ರತಿಶತ <xliff:g id="PERCENTAGE">%1$s</xliff:g> ರಷ್ಟು ಮತ್ತು <xliff:g id="TIME">%2$s</xliff:g> ಸಮಯ ಬಾಕಿ ಉಳಿದಿದೆ"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"ನಿಮ್ಮ ಬಳಕೆಯ ಆಧಾರದ ಮೇಲೆ ಬ್ಯಾಟರಿಯು ಪ್ರತಿಶತ <xliff:g id="PERCENTAGE">%1$d</xliff:g> ರಷ್ಟು ಮತ್ತು <xliff:g id="TIME">%2$s</xliff:g> ಸಮಯ ಬಾಕಿ ಉಳಿದಿದೆ"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"ಬ್ಯಾಟರಿ <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> ಪ್ರತಿಶತ ಚಾರ್ಜ್ ಆಗುತ್ತಿದೆ."</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"ಎಲ್ಲಾ ಅಧಿಸೂಚನೆಗಳನ್ನು ನೋಡಿ"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"ಟೆಲಿಟೈಪ್‌ರೈಟರ್ ಸಕ್ರಿಯವಾಗಿದೆ."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"ರಿಂಗರ್ ವೈಬ್ರೇಟ್‌."</string>
@@ -386,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"ನೀವು ಆ್ಯಪ್ ಅನ್ನು ಹಂಚಿಕೊಳ್ಳುತ್ತಿರುವಾಗ, ರೆಕಾರ್ಡ್ ಮಾಡುತ್ತಿರುವಾಗ ಅಥವಾ ಬಿತ್ತರಿಸುತ್ತಿರುವಾಗ, ಆ ಆ್ಯಪ್‌ನಲ್ಲಿ ತೋರಿಸಲಾಗುವ ಅಥವಾ ಪ್ಲೇ ಆಗುವ ಯಾವುದೇ ವಿಷಯಕ್ಕೆ <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ಆ್ಯಕ್ಸೆಸ್ ಅನ್ನು ಹೊಂದಿರುತ್ತದೆ. ಹಾಗಾಗಿ, ಪಾಸ್‌ವರ್ಡ್‌ಗಳು, ಪಾವತಿ ವಿವರಗಳು, ಸಂದೇಶಗಳು ಅಥವಾ ಇತರ ಸೂಕ್ಷ್ಮ ಮಾಹಿತಿಯ ಕುರಿತು ಜಾಗರೂಕರಾಗಿರಿ."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"ಮುಂದುವರಿಸಿ"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"ಆ್ಯಪ್ ಅನ್ನು ಹಂಚಿಕೊಳ್ಳಿ ಅಥವಾ ರೆಕಾರ್ಡ್ ಮಾಡಿ"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"ಹಂಚಿಕೊಳ್ಳಲು ಅಥವಾ ರೆಕಾರ್ಡ್ ಮಾಡಲು ಈ ಆ್ಯಪ್‌ಗೆ ಅನುಮತಿಸುವುದೇ?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"ನೀವು ಹಂಚಿಕೊಳ್ಳುತ್ತಿರುವಾಗ, ರೆಕಾರ್ಡ್ ಮಾಡುತ್ತಿರುವಾಗ ಅಥವಾ ಬಿತ್ತರಿಸುತ್ತಿರುವಾಗ, ನಿಮ್ಮ ಸ್ಕ್ರೀನ್ ಮೇಲೆ ಕಾಣಿಸುವ ಅಥವಾ ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಪ್ಲೇ ಆಗುವ ಯಾವುದೇ ವಿಷಯಕ್ಕೆ ಈ ಆ್ಯಪ್ ಆ್ಯಕ್ಸೆಸ್ ಅನ್ನು ಹೊಂದಿರುತ್ತದೆ. ಹಾಗಾಗಿ, ಪಾಸ್‌ವರ್ಡ್‌ಗಳು, ಪಾವತಿ ವಿವರಗಳು, ಸಂದೇಶಗಳು ಅಥವಾ ಇತರ ಸೂಕ್ಷ್ಮ ಮಾಹಿತಿಯ ಕುರಿತು ಜಾಗರೂಕರಾಗಿರಿ."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"ನೀವು ಆ್ಯಪ್ ಒಂದನ್ನು ಹಂಚಿಕೊಳ್ಳುತ್ತಿರುವಾಗ, ರೆಕಾರ್ಡ್ ಮಾಡುತ್ತಿರುವಾಗ ಅಥವಾ ಬಿತ್ತರಿಸುತ್ತಿರುವಾಗ, ಆ ಆ್ಯಪ್‌ನಲ್ಲಿ ತೋರಿಸಲಾಗುವ ಅಥವಾ ಪ್ಲೇ ಆಗುವ ಯಾವುದೇ ವಿಷಯಕ್ಕೆ ಆ್ಯಕ್ಸೆಸ್ ಅನ್ನು ಈ ಆ್ಯಪ್ ಹೊಂದಿರುತ್ತದೆ. ಹಾಗಾಗಿ, ಪಾಸ್‌ವರ್ಡ್‌ಗಳು, ಪಾವತಿ ವಿವರಗಳು, ಸಂದೇಶಗಳು ಅಥವಾ ಇತರ ಸೂಕ್ಷ್ಮ ಮಾಹಿತಿಯ ಕುರಿತು ಜಾಗರೂಕರಾಗಿರಿ."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"ನಿಮ್ಮ IT ನಿರ್ವಾಹಕರು ನಿರ್ಬಂಧಿಸಿದ್ದಾರೆ"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"ಸಾಧನ ನೀತಿಯಿಂದ ಸ್ಕ್ರೀನ್ ಕ್ಯಾಪ್ಚರಿಂಗ್ ಅನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"ಎಲ್ಲವನ್ನೂ ತೆರವುಗೊಳಿಸಿ"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"ನಿರ್ವಹಿಸಿ"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"ಇತಿಹಾಸ"</string>
@@ -511,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"ಬಳಸಲು ಅನ್‌ಲಾಕ್ ಮಾಡಿ"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"ನಿಮ್ಮ ಕಾರ್ಡ್‌ಗಳನ್ನು ಪಡೆಯುವಾಗ ಸಮಸ್ಯೆ ಉಂಟಾಗಿದೆ, ನಂತರ ಪುನಃ ಪ್ರಯತ್ನಿಸಿ"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"ಲಾಕ್ ಸ್ಕ್ರ್ರೀನ್ ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"QR ಕೋಡ್ ಸ್ಕ್ಯಾನ್ ಮಾಡಿ"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"ಕೆಲಸದ ಪ್ರೊಫೈಲ್"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"ಏರ್‌ಪ್ಲೇನ್ ಮೋಡ್"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"ನಿಮ್ಮ ಮುಂದಿನ <xliff:g id="WHEN">%1$s</xliff:g> ಅಲಾರಮ್ ಅನ್ನು ನೀವು ಆಲಿಸುವುದಿಲ್ಲ"</string>
@@ -794,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"ಪೂರ್ಣ ಸ್ಕ್ರೀನ್‌ ಅನ್ನು ಹಿಗ್ಗಿಸಿ"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"ಸ್ಕ್ರೀನ್‌ನ ಅರ್ಧಭಾಗವನ್ನು ಝೂಮ್ ಮಾಡಿ"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"ಸ್ವಿಚ್"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"ಡಯಾಗನಲ್ ಸ್ಕ್ರೋಲಿಂಗ್ ಅನ್ನು ಅನುಮತಿಸಿ"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"ಮರುಗಾತ್ರಗೊಳಿಸಿ"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"ಹಿಗ್ಗಿಸುವಿಕೆಯ ಪ್ರಕಾರವನ್ನು ಬದಲಾಯಿಸಿ"</string>
@@ -1024,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"ಎಲ್ಲಾ ಸಾಧನದ ಲಾಗ್‌ಗಳನ್ನು ಆ್ಯಕ್ಸೆಸ್ ಮಾಡಲು <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> ಗೆ ಅನುಮತಿಸುವುದೇ?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"ಒಂದು ಬಾರಿಯ ಪ್ರವೇಶವನ್ನು ಅನುಮತಿಸಿ"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"ಅನುಮತಿಸಬೇಡಿ"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿನ ಕಾರ್ಯಾಚರಣೆಗಳನ್ನು ಸಾಧನದ ಲಾಗ್‌ಗಳು ರೆಕಾರ್ಡ್ ಮಾಡುತ್ತವೆ. ಸಮಸ್ಯೆಗಳನ್ನು ಪತ್ತೆಹಚ್ಚಲು ಮತ್ತು ಪರಿಹರಿಸಲು ಆ್ಯಪ್‌ಗಳು ಈ ಲಾಗ್ ಅನ್ನು ಬಳಸಬಹುದು.\n\nಕೆಲವು ಲಾಗ್‌ಗಳು ಸೂಕ್ಷ್ಮ ಮಾಹಿತಿಯನ್ನು ಒಳಗೊಂಡಿರಬಹುದು, ಆದ್ದರಿಂದ ನಿಮ್ಮ ವಿಶ್ವಾಸಾರ್ಹ ಆ್ಯಪ್‌ಗಳಿಗೆ ಮಾತ್ರ ಸಾಧನದ ಎಲ್ಲಾ ಲಾಗ್‌ಗಳಿಗೆ ಪ್ರವೇಶವನ್ನು ಅನುಮತಿಸಿ. \n\nಎಲ್ಲಾ ಸಾಧನ ಲಾಗ್‌ಗಳನ್ನು ಪ್ರವೇಶಿಸಲು ನೀವು ಈ ಆ್ಯಪ್‌ಗೆ ಅನುಮತಿಸದಿದ್ದರೆ, ಅದು ಆಗಲೂ ತನ್ನದೇ ಆದ ಲಾಗ್‌ಗಳನ್ನು ಪ್ರವೇಶಿಸಬಹುದು. ನಿಮ್ಮ ಸಾಧನ ತಯಾರಕರಿಗೆ ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿನ ಕೆಲವು ಲಾಗ್‌ಗಳು ಅಥವಾ ಮಾಹಿತಿಯನ್ನು ಪ್ರವೇಶಿಸಲು ಈಗಲೂ ಸಾಧ್ಯವಾಗುತ್ತದೆ."</string>
</resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index e5e46573a624..ded1cc23234c 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"이 컴퓨터에서 항상 허용"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"허용"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"USB 디버깅이 허용되지 않음"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"현재 이 기기에 로그인한 사용자는 USB 디버깅을 사용 설정할 수 없습니다. 이 기능을 사용하려면 기본 사용자로 전환하세요."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"현재 이 기기에 로그인한 사용자는 USB 디버깅을 사용 설정할 수 없습니다. 이 기능을 사용하려면 관리자로 전환하세요."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"시스템 언어를 <xliff:g id="LANGUAGE">%1$s</xliff:g>로 변경하시겠습니까?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"다른 기기에서 시스템 언어 변경을 요청함"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"언어 변경"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"이 네트워크에서 항상 허용"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"허용"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"무선 디버깅이 허용되지 않음"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"현재 이 기기에 로그인한 사용자는 무선 디버깅을 사용 설정할 수 없습니다. 이 기능을 사용하려면 기본 사용자로 전환하세요."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"현재 이 기기에 로그인한 사용자는 무선 디버깅을 사용 설정할 수 없습니다. 이 기능을 사용하려면 관리자로 전환하세요."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"USB 포트 비활성화됨"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"기기를 액체나 이물질로부터 보호하기 위해 USB 포트가 사용 중지되었으며 액세서리를 연결할 수 없습니다.\n\nUSB 포트를 다시 안전하게 사용할 수 있게 되면 알려 드리겠습니다."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"충전기와 액세서리를 감지할 수 있도록 USB 포트가 사용 설정됨"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"음성 지원"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"월렛"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"QR 코드 스캐너"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"잠금 해제"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"기기 잠김"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"얼굴 스캔 중"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"보내기"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"얼굴을 인식할 수 없습니다."</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"대신 지문을 사용하세요."</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"블루투스가 연결되었습니다."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"배터리 잔량을 알 수 없습니다."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"비행기 모드입니다."</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN 켜짐"</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"배터리 <xliff:g id="NUMBER">%d</xliff:g>퍼센트"</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"배터리 <xliff:g id="PERCENTAGE">%1$s</xliff:g>퍼센트, 평소 사용량 기준 약 <xliff:g id="TIME">%2$s</xliff:g> 남음"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"배터리 <xliff:g id="PERCENTAGE">%1$d</xliff:g>퍼센트, 평소 사용량 기준 약 <xliff:g id="TIME">%2$s</xliff:g> 남음"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"배터리 충전 중, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%입니다."</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"모든 알림 보기"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"전신 타자기(TTY)가 사용 설정되었습니다."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"벨소리가 진동입니다."</string>
@@ -386,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"앱을 공유하거나 녹화하거나 전송할 때는 <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>에서 해당 앱에 표시되거나 재생되는 모든 항목에 액세스할 수 있으므로 비밀번호, 결제 세부정보, 메시지 등 민감한 정보가 노출되지 않도록 주의하세요."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"계속"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"앱 공유 또는 녹화"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"앱에서 공유하거나 기록하도록 허용하시겠습니까?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"공유하거나 녹화하거나 전송할 때 이 앱에서 화면에 표시되거나 기기에서 재생되는 모든 항목에 액세스할 수 있습니다. 따라서 비밀번호, 결제 세부정보, 메시지 등 민감한 정보가 노출되지 않도록 주의하세요."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"앱을 공유하거나 녹화하거나 전송할 때는 이 앱에서 해당 앱에 표시되거나 재생되는 모든 항목에 액세스할 수 있으므로 비밀번호, 결제 세부정보, 메시지 등 민감한 정보가 노출되지 않도록 주의하세요."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"IT 관리자에 의해 차단됨"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"기기 정책에 의해 화면 캡처가 사용 중지되었습니다."</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"모두 지우기"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"관리"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"기록"</string>
@@ -511,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"잠금 해제하여 사용"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"카드를 가져오는 중에 문제가 발생했습니다. 나중에 다시 시도해 보세요."</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"잠금 화면 설정"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"QR 코드 스캔"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"직장 프로필"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"비행기 모드"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"<xliff:g id="WHEN">%1$s</xliff:g>에 다음 알람을 들을 수 없습니다."</string>
@@ -794,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"전체 화면 확대"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"화면 일부 확대"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"전환"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"대각선 스크롤 허용"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"크기 조절"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"확대 유형 변경"</string>
@@ -1024,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"MMM d일 EEE"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g>에서 모든 기기 로그에 액세스하도록 허용하시겠습니까?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"일회성 액세스 허용"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"허용 안함"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"기기 로그에 기기에서 발생한 상황이 기록됩니다. 앱은 문제를 찾고 해결하는 데 이 로그를 사용할 수 있습니다.\n\n일부 로그는 민감한 정보를 포함할 수 있으므로 신뢰할 수 있는 앱만 모든 기기 로그에 액세스하도록 허용하세요. \n\n앱에 전체 기기 로그에 대한 액세스 권한을 부여하지 않아도 앱이 자체 로그에는 액세스할 수 있습니다. 기기 제조업체에서 일부 로그 또는 기기 내 정보에 액세스할 수도 있습니다."</string>
</resources>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index bef48dce1fcd..a49a1d5cfa75 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"Бул компүтерден дайыма уруксат берилсин"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"Ооба"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"USB мүчүлүштүктөрүн оңдоого уруксат жок"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"Учурда бул аккаунтта USB аркылуу мүчүлүштүктөрдү аныктоо функциясын иштетүүгө болбойт. Негизги колдонуучунун аккаунтуна кириңиз."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"Учурда ушул түзмөккө кирип турган колдонуучу USB аркылуу мүчүлүштүктөрдү оңдоо функциясын күйгүзө албайт. Бул функцияны пайдалануу үчүн админге которулуңуз."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Тутум тилин <xliff:g id="LANGUAGE">%1$s</xliff:g> тилине өзгөртөсүзбү?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Тутум тилин өзгөртүү сурамы башка түзмөктөн жөнөтүлдү"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Тилди өзгөртүү"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"Бул тармакта ар дайым уруксат берилсин"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"Ооба"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Мүчүлүштүктөрдү Wi-Fi аркылуу оңдоого уруксат берилген жок"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"Учурда бул түзмөккө кирген колдонуучу мүчүлүштүктөрдү Wi-Fi аркылуу оңдоо функциясын күйгүзө албайт. Бул функцияны колдонуу үчүн негизги колдонуучунун аккаунтуна которулуңуз."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"Учурда бул түзмөккө кирип турган колдонуучу мүчүлүштүктөрдү Wi-Fi аркылуу оңдоо функциясын күйгүзө албайт. Бул функцияны колдонуу үчүн админге которулуңуз."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"USB порту өчүрүлдү"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"Түзмөгүңүздүн ичине суюктук же булганч нерселер кирип кетпеши үчүн USB порту өчүрүлдү. Азырынча ал аркылуу башка түзмөктөргө туташууга болбойт.\n\nUSB портун кайра колдонуу мүмкүн болгондо, билдирме аласыз."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"Кубаттагычтарды жана аксессуарларды аныктоо үчүн USB оюкчасы иштетилди"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Үн жардамчысы"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Капчык"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"QR коддорунун сканери"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"Кулпусун ачуу"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"Түзмөк кулпуланды"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Жүз скандалууда"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Жөнөтүү"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"Жүз таанылбай жатат"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Манжа изин колдонуңуз"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth байланышта"</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"Батарея кубатынын деңгээли белгисиз."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"Учак тартиби."</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN күйүк."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"Батарея <xliff:g id="NUMBER">%d</xliff:g> пайыз."</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Батареянын деңгээли <xliff:g id="PERCENTAGE">%1$s</xliff:g> пайыз, колдонгонуңузга караганда болжол менен <xliff:g id="TIME">%2$s</xliff:g> калды"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Батареянын деңгээли <xliff:g id="PERCENTAGE">%1$d</xliff:g> пайыз, колдонгонуңузга караганда болжол менен <xliff:g id="TIME">%2$s</xliff:g> калды"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Батарея кубатталууда, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"Бардык билдирмелерди көрүү"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"ТелеТайп терүүсү жандырылган."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Шыңгыраганда титирөө."</string>
@@ -386,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Бөлүшүп, жаздырып же тышкы экранда бөлүшкөндө <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ал колдонмодо көрүнүп жана ойнотулуп жаткан нерселерге мүмкүнчүлүк алат. Андыктан сырсөздөрдү, төлөм маалыматын, билдирүүлөрдү жана башка купуя маалыматты көрсөтүп албаңыз."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Улантуу"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Колдонмону бөлүшүү же жаздыруу"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Бул колдонмого бөлүшүп же жаздырууга уруксат бересизби?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Бөлүшүп, жаздырып же тышкы экранга чыгарганда бул колдонмо экраныңызда көрүнүп жана түзмөктө ойнотулуп жаткан нерселерге мүмкүнчүлүк алат. Андыктан сырсөздөрдү, төлөмдүн чоо-жайын, билдирүүлөрдү жана башка купуя маалыматты көрсөтүп албаңыз."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Бөлүшүп, жаздырып же тышкы экранга чыгарганда бул колдонмо ал колдонмодо көрсөтүлүп жана ойнотулуп жаткан нерселерге мүмкүнчүлүк алат. Андыктан сырсөздөрдү, төлөмдүн чоо-жайын, билдирүүлөрдү жана башка купуя маалыматты көрсөтүп албаңыз."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"IT администраторуңуз бөгөттөп койгон"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"Түзмөк саясаты экрандагыны тартып алууну өчүрүп койгон"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Баарын тазалап салуу"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Башкаруу"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Таржымал"</string>
@@ -511,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Колдонуу үчүн кулпусун ачыңыз"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Кыйытмаларды алууда ката кетти. Бир аздан кийин кайталап көрүңүз."</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Экранды кулпулоо параметрлери"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"QR кодун скандоо"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Жумуш профили"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Учак режими"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"<xliff:g id="WHEN">%1$s</xliff:g> боло турган кийинки эскертмени укпайсыз"</string>
@@ -794,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Толук экранда ачуу"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Экрандын бир бөлүгүн чоңойтуу"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Которулуу"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Диагональ боюнча сыдырууга уруксат берүү"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Өлчөмүн өзгөртүү"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"Чоңойтуу түрүн өзгөртүү"</string>
@@ -1024,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> колдонмосуна түзмөктөгү бардык таржымалдарды жеткиликтүү кыласызбы?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"Бир жолу жеткиликтүү кылуу"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Тыюу салуу"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"Түзмөктө аткарылган бардык аракеттер түзмөктүн таржымалдарында сакталып калат. Колдонмолор бул таржымалдарды колдонуп, маселелерди оңдошот.\n\nАйрым таржымалдарда купуя маалымат болушу мүмкүн, андыктан ишенимдүү колдонмолорго гана түзмөктөгү бардык таржымалдарды пайдаланууга уруксат бериңиз. \n\nЭгер бул колдонмого түзмөктөгү бардык таржымалдарга кирүүгө тыюу салсаңыз, ал өзүнүн таржымалдарын пайдалана берет. Түзмөктү өндүрүүчү түзмөгүңүздөгү айрым таржымалдарды же маалыматты көрө берет."</string>
</resources>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index 0d0d9dec7258..b61a34789959 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"ອະນຸຍາດຈາກຄອມພິວເຕີນີ້ຕະຫຼອດ"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"ອະນຸຍາດ"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"ບໍ່​ອະ​ນຸ​ຍາດ​ໃຫ້​ມີ​ການ​ແກ້​ໄຂ​ບັນ​ຫາ USB"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"ຜູ້ໃຊ້ທີ່ກຳລັງເຂົ້າສູ່ລະບົບອຸປະກອນຢູ່ໃນຕອນນີ້ບໍ່ສາມາດເປີດໃຊ້ການດີບັກ USB ໄດ້. ເພື່ອໃຊ້ຄຸນສົມບັດນີ້, ໃຫ້ສະຫຼັບໄປໃຊ້ຜູ້ໃຊ້ຫຼັກ."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"ຜູ້ໃຊ້ທີ່ເຂົ້າສູ່ລະບົບອຸປະກອນຢູ່ໃນຕອນນີ້ບໍ່ສາມາດເປີດໃຊ້ການດີບັກ USB ໄດ້. ເພື່ອໃຊ້ຄຸນສົມບັດນີ້, ໃຫ້ປ່ຽນໄປເປັນຜູ້ໃຊ້ທີ່ເບິ່ງແຍງລະບົບ."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"ທ່ານຕ້ອງການປ່ຽນພາສາລະບົບເປັນ <xliff:g id="LANGUAGE">%1$s</xliff:g> ບໍ່?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"ມີການຮ້ອງຂໍໃຫ້ປ່ຽນພາສາລະບົບໂດຍອຸປະກອນອື່ນ"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"ປ່ຽນພາສາ"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"ອະນຸຍາດຕະຫຼອດຢູ່ເຄືອຂ່າຍນີ້"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"ອະນຸຍາດ"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"ບໍ່ອະນຸຍາດໃຫ້ໃຊ້ການດີບັກໄຮ້ສາຍ"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"ຜູ້ໃຊ້ທີ່ກຳລັງເຂົ້າສູ່ລະບົບອຸປະກອນຢູ່ໃນຕອນນີ້ບໍ່ສາມາດເປີດໃຊ້ການດີບັກໄຮ້ສາຍໄດ້. ເພື່ອໃຊ້ຄຸນສົມບັດນີ້, ໃຫ້ສະຫຼັບໄປໃຊ້ຜູ້ໃຊ້ຫຼັກ."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"ຜູ້ໃຊ້ທີ່ເຂົ້າສູ່ລະບົບອຸປະກອນຢູ່ໃນຕອນນີ້ບໍ່ສາມາດເປີດໃຊ້ການດີບັກໄຮ້ສາຍໄດ້. ເພື່ອໃຊ້ຄຸນສົມບັດນີ້, ໃຫ້ປ່ຽນໄປເປັນຜູ້ໃຊ້ທີ່ເບິ່ງແຍງລະບົບ."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"ປິດການນຳໃຊ້ຜອດ USB ແລ້ວ"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"ເພື່ອປົກປ້ອງອຸປະກອນຂອງທ່ານຈາກຂອງແຫລວ ຫຼື ເສດດິນຕ່າງໆ, ຜອດ USB ຈຶ່ງຖືກປິດການນຳໃຊ້ ແລະ ຈະບໍ່ກວດຫາອຸປະກອນເສີມໃດໆ.\n\nທ່ານຈະໄດ້ຮັບການແຈ້ງເຕືອນເມື່ອສາມາດໃຊ້ຜອດ USB ໄດ້ອີກເທື່ອໜຶ່ງ."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"ເປີດນຳໃຊ້ USB ແລ້ວເພື່ອກວດຫາສາຍສາກ ແລະ ອຸປະກອນເສີມ"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"ຊ່ວຍ​ເຫຼືອ​ທາງ​ສຽງ"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"ຕົວສະແກນລະຫັດ QR"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"ປົດລັອກ"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"ອຸປະກອນຖືກລັອກໄວ້"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"ການສະແກນໜ້າ"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"ສົ່ງ"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"ບໍ່ສາມາດຈຳແນກໃບໜ້າໄດ້"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"ກະລຸນາໃຊ້ລາຍນິ້ວມືແທນ"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"ເຊື່ອມຕໍ່ Bluetooth ແລ້ວ."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"ບໍ່ຮູ້ເປີເຊັນແບັດເຕີຣີ."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"ໂໝດໃນຍົນ."</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN ເປີດ."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"ແບັດເຕີຣີ <xliff:g id="NUMBER">%d</xliff:g> ເປີເຊັນ."</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"ແບັດເຕີຣີ <xliff:g id="PERCENTAGE">%1$s</xliff:g> ເປີເຊັນ, ເຫຼືອປະມານ <xliff:g id="TIME">%2$s</xliff:g> ອ້າງອີງຈາກການນຳໃຊ້ຂອງທ່ານ"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"ແບັດເຕີຣີ <xliff:g id="PERCENTAGE">%1$d</xliff:g> ເປີເຊັນ, ເຫຼືອປະມານ <xliff:g id="TIME">%2$s</xliff:g> ອ້າງອີງຈາກການນຳໃຊ້ຂອງທ່ານ"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"ກຳລັງສາກແບັດເຕີຣີ, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> ເປີເຊັນ."</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"ເບິ່ງການແຈ້ງເຕືອນທັງໝົດ"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"TeleTypewriter ຖືກເປີດຢູ່."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"ສັ່ນເຕືອນພ້ອມສຽງເອີ້ນເຂົ້າ."</string>
@@ -386,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"ໃນຕອນທີ່ທ່ານກຳລັງແບ່ງປັນ, ບັນທຶກ ຫຼື ສົ່ງສັນຍານແອັບ, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ມີສິດເຂົ້າເຖິງສິ່ງທີ່ສະແດງ ຫຼື ຫຼິ້ນຢູ່ໃນແອັບນັ້ນ. ດັ່ງນັ້ນໃຫ້ລະມັດລະວັງກ່ຽວກັບລະຫັດຜ່ານ, ລາຍລະອຽດການຈ່າຍເງິນ, ຂໍ້ຄວາມ ຫຼື ຂໍ້ມູນທີ່ລະອຽດອ່ອນອື່ນໆ."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"ສືບຕໍ່"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"ແບ່ງປັນ ຫຼື ບັນທຶກແອັບ"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"ອະນຸຍາດໃຫ້ແອັບນີ້ແບ່ງປັນ ຫຼື ບັນທຶກບໍ?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"ເມື່ອທ່ານກຳລັງແບ່ງປັນ, ບັນທຶກ ຫຼື ສົ່ງສັນຍານ, ແອັບນີ້ຈະມີສິດເຂົ້າເຖິງສິ່ງທີ່ເຫັນໄດ້ໃນໜ້າຈໍຂອງທ່ານ ຫຼື ຫຼິ້ນຢູ່ອຸປະກອນຂອງທ່ານ. ດັ່ງນັ້ນໃຫ້ລະມັດລະວັງເລື່ອງລະຫັດຜ່ານ, ລາຍລະອຽດການຈ່າຍເງິນ, ຂໍ້ຄວາມ ຫຼື ຂໍ້ມູນທີ່ລະອຽດອ່ອນອື່ນໆ."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"ໃນຕອນທີ່ທ່ານກຳລັງແບ່ງປັນ, ບັນທຶກ ຫຼື ສົ່ງສັນຍານແອັບ, ແອັບນີ້ຈະມີສິດເຂົ້າເຖິງສິ່ງທີ່ສະແດງ ຫຼື ຫຼິ້ນຢູ່ໃນແອັບນັ້ນ. ດັ່ງນັ້ນໃຫ້ລະມັດລະວັງກ່ຽວກັບລະຫັດຜ່ານ, ລາຍລະອຽດການຈ່າຍເງິນ, ຂໍ້ຄວາມ ຫຼື ຂໍ້ມູນທີ່ລະອຽດອ່ອນອື່ນໆ."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"ຖືກບລັອກໄວ້ໂດຍຜູ້ເບິ່ງແຍງລະບົບໄອທີຂອງທ່ານ"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"ການຖ່າຍຮູບໜ້າຈໍຖືກປິດການນຳໃຊ້ໄວ້ໂດຍນະໂຍບາຍອຸປະກອນ"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"ລຶບລ້າງທັງໝົດ"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"ຈັດການ"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"ປະຫວັດ"</string>
@@ -511,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"ປົດລັອກເພື່ອໃຊ້"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"ເກີດບັນຫາໃນການໂຫຼດບັດຂອງທ່ານ, ກະລຸນາລອງໃໝ່ໃນພາຍຫຼັງ"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"ການຕັ້ງຄ່າໜ້າຈໍລັອກ"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"ສະແກນລະຫັດ QR"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"​ໂປຣ​ໄຟລ໌​ບ່ອນ​ເຮັດ​ວຽກ"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"ໂໝດເຮືອ​ບິນ"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"ທ່ານ​ຈະ​ບໍ່​ໄດ້​ຍິນ​ສຽງ​ໂມງ​ປ <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -794,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"ຂະຫຍາຍເຕັມຈໍ"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"ຂະຫຍາຍບາງສ່ວນຂອງໜ້າຈໍ"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"ສະຫຼັບ"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"ອະນຸຍາດໃຫ້ເລື່ອນທາງຂວາງ"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"ປ່ຽນຂະໜາດ"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"ປ່ຽນຮູບແບບການຂະຫຍາຍ"</string>
@@ -1024,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"ຊມ:ນທ"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"ຊມ:ນທ"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"ອະນຸຍາດໃຫ້ <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> ເຂົ້າເຖິງບັນທຶກທັງໝົດຂອງອຸປະກອນບໍ?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"ອະນຸຍາດສິດເຂົ້າເຖິງແບບເທື່ອດຽວ"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"ບໍ່ອະນຸຍາດ"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"ບັນທຶກຂອງອຸປະກອນຈະບັນທຶກສິ່ງທີ່ເກີດຂຶ້ນຢູ່ອຸປະກອນຂອງທ່ານ. ແອັບສາມາດໃຊ້ບັນທຶກເຫຼົ່ານີ້ເພື່ອຊອກຫາ ແລະ ແກ້ໄຂບັນຫາໄດ້.\n\nບັນທຶກບາງຢ່າງອາດມີຂໍ້ມູນທີ່ລະອຽດອ່ອນ, ດັ່ງນັ້ນໃຫ້ອະນຸຍາດສະເພາະແອັບທີ່ທ່ານເຊື່ອຖືໄດ້ໃຫ້ເຂົ້າເຖິງບັນທຶກທັງໝົດຂອງອຸປະກອນເທົ່ານັ້ນ. \n\nຫາກທ່ານບໍ່ອະນຸຍາດໃຫ້ແອັບນີ້ເຂົ້າເຖິງບັນທຶກທັງໝົດຂອງອຸປະກອນ, ມັນຈະຍັງຄົງສາມາດເຂົ້າເຖິງບັນທຶກຂອງຕົວມັນເອງໄດ້ຢູ່. ຜູ້ຜະລິດອຸປະກອນຂອງທ່ານອາດຍັງຄົງສາມາດເຂົ້າເຖິງບັນທຶກ ຫຼື ຂໍ້ມູນບາງຢ່າງຢູ່ອຸປະກອນຂອງທ່ານໄດ້."</string>
</resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 5c9969f677b1..b3c234ee5d71 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"Visada leisti iš šio kompiuterio"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"Leisti"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"USB derinimas neleidžiamas"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"Šiuo metu prie įrenginio prisijungęs naudotojas negali įjungti USB derinimo. Kad galėtumėte naudoti šią funkciją, perjunkite į pagrindinį naudotoją."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"Šiuo metu prie įrenginio prisijungęs naudotojas negali įjungti USB derinimo. Kad galėtumėte naudoti šią funkciją, perjunkite į naudotoją administratorių."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Ar norite pakeisti sistemos kalbą į <xliff:g id="LANGUAGE">%1$s</xliff:g> k.?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Užklausą dėl sistemos kalbos pakeitimo pateikė kitas įrenginys"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Keisti kalbą"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"Visada leisti naudojant šį tinklą"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"Leisti"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Belaidžio ryšio derinimas neleidžiamas"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"Šiuo metu prie įrenginio prisijungęs naudotojas negali įjungti belaidžio ryšio derinimo. Kad galėtumėte naudoti šią funkciją, perjunkite į pagrindinį naudotoją."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"Šiuo metu prie įrenginio prisijungęs naudotojas negali įjungti belaidžio ryšio derinimo. Kad galėtumėte naudoti šią funkciją, perjunkite į naudotoją administratorių."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"USB prievadas išjungtas"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"Siekiant apsaugoti įrenginį nuo skysčių ar smulkių dalelių, USB prievadas buvo išjungtas ir neaptiks jokių priedų.\n\nJums bus pranešta, kai galėsite vėl saugiai naudoti USB prievadą."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"USB prievadas įgalintas aptikti kroviklius ir priedus"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Voice Assist"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"QR kodų skaitytuvas"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"Atrakinti"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"Įrenginys užrakintas"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Nuskaitomas veidas"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Siųsti"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"Veidas neatpažintas"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Naudoti piršto antspaudą"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"„Bluetooth“ prijungtas."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"Akumuliatoriaus energija procentais nežinoma."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"Lėktuvo režimas."</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN įjungtas."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"Akumuliatorius: <xliff:g id="NUMBER">%d</xliff:g> proc."</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> proc. akumuliatoriaus energijos – liko maždaug <xliff:g id="TIME">%2$s</xliff:g>, atsižvelgiant į naudojimą"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> proc. akumuliatoriaus energijos – liko maždaug <xliff:g id="TIME">%2$s</xliff:g>, atsižvelgiant į naudojimą"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Įkraunamas akumuliatorius, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"Žr. visus pranešimus"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"„TeleTypewriter“ įgalinta."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Vibracija skambinant."</string>
@@ -386,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Kai bendrinate, įrašote ar perduodate turinį, „<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>“ gali pasiekti viską, kas rodoma ar leidžiama programoje. Todėl būkite atsargūs su slaptažodžiais, išsamia mokėjimo metodo informacija, pranešimais ar kita neskelbtina informacija."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Tęsti"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Programos bendrinimas ar įrašymas"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Leisti šiai programai bendrinti arba įrašyti?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Kai bendrinate, įrašote ar perduodate turinį, ši programa gali pasiekti viską, kas rodoma ekrane ar leidžiama įrenginyje. Todėl būkite atsargūs su slaptažodžiais, išsamia mokėjimo metodo informacija, pranešimais ar kita neskelbtina informacija."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Kai bendrinate, įrašote ar perduodate turinį, ši programa gali pasiekti viską, kas rodoma ar leidžiama programoje. Todėl būkite atsargūs su slaptažodžiais, išsamia mokėjimo metodo informacija, pranešimais ar kita neskelbtina informacija."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Užblokavo jūsų IT administratorius"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"Ekrano fiksavimo funkcija išjungta vadovaujantis įrenginio politika"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Viską išvalyti"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Tvarkyti"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Istorija"</string>
@@ -511,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Atrakinti, kad būtų galima naudoti"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Gaunant korteles kilo problema, bandykite dar kartą vėliau"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Užrakinimo ekrano nustatymai"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"QR kodo nuskaitymas"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Darbo profilis"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Lėktuvo režimas"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Negirdėsite kito signalo <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -794,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Viso ekrano didinimas"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Didinti ekrano dalį"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Perjungti"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Slinkimo įstrižai leidimas"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Pakeisti dydį"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"Didinimo tipo keitimas"</string>
@@ -1024,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"Leisti „<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g>“ pasiekti visus įrenginio žurnalus?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"Leisti vienkartinę prieigą"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Neleisti"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"Įrenginio žurnaluose įrašoma, kas įvyksta įrenginyje. Programos gali naudoti šiuos žurnalus, kai reikia surasti ir išspręsti problemas.\n\nKai kuriuose žurnaluose gali būti neskelbtinos informacijos, todėl visus įrenginio žurnalus leiskite pasiekti tik programoms, kuriomis pasitikite. \n\nJei neleisite šiai programai pasiekti visų įrenginio žurnalų, ji vis tiek galės pasiekti savo žurnalus. Įrenginio gamintojui vis tiek gali būti leidžiama pasiekti tam tikrus žurnalus ar informaciją jūsų įrenginyje."</string>
</resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 415ba8f9813f..7dff7c12828a 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -52,7 +52,8 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"Vienmēr atļaut no šī datora"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"Atļaut"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"USB atkļūdošana nav atļauta"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"Lietotājs, kurš pašlaik ir pierakstījies šajā ierīcē, nevar iespējot USB atkļūdošanu. Lai izmantotu šo funkciju, pārslēdzieties uz galveno lietotāju."</string>
+ <!-- no translation found for usb_debugging_secondary_user_message (1888835696965417845) -->
+ <skip />
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Vai vēlaties mainīt sistēmas valodu uz šādu: <xliff:g id="LANGUAGE">%1$s</xliff:g>?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Sistēmas valodas maiņu pieprasīja cita ierīce."</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Mainīt valodu"</string>
@@ -62,7 +63,8 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"Vienmēr atļaut šajā tīklā"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"Atļaut"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Bezvadu atkļūdošana nav atļauta"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"Lietotājs, kurš pašlaik ir pierakstījies šajā ierīcē, nevar iespējot bezvadu atkļūdošanu. Lai izmantotu šo funkciju, pārslēdzieties uz galveno lietotāju."</string>
+ <!-- no translation found for wifi_debugging_secondary_user_message (9085779370142222881) -->
+ <skip />
<string name="usb_contaminant_title" msgid="894052515034594113">"USB pieslēgvieta atspējota"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"Lai aizsargātu ierīci no šķidruma un gružiem, USB pieslēgvieta ir atspējota un tajā nevarēs noteikt pieslēgtus piederumus.\n\nKad USB pieslēgvietu atkal drīkstēs izmantot, saņemsiet paziņojumu."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"USB portam ir iespējota uzlādes ierīču un piederumu noteikšana"</string>
@@ -125,7 +127,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Balss palīgs"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Maks"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"Kvadrātkoda skeneris"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"Atbloķēt"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"Ierīce ir bloķēta"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Sejas skenēšana"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Sūtīt"</string>
@@ -168,7 +171,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"Nevar atpazīt seju"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Lietot pirksta nospiedumu"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth savienojums ir izveidots."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"Akumulatora uzlādes līmenis procentos nav zināms."</string>
@@ -180,8 +183,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"Lidmašīnas režīms."</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN ieslēgts"</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"Akumulators: <xliff:g id="NUMBER">%d</xliff:g> procenti"</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Akumulatora uzlādes līmenis: <xliff:g id="PERCENTAGE">%1$s</xliff:g> procenti. Ņemot vērā lietojumu, atlikušais laiks ir apmēram <xliff:g id="TIME">%2$s</xliff:g>"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Akumulatora uzlādes līmenis: <xliff:g id="PERCENTAGE">%1$d</xliff:g> procenti. Ņemot vērā lietojumu, atlikušais laiks ir apmēram <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Notiek akumulatora uzlāde, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"Skatīt visus paziņojumus"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"Teletaips ir iespējots."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Zvana signāls — vibrācija."</string>
@@ -386,16 +393,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Lietotnes kopīgošanas, ierakstīšanas vai apraides laikā <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> var piekļūt visam, kas tiek rādīts vai atskaņots attiecīgajā lietotnē. Tāpēc piesardzīgi apejieties ar parolēm, maksājumu informāciju, ziņojumiem un citu sensitīvu informāciju."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Turpināt"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Lietotnes kopīgošana vai ierakstīšana"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Vai atļaut šai lietotnei kopīgot vai ierakstīt?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Kopīgošanas, ierakstīšanas vai apraides laikā šī lietotne var piekļūt visam, kas tiek rādīts jūsu ekrānā vai atskaņots jūsu ierīcē. Tāpēc piesardzīgi apejieties ar parolēm, maksājumu informāciju, ziņojumiem un citu sensitīvu informāciju."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Kopīgošanas, ierakstīšanas vai apraides laikā lietotne var piekļūt visam, kas tiek rādīts vai atskaņots attiecīgajā lietotnē. Tāpēc piesardzīgi apejieties ar parolēm, maksājumu informāciju, ziņojumiem un citu sensitīvu informāciju."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Bloķējis jūsu IT administrators"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"Ierīces politika ir atspējojusi ekrānuzņēmumu izveidi"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Dzēst visu"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Pārvaldīt"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Vēsture"</string>
@@ -511,7 +513,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Lai izmantotu, atbloķējiet ekrānu"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Ienesot jūsu kartes, radās problēma. Lūdzu, vēlāk mēģiniet vēlreiz."</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Bloķēšanas ekrāna iestatījumi"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"Kvadrātkoda skenēšana"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Darba profils"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Lidojuma režīms"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Nākamais signāls (<xliff:g id="WHEN">%1$s</xliff:g>) netiks atskaņots."</string>
@@ -794,6 +797,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Palielināt visu ekrānu"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Palielināt ekrāna daļu"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Pārslēgt"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Atļaut ritināšanu pa diagonāli"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Mainīt lielumu"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"Mainīt palielinājuma veidu"</string>
@@ -1024,4 +1029,12 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d. MMM"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"hh:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <!-- no translation found for log_access_confirmation_title (4843557604739943395) -->
+ <skip />
+ <!-- no translation found for log_access_confirmation_allow (752147861593202968) -->
+ <skip />
+ <!-- no translation found for log_access_confirmation_deny (2389461495803585795) -->
+ <skip />
+ <!-- no translation found for log_access_confirmation_body (6883031912003112634) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 0ff554596c46..cf97701b51c2 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"Секогаш дозволувај од овој компјутер"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"Дозволи"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"Отстранувањето грешки на USB не е дозволено"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"Корисникот што моментално е најавен на уредов не може да вклучи отстранување грешки на USB. За да ја користите функцијава, префрлете се на примарниот корисник."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"Корисникот што моментално е најавен на уредов не може да вклучи отстранување грешки преку USB. За да ја користите функцијава, најавете се како администраторски корисник."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Дали сакате да го промените системскиот јазик на <xliff:g id="LANGUAGE">%1$s</xliff:g>?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Побарана е промена на системскиот јазик од друг уред"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Промени го јазикот"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"Секогаш дозволувај на оваа мрежа"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"Дозволи"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Безжичното отстранување грешки не е дозволено"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"Корисникот што моментално е најавен на уредов не може да вклучи безжично отстранување грешки. За да ја користите функцијава, префрлете се на примарниот корисник."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"Корисникот што моментално е најавен на уредов не може да вклучи безжично отстранување грешки. За да ја користите функцијава, најавете се како администраторски корисник."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"USB-портата е оневозможена"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"За да го заштитиме уредот од течност или нечистотија, USB-портата е оневозможена и нема да ги открива додатоците.\n\nЌе ве известиме кога ќе биде во ред да ја користите USB-портата повторно."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"USB-портата е овозможена за откривање полначи и додатоци"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Гласовна помош"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"Скенер на QR-кодови"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"Отклучување"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"Уредот е заклучен"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Скенирање лице"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Испрати"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"Не се препознава ликот"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Користи отпечаток"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth е поврзан."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"Процентот на батеријата е непознат."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"Авионски режим."</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN е вклучена."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"Батерија <xliff:g id="NUMBER">%d</xliff:g> проценти."</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Батерија <xliff:g id="PERCENTAGE">%1$s</xliff:g> отсто, уште околу <xliff:g id="TIME">%2$s</xliff:g> според вашето користење"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Батерија <xliff:g id="PERCENTAGE">%1$d</xliff:g> отсто, уште околу <xliff:g id="TIME">%2$s</xliff:g> според вашето користење"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Полнење на батеријата, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> отсто."</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"Видете ги сите известувања"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"Овозможен е телепринтер."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Ѕвонче на вибрации."</string>
@@ -386,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Кога споделувате, снимате или емитувате апликација, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> има пристап до сѐ што се прикажува или пушта на таа апликација. Затоа, бидете внимателни со лозинки, детали за плаќање, пораки или други чувствителни податоци."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Продолжи"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Споделете или снимете апликација"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Да се дозволи апликацијава да споделува или снима?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Кога споделувате, снимате или емитувате, апликацијава има пристап до сѐ што е видливо на вашиот екран или пуштено на вашиот уред. Затоа, бидете внимателни со лозинки, детали за плаќање, пораки или други чувствителни податоци."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Кога споделувате, снимате или емитувате апликација, апликацијава има пристап до сѐ што се прикажува или пушта на таа апликација. Затоа, бидете внимателни со лозинки, детали за плаќање, пораки или други чувствителни податоци."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Блокирано од IT-администраторот"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"Снимањето на екранот е оневозможено со правила на уредот"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Избриши сѐ"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Управувајте"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Историја"</string>
@@ -511,7 +511,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Отклучете за да користите"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Имаше проблем при преземањето на картичките. Обидете се повторно подоцна"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Поставки за заклучен екран"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"Скенирајте QR-код"</string>
+ <string name="qr_code_scanner_title" msgid="1938155688725760702">"Скенер на QR-кодови"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Работен профил"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Авионски режим"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Нема да го слушнете следниот аларм <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -794,6 +794,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Зголемете го целиот екран"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Зголемувајте дел од екранот"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Префрли"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Дозволете дијагонално лизгање"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Промени големина"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"Променете го типот на зголемување"</string>
@@ -1024,4 +1026,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"Да се дозволи <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> да пристапува до сите дневници за евиденција на уредот?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"Дозволи еднократен пристап"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Не дозволувај"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"Дневниците за евиденција на уредот снимаат што се случува на вашиот уред. Апликациите може да ги користат овие дневници за евиденција за да наоѓаат и поправаат проблеми.\n\nНекои дневници за евиденција може да содржат чувствителни податоци, па затоа дозволете им пристап до сите дневници за евиденција на уредот само на апликациите во кои имате доверба. \n\nАко не ѝ дозволите на апликацијава да пристапува до сите дневници за евиденција на уредот, таа сепак ќе може да пристапува до сопствените дневници за евиденција. Производителот на вашиот уред можеби сепак ќе може да пристапува до некои дневници за евиденција или податоци на уредот."</string>
</resources>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index e8fdef357d6f..0c72b9acf903 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"ഈ കമ്പ്യൂട്ടറിൽ നിന്ന് എല്ലായ്പ്പോഴും അനുവദിക്കുക"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"അനുവദിക്കുക"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"USB ഡീബഗ്ഗിംഗ് അനുവദനീയമല്ല"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"ഉപകരണത്തിൽ ഇപ്പോൾ സൈൻ ഇൻ ചെയ്‌തിരിക്കുന്ന ഉപയോക്താവിന് USB ഡീബഗ്ഗിംഗ് ഓണാക്കാനാകില്ല. ഈ ഫീച്ചർ ഉപയോഗിക്കാൻ പ്രാഥമിക ഉപയോക്താവിലേക്ക് മാറുക."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"ഈ ഉപകരണത്തിൽ ഇപ്പോൾ സൈൻ ഇൻ ചെയ്‌തിരിക്കുന്ന ഉപയോക്താവിന് USB ഡീബഗ് ചെയ്യൽ ഓണാക്കാനാകില്ല. ഈ ഫീച്ചർ ഉപയോഗിക്കാൻ അഡ്‌മിൻ ഉപയോക്താവിലേക്ക് മാറുക."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"സിസ്റ്റത്തിന്റെ ഭാഷ <xliff:g id="LANGUAGE">%1$s</xliff:g> ആക്കണോ?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"സിസ്റ്റത്തിന്റെ ഭാഷ മാറ്റാൻ മറ്റൊരു ഉപകരണം അഭ്യർത്ഥിച്ചു"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"ഭാഷ മാറ്റുക"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"ഈ നെറ്റ്‌വർക്കിൽ എപ്പോഴും അനുവദിക്കുക"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"അനുവദിക്കൂ"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"വയർലെസ് ഡീബഗ്ഗിംഗ് അനുവദനീയമല്ല"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"ഉപകരണത്തിൽ ഇപ്പോൾ സൈൻ ഇൻ ചെയ്‌തിരിക്കുന്ന ഉപയോക്താവിന് വയർലെസ് ഡീബഗ്ഗിംഗ് ഓണാക്കാനാകില്ല. ഈ ഫീച്ചർ ഉപയോഗിക്കാൻ പ്രാഥമിക ഉപയോക്താവിലേക്ക് മാറുക."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"ഈ ഉപകരണത്തിൽ ഇപ്പോൾ സൈൻ ഇൻ ചെയ്‌തിരിക്കുന്ന ഉപയോക്താവിന് വയർലെസ് ഡീബഗ്ഗിംഗ് ഓണാക്കാനാകില്ല. ഈ ഫീച്ചർ ഉപയോഗിക്കാൻ അഡ്‌മിൻ ഉപയോക്താവിലേക്ക് മാറുക."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"USB പോർട്ട് പ്രവർത്തനരഹിതമാക്കി"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"ദ്രാവകത്തിൽ നിന്നോ പൊടിയിൽ നിന്നോ നിങ്ങളുടെ ഉപകരണത്തെ പരിരക്ഷിക്കാനായി USB പോർട്ട് പ്രവർത്തനരഹിതമാക്കിയിരിക്കുന്നതിനാൽ അത് ആക്‌സസറികളൊന്നും തിരിച്ചറിയില്ല.\n\n USB പോർട്ട് വീണ്ടും ഉപയോഗിക്കാനാകുമ്പോൾ നിങ്ങളെ അറിയിക്കും."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"ആക്‌സസറികളും ചാർജറുകളും കണ്ടെത്താൻ USB പോർട്ട് പ്രവർത്തനക്ഷമമാക്കുക"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"വോയ്‌സ് സഹായം"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"QR കോഡ് സ്കാനർ"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"അണ്‍ലോക്ക് ചെയ്യുക"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"ഉപകരണം ലോക്ക് ചെയ്തു"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"മുഖം സ്കാൻ ചെയ്യുന്നു"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"അയയ്ക്കുക"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"മുഖം തിരിച്ചറിയാനാകുന്നില്ല"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"പകരം ഫിംഗർപ്രിന്റ് ഉപയോഗിക്കൂ"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"ബ്ലൂടൂത്ത് കണക്‌റ്റുചെയ്തു."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"ബാറ്ററി ശതമാനം അജ്ഞാതമാണ്."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"ഫ്ലൈറ്റ് മോഡ്."</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN ഓണാണ്."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"ബാറ്ററി <xliff:g id="NUMBER">%d</xliff:g> ശതമാനം."</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"ബാറ്ററി <xliff:g id="PERCENTAGE">%1$s</xliff:g> ശതമാനം, നിങ്ങളുടെ ഉപയോഗത്തിൻ്റെ അടിസ്ഥാനത്തിൽ ഏകദേശം <xliff:g id="TIME">%2$s</xliff:g> സമയം കൂടി ശേഷിക്കുന്നു"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"ബാറ്ററി <xliff:g id="PERCENTAGE">%1$d</xliff:g> ശതമാനം, നിങ്ങളുടെ ഉപയോഗത്തിൻ്റെ അടിസ്ഥാനത്തിൽ ഏകദേശം <xliff:g id="TIME">%2$s</xliff:g> സമയം കൂടി ശേഷിക്കുന്നു"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"ബാറ്ററി ചാർജ് ചെയ്യുന്നു, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"എല്ലാ അറിയിപ്പുകളും കാണുക"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"TeleTypewriter പ്രവർത്തനക്ഷമമാണ്."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"റിംഗർ വൈബ്രേറ്റ് ചെയ്യുന്നു."</string>
@@ -386,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"ഒരു ആപ്പ് പങ്കിടുമ്പോൾ, റെക്കോർഡ് ചെയ്യുമ്പോൾ അല്ലെങ്കിൽ കാസ്റ്റ് ചെയ്യുമ്പോൾ, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> എന്നതിന് ആപ്പിൽ കാണിക്കുന്ന അല്ലെങ്കിൽ പ്ലേ ചെയ്യുന്ന എല്ലാത്തിലേക്കും ആക്സസ് ഉണ്ട്. അതിനാൽ, പാസ്‍വേഡുകൾ, പേയ്‌മെന്റ് വിശദാംശങ്ങൾ, സന്ദേശങ്ങൾ അല്ലെങ്കിൽ സൂക്ഷ്‌മമായി കൈകാര്യം ചെയ്യേണ്ട മറ്റു വിവരങ്ങൾ എന്നിവ നൽകുമ്പോൾ സൂക്ഷിക്കുക."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"തുടരുക"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"ഒരു ആപ്പ് പങ്കിടുക അല്ലെങ്കിൽ റെക്കോർഡ് ചെയ്യുക"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"പങ്കിടാനോ റെക്കോർഡ് ചെയ്യാനോ ഈ ആപ്പിനെ അനുവദിക്കണോ?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"പങ്കിടുമ്പോൾ, റെക്കോർഡ് ചെയ്യുമ്പോൾ അല്ലെങ്കിൽ കാസ്റ്റ് ചെയ്യുമ്പോൾ, ഈ ആപ്പിന് നിങ്ങളുടെ സ്ക്രീനിൽ ദൃശ്യമാകുന്നതോ ഉപകരണത്തിൽ പ്ലേ ചെയ്യുന്നതോ ആയ ഏത് കാര്യത്തിലേക്കും ആക്സസ് ഉണ്ട്. അതിനാൽ, പാസ്‍വേഡുകൾ, പേയ്‌മെന്റ് വിശദാംശങ്ങൾ, സന്ദേശങ്ങൾ അല്ലെങ്കിൽ സൂക്ഷ്‌മമായി കൈകാര്യം ചെയ്യേണ്ട മറ്റു വിവരങ്ങൾ എന്നിവ നൽകുമ്പോൾ സൂക്ഷിക്കുക."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"ഒരു ആപ്പ് പങ്കിടുമ്പോൾ, റെക്കോർഡ് ചെയ്യുമ്പോൾ അല്ലെങ്കിൽ കാസ്റ്റ് ചെയ്യുമ്പോൾ, ഈ ആപ്പിന് ആപ്പിൽ കാണിക്കുന്ന അല്ലെങ്കിൽ പ്ലേ ചെയ്യുന്ന എല്ലാത്തിലേക്കും ആക്സസ് ഉണ്ട്. അതിനാൽ, പാസ്‍വേഡുകൾ, പേയ്‌മെന്റ് വിശദാംശങ്ങൾ, സന്ദേശങ്ങൾ അല്ലെങ്കിൽ സൂക്ഷ്‌മമായി കൈകാര്യം ചെയ്യേണ്ട മറ്റു വിവരങ്ങൾ എന്നിവ നൽകുമ്പോൾ സൂക്ഷിക്കുക."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"നിങ്ങളുടെ ഐടി അഡ്‌മിൻ ബ്ലോക്ക് ചെയ്‌തു"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"ഉപകരണ നയം, സ്ക്രീൻ ക്യാപ്‌ചർ ചെയ്യൽ പ്രവർത്തനരഹിതമാക്കി"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"എല്ലാം മായ്‌ക്കുക"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"മാനേജ് ചെയ്യുക"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"ചരിത്രം"</string>
@@ -511,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"ഉപയോഗിക്കാൻ അൺലോക്ക് ചെയ്യുക"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"നിങ്ങളുടെ കാർഡുകൾ ലഭ്യമാക്കുന്നതിൽ ഒരു പ്രശ്‌നമുണ്ടായി, പിന്നീട് വീണ്ടും ശ്രമിക്കുക"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"ലോക്ക് സ്ക്രീൻ ക്രമീകരണം"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"QR കോഡ് സ്‌കാൻ ചെയ്യുക"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"ഔദ്യോഗിക പ്രൊഫൈൽ"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"ഫ്ലൈറ്റ് മോഡ്"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"<xliff:g id="WHEN">%1$s</xliff:g>-നുള്ള നിങ്ങളുടെ അടുത്ത അലാറം കേൾക്കില്ല"</string>
@@ -794,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"സ്ക്രീൻ പൂർണ്ണമായും മാഗ്നിഫൈ ചെയ്യുക"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"സ്‌ക്രീനിന്റെ ഭാഗം മാഗ്നിഫൈ ചെയ്യുക"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"മാറുക"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"ഡയഗണൽ സ്‌ക്രോളിംഗ് അനുവദിക്കുക"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"വലുപ്പം മാറ്റുക"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"മാഗ്നിഫിക്കേഷൻ തരം മാറ്റുക"</string>
@@ -1024,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"എല്ലാ ഉപകരണ ലോഗുകളും ആക്‌സസ് ചെയ്യാൻ <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> എന്നതിനെ അനുവദിക്കണോ?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"ഒറ്റത്തവണ ആക്‌സസ് അനുവദിക്കുക"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"അനുവദിക്കരുത്"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"നിങ്ങളുടെ ഉപകരണത്തിൽ സംഭവിക്കുന്ന കാര്യങ്ങൾ ഉപകരണ ലോഗുകൾ റെക്കോർഡ് ചെയ്യുന്നു. പ്രശ്‌നങ്ങൾ കണ്ടെത്തി പരിഹരിക്കുന്നതിന് ആപ്പുകൾക്ക് ഈ ലോഗുകൾ ഉപയോഗിക്കാൻ കഴിയും.\n\nചില ലോഗുകളിൽ സൂക്ഷ്‌മമായി കൈകാര്യം ചെയ്യേണ്ട വിവരങ്ങൾ അടങ്ങിയിരിക്കാൻ സാധ്യതയുള്ളതിനാൽ, എല്ലാ ഉപകരണ ലോഗുകളും ആക്സസ് ചെയ്യാനുള്ള അനുമതി നിങ്ങൾക്ക് വിശ്വാസമുള്ള ആപ്പുകൾക്ക് മാത്രം നൽകുക. \n\nഎല്ലാ ഉപകരണ ലോഗുകളും ആക്‌സസ് ചെയ്യാനുള്ള അനുവാദം നൽകിയില്ലെങ്കിലും, ഈ ആപ്പിന് അതിന്റെ സ്വന്തം ലോഗുകൾ ആക്‌സസ് ചെയ്യാനാകും. നിങ്ങളുടെ ഉപകരണ നിർമ്മാതാവിന് തുടർന്നും നിങ്ങളുടെ ഉപകരണത്തിലെ ചില ലോഗുകളോ വിവരങ്ങളോ ആക്‌സസ് ചെയ്യാനായേക്കും."</string>
</resources>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index 6be28ddc31fa..a00b0f457554 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"Энэ компьютерээс орохыг байнга зөвшөөрөх"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"Зөвшөөрөх"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"USB алдаа засалт хийх боломжгүй"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"Энэ төхөөрөмжид нэвтэрсэн хэрэглэгч USB дебаг хийх онцлогийг асаах боломжгүй байна. Энэ онцлогийг ашиглахын тулд үндсэн хэрэглэгч рүү сэлгэнэ үү."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"Энэ төхөөрөмжид одоогоор нэвтэрсэн хэрэглэгч USB дебагийг асаах боломжгүй. Энэ онцлогийг ашиглахын тулд админ хэрэглэгч рүү сэлгэнэ үү."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Та системийн хэлийг <xliff:g id="LANGUAGE">%1$s</xliff:g> хэл болгож өөрчлөхийг хүсэж байна уу?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Өөр төхөөрөмжөөс системийн хэлийг өөрчлөх хүсэлт тавьсан"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Хэл солих"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"Энэ сүлжээн дээр үргэлж зөвшөөрөх"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"Зөвшөөрөх"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Wireless debugging-г зөвшөөрөөгүй байна"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"Энэ төхөөрөмжид одоогоор нэвтэрсэн байгаа хэрэглэгч wireless debugging-г асаах боломжгүй. Энэ онцлогийг ашиглахын тулд үндсэн хэрэглэгч рүү сэлгэнэ үү."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"Энэ төхөөрөмжид одоогоор нэвтэрсэн хэрэглэгч wireless debugging-г асаах боломжгүй. Энэ онцлогийг ашиглахын тулд админ хэрэглэгч рүү сэлгэнэ үү."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"USB портыг идэвхгүй болгосон"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"Таны төхөөрөмжийг шингэн зүйл эсвэл бохирдлоос хамгаалахын тулд USB портыг идэвхгүй болгосон бөгөөд энэ нь ямар ч дагалдах хэрэгслийг илрүүлэхгүй.\n\nТанд USB портыг дахин ашиглахад аюулгүй болох үед мэдэгдэх болно."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"Цэнэглэгч болон нэмэлт хэрэгслийг илрүүлэхийн тулд USB портыг идэвхжүүлсэн"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Дуут туслах"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"QR код сканнер"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"Тайлах"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"Төхөөрөмжийг түгжсэн"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Скан хийх нүүр царай"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Илгээх"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"Царайг танихгүй байна"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Оронд нь хурууны хээ ашиглах"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth холбогдсон."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"Батарейн хувь тодорхойгүй байна."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"Нислэгийн горим"</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN асаалттай байна."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"Батарей <xliff:g id="NUMBER">%d</xliff:g> хувьтай."</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Батарей <xliff:g id="PERCENTAGE">%1$s</xliff:g> хувьтай байна. Таны хэрэглээнд тулгуурлан ойролцоогоор <xliff:g id="TIME">%2$s</xliff:g> үлдсэн"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Батарей <xliff:g id="PERCENTAGE">%1$d</xliff:g> хувьтай байна. Таны хэрэглээнд тулгуурлан ойролцоогоор <xliff:g id="TIME">%2$s</xliff:g> үлдсэн"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Батарейг цэнэглэж байна, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"Бүх мэдэгдлийг харах"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"TeleTypewriter идэвхтэй болов."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Хонхны чичиргээ."</string>
@@ -386,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Таныг хуваалцаж, бичиж эсвэл дамжуулж байх үед <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> нь тухайн апп дээр харуулсан эсвэл тоглуулсан аливаа зүйлд хандах эрхтэй. Тиймээс нууц үг, төлбөрийн дэлгэрэнгүй, мессеж эсвэл бусад эмзэг мэдээлэлд болгоомжтой хандаарай."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Үргэлжлүүлэх"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Хуваалцах эсвэл бичих апп"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Энэ аппад хуваалцах эсвэл бичихийг зөвшөөрөх үү?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Таныг хуваалцаж, бичиж эсвэл дамжуулж байх үед энэ апп нь таны дэлгэц дээр харагдаж буй аливаа зүйл эсвэл төхөөрөмж дээр тань тоглуулж буй зүйлд хандах эрхтэй. Тиймээс нууц үг, төлбөрийн дэлгэрэнгүй, мессеж эсвэл бусад эмзэг мэдээлэлд болгоомжтой хандаарай."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Таныг хуваалцаж, бичиж эсвэл дамжуулж байх үед энэ апп нь тухайн апп дээр харуулж эсвэл тоглуулж буй аливаа зүйлд хандах эрхтэй. Тиймээс нууц үг, төлбөрийн дэлгэрэнгүй, мессеж эсвэл бусад эмзэг мэдээлэлд болгоомжтой хандаарай."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Таны IT админ блоклосон"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"Төхөөрөмжийн бодлогоор дэлгэцийн зураг авахыг идэвхгүй болгосон"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Бүгдийг арилгах"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Удирдах"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Түүх"</string>
@@ -511,7 +511,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Ашиглахын тулд түгжээг тайлах"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Таны картыг авахад асуудал гарлаа. Дараа дахин оролдоно уу"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Түгжигдсэн дэлгэцийн тохиргоо"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"QR код скан хийх"</string>
+ <string name="qr_code_scanner_title" msgid="1938155688725760702">"QR код сканнер"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Ажлын профайл"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Нислэгийн горим"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"<xliff:g id="WHEN">%1$s</xliff:g>-т та дараагийн сэрүүлгээ сонсохгүй"</string>
@@ -794,6 +794,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Бүтэн дэлгэцийг томруулах"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Дэлгэцийн нэг хэсгийг томруулах"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Сэлгэх"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Хөндлөн гүйлгэхийг зөвшөөрнө үү"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Хэмжээг өөрчлөх"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"Томруулах төрлийг өөрчлөх"</string>
@@ -1024,4 +1026,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"MMM d EEE"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g>-д төхөөрөмжийн бүх логт хандахыг зөвшөөрөх үү?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"Нэг удаагийн хандалтыг зөвшөөрөх"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Бүү зөвшөөр"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"Төхөөрөмжийн лог нь таны төхөөрөмж дээр юу болж байгааг бичдэг. Аппууд эдгээр логийг асуудлыг олох болон засахад ашиглах боломжтой.\n\nЗарим лог эмзэг мэдээлэл агуулж байж магадгүй тул та зөвхөн итгэдэг аппууддаа төхөөрөмжийн бүх логт хандахыг зөвшөөрнө үү. \n\nХэрэв та энэ аппад төхөөрөмжийн бүх логт хандахыг зөвшөөрөхгүй бол энэ нь өөрийн логт хандах боломжтой хэвээр байх болно. Tаны төхөөрөмжийн үйлдвэрлэгч таны төхөөрөмж дээрх зарим лог эсвэл мэдээлэлд хандах боломжтой хэвээр байж магадгүй."</string>
</resources>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index 7c1dcc356b3d..e6311d609bd2 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"या संगणकावरून नेहमी अनुमती द्या"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"अनुमती द्या"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"USB डीबग करण्‍यास अनुमती नाही"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"सध्‍या या डीव्हाइसमध्‍ये साइन इन केलेला वापरकर्ता USB डीबग करणे सुरू करू शकत नाही. हे वैशिष्‍ट्य वापरण्‍यासाठी, प्राथमिक वापरकर्त्‍यावर स्विच करा."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"सध्‍या या डिव्हाइसमध्‍ये साइन इन केलेला वापरकर्ता USB डीबगिंग सुरू करू शकत नाही. हे वैशिष्‍ट्य वापरण्‍यासाठी ॲडमिन वापरकर्त्यावर स्विच करा."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"तुम्हाला सिस्टीमची भाषा <xliff:g id="LANGUAGE">%1$s</xliff:g> वर बदलायची आहे का?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"दुसऱ्या डिव्हाइसद्वारे सिस्टीमची भाषा बदलण्याची विनंती केली गेली"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"भाषा बदला"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"या नेटवर्कवर नेहमी अनुमती द्या"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"अनुमती द्या"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"वायरलेस डीबगिंग करण्याला अनुमती नाही"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"सध्‍या या डिव्हाइसमध्‍ये साइन इन केलेला वापरकर्ता वायरलेस डीबगिंग सुरू करू शकत नाही. हे वैशिष्‍ट्य वापरण्‍यासाठी प्राथमिक वापरकर्त्‍यावर स्विच करा."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"सध्‍या या डिव्हाइसमध्‍ये साइन इन केलेला वापरकर्ता वायरलेस डीबगिंग सुरू करू शकत नाही. हे वैशिष्‍ट्य वापरण्‍यासाठी ॲडमिन वापरकर्त्‍यावर स्विच करा."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"USB पोर्ट बंद करा"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"तुमच्या डिव्हाइसला ओलावा किंवा धूळीपासून संरक्षित करण्यासाठी, USB पोर्ट बंद आहे आणि अ‍ॅक्सेसरी डिटेक्ट करणार नाही. \n\n तुम्हाला USB पोर्ट पुन्हा वापरणे ठीक आहे तेव्हा सूचित केले जाईल."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"चार्जर आणि अ‍ॅक्सेसरी शोधण्यासाठी USB पोर्ट सुरू केलेले आहे"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"व्हॉइस सहाय्य"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"वॉलेट"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"QR कोड स्कॅनर"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"अनलॉक करा"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"डिव्हाइस लॉक केले"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"चेहरा स्कॅन करत आहे"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"पाठवा"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"चेहरा ओळखू शकत नाही"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"त्याऐवजी फिंगरप्रिंट वापरा"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"ब्लूटूथ कनेक्‍ट केले."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"बॅटरीच्या चार्जिंगची टक्केवारी माहित नाही."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"विमान मोड."</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN सुरू."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"बॅटरी <xliff:g id="NUMBER">%d</xliff:g> टक्के."</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"बॅटरी <xliff:g id="PERCENTAGE">%1$s</xliff:g> टक्के, तुमच्या वापराच्या आधारावर सुमारे <xliff:g id="TIME">%2$s</xliff:g> शिल्लक आहे"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"बॅटरी <xliff:g id="PERCENTAGE">%1$d</xliff:g> टक्के, तुमच्या वापराच्या आधारावर सुमारे <xliff:g id="TIME">%2$s</xliff:g> शिल्लक आहे"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"बॅटरी चार्ज होत आहे, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> टक्के."</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"सर्व सूचना पहा"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"TeleTypewriter सक्षम केले."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"रिंगर व्हायब्रेट."</string>
@@ -386,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"तुम्ही अ‍ॅप शेअर, रेकॉर्ड किंवा कास्ट करत असताना, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ला त्या अ‍ॅपवर दाखवलेल्या किंवा प्ले केलेल्या कोणत्याही गोष्टीचा अ‍ॅक्सेस असतो. त्यामुळे पासवर्ड, पेमेंट तपशील, मेसेज किंवा इतर संवेदनशील माहिती काळजीपूर्वक वापरा."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"पुढे सुरू ठेवा"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"अ‍ॅप शेअर किंवा रेकॉर्ड करा"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"या अ‍ॅपला शेअर किंवा रेकॉर्ड करण्याची अनुमती द्यायची आहे का?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"तुम्ही शेअर, रेकॉर्ड किंवा कास्ट करत असता, तेव्हा या अ‍ॅपला तुमच्या स्क्रीनवर दाखवलेल्या अथवा डिव्हाइसवर प्ले केलेल्या कोणत्याही गोष्टीचा अ‍ॅक्सेस असतो. त्यामुळे पासवर्ड, पेमेंट तपशील, मेसेज किंवा इतर संवेदनशील माहिती काळजीपूर्वक वापरा."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"तुम्ही अ‍ॅप शेअर, रेकॉर्ड किंवा कास्ट करत असताना, या अ‍ॅपला त्या अ‍ॅपवर दाखवलेल्या किंवा प्ले केलेल्या कोणत्याही गोष्टीचा अ‍ॅक्सेस असतो. त्यामुळे पासवर्ड, पेमेंट तपशील, मेसेज अथवा इतर संवेदनशील माहिती काळजीपूर्वक वापरा."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"तुमच्या आयटी ॲडमिनने ब्लॉक केले आहे"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"डिव्हाइस धोरणाने स्‍क्रीन कॅप्‍चर करणे बंद केले आहे"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"सर्व साफ करा"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"व्यवस्थापित करा"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"इतिहास"</string>
@@ -511,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"वापरण्यासाठी अनलॉक करा"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"तुमची कार्ड मिळवताना समस्या आली, कृपया नंतर पुन्हा प्रयत्न करा"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"लॉक स्क्रीन सेटिंग्ज"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"QR कोड स्कॅन करा"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"कार्य प्रोफाईल"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"विमान मोड"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"तुम्ही तुमचा <xliff:g id="WHEN">%1$s</xliff:g> वाजता होणारा पुढील अलार्म ऐकणार नाही"</string>
@@ -794,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"फुल स्क्रीन मॅग्निफाय करा"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"स्क्रीनचा काही भाग मॅग्निफाय करा"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"स्विच करा"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"तिरपे स्क्रोल करण्याची अनुमती द्या"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"आकार बदला"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"मॅग्निफिकेशनचा प्रकार बदला"</string>
@@ -1024,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> ला सर्व डिव्हाइस लॉग अ‍ॅक्सेस करण्याची अनुमती द्यायची आहे का?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"एक वेळ अ‍ॅक्सेसची अनुमती द्या"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"अनुमती देऊ नका"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"तुमच्या डिव्हाइसवर काय होते ते डिव्हाइस लॉग रेकॉर्ड करते. समस्या शोधण्यासाठी आणि त्यांचे निराकरण करण्यासाठी ॲप्स हे लॉग वापरू शकतात.\n\nकाही लॉगमध्ये संवेदनशील माहिती असू शकते, त्यामुळे फक्त तुमचा विश्वास असलेल्या ॲप्सना सर्व डिव्हाइस लॉग अ‍ॅक्सेस करण्याची अनुमती द्या. \n\nतुम्ही या ॲपला सर्व डिव्हाइस लॉग अ‍ॅक्सेस करण्याची अनुमती न दिल्यास, ते तरीही त्याचा स्वतःचा लॉग अ‍ॅक्सेस करू शकते. तुमच्या डिव्हाइसचा उत्पादक तरीही काही लॉग किंवा तुमच्या डिव्हाइसवरील माहिती अ‍ॅक्सेस करू शकतो."</string>
</resources>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index 08132f46c734..b76c3369a16c 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"Sentiasa benarkan komputer ini"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"Benarkan"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"Penyahpepijatan USB tidak dibenarkan"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"Pengguna yang log masuk ke peranti ini pada masa ini tidak boleh menghidupkan penyahpepijatan USB. Untuk menggunakan ciri ini, tukar kepada pengguna utama."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"Pengguna yang log masuk ke peranti ini pada masa ini tidak boleh menghidupkan penyahpepijatan USB. Untuk menggunakan ciri ini, tukar kepada pengguna pentadbir."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Adakah anda ingin menukar bahasa sistem kepada <xliff:g id="LANGUAGE">%1$s</xliff:g>?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Permintaan pertukaran bahasa sistem oleh peranti lain"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Tukar bahasa"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"Sentiasa benarkan pada rangkaian ini"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"Benarkan"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Penyahpepijatan wayarles tidak dibenarkan"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"Pengguna yang telah log masuk ke peranti ini pada masa ini tidak boleh menghidupkan penyahpepijatan wayarles. Untuk menggunakan ciri ini, tukar kepada pengguna utama."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"Pengguna yang log masuk ke peranti ini pada masa ini tidak boleh menghidupkan penyahpepijatan wayarles. Untuk menggunakan ciri ini, tukar kepada pengguna pentadbir."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"Port USB dilumpuhkan"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"Untuk melindungi peranti anda daripada cecair atau serpihan, port USB dilumpuhkan dan tidak akan mengesan sebarang aksesori.\n\nAnda akan dimaklumi apabila selamat untuk menggunakan port USB lagi."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"Port USB didayakan untuk mengesan pengecas dan aksesori"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Bantuan Suara"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"Pengimbas Kod QR"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"Buka kunci"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"Peranti dikunci"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Mengimbas wajah"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Hantar"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"Tak dapat mengecam wajah"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Gunakan cap jari"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth disambungkan."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"Peratusan kuasa bateri tidak diketahui."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"Mod pesawat"</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN dihidupkan."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"Bateri <xliff:g id="NUMBER">%d</xliff:g> peratus."</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Bateri <xliff:g id="PERCENTAGE">%1$s</xliff:g> peratus, tinggal kira-kira <xliff:g id="TIME">%2$s</xliff:g> lagi berdasarkan penggunaan anda"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Bateri <xliff:g id="PERCENTAGE">%1$d</xliff:g> peratus, tinggal kira-kira <xliff:g id="TIME">%2$s</xliff:g> lagi berdasarkan penggunaan anda"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Bateri mengecas, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> peratus."</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"Lihat semua pemberitahuan"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"Mesin Teletaip didayakan."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Pendering bergetar."</string>
@@ -305,28 +310,17 @@
<string name="sensor_privacy_mic_unblocked_toast_content" msgid="306555320557065068">"Mikrofon tersedia"</string>
<string name="sensor_privacy_camera_unblocked_toast_content" msgid="7843105715964332311">"Kamera tersedia"</string>
<string name="sensor_privacy_mic_camera_unblocked_toast_content" msgid="7339355093282661115">"Mikrofon dan kamera tersedia"</string>
- <!-- no translation found for sensor_privacy_mic_turned_on_dialog_title (6348853159838376513) -->
- <skip />
- <!-- no translation found for sensor_privacy_mic_turned_off_dialog_title (5760464281790732849) -->
- <skip />
- <!-- no translation found for sensor_privacy_mic_unblocked_dialog_content (4889961886199270224) -->
- <skip />
- <!-- no translation found for sensor_privacy_mic_blocked_no_exception_dialog_content (5864898470772965394) -->
- <skip />
- <!-- no translation found for sensor_privacy_mic_blocked_with_exception_dialog_content (810289713700437896) -->
- <skip />
- <!-- no translation found for sensor_privacy_camera_turned_on_dialog_title (8039095295100075952) -->
- <skip />
- <!-- no translation found for sensor_privacy_camera_turned_off_dialog_title (1936603903120742696) -->
- <skip />
- <!-- no translation found for sensor_privacy_camera_unblocked_dialog_content (7847190103011782278) -->
- <skip />
- <!-- no translation found for sensor_privacy_camera_blocked_dialog_content (3182428709314874616) -->
- <skip />
- <!-- no translation found for sensor_privacy_htt_blocked_dialog_content (3333321592997666441) -->
- <skip />
- <!-- no translation found for sensor_privacy_dialog_open_settings (1503088305279285048) -->
- <skip />
+ <string name="sensor_privacy_mic_turned_on_dialog_title" msgid="6348853159838376513">"Mikrofon dihidupkan"</string>
+ <string name="sensor_privacy_mic_turned_off_dialog_title" msgid="5760464281790732849">"Mikrofon dimatikan"</string>
+ <string name="sensor_privacy_mic_unblocked_dialog_content" msgid="4889961886199270224">"Mikrofon didayakan untuk semua apl dan perkhidmatan."</string>
+ <string name="sensor_privacy_mic_blocked_no_exception_dialog_content" msgid="5864898470772965394">"Akses mikrofon dilumpuhkan untuk semua apl dan perkhidmatan. Anda boleh mendayakan akses mikrofon dalam Tetapan &gt; Privasi &gt; Mikrofon."</string>
+ <string name="sensor_privacy_mic_blocked_with_exception_dialog_content" msgid="810289713700437896">"Akses mikrofon dilumpuhkan untuk semua apl dan perkhidmatan. Anda boleh menukar tetapan ini dalam Tetapan &gt; Privasi &gt; Mikrofon."</string>
+ <string name="sensor_privacy_camera_turned_on_dialog_title" msgid="8039095295100075952">"Kamera dihidupkan"</string>
+ <string name="sensor_privacy_camera_turned_off_dialog_title" msgid="1936603903120742696">"Kamera dimatikan"</string>
+ <string name="sensor_privacy_camera_unblocked_dialog_content" msgid="7847190103011782278">"Kamera didayakan untuk semua apl dan perkhidmatan."</string>
+ <string name="sensor_privacy_camera_blocked_dialog_content" msgid="3182428709314874616">"Akses kamera dilumpuhkan untuk semua apl dan perkhidmatan."</string>
+ <string name="sensor_privacy_htt_blocked_dialog_content" msgid="3333321592997666441">"Untuk menggunakan butang mikrofon, dayakan akses mikrofon dalam Tetapan."</string>
+ <string name="sensor_privacy_dialog_open_settings" msgid="1503088305279285048">"Buka tetapan."</string>
<string name="media_seamless_other_device" msgid="4654849800789196737">"Peranti lain"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Togol Ikhtisar"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Anda tidak akan diganggu oleh bunyi dan getaran, kecuali daripada penggera, peringatan, acara dan pemanggil yang anda tetapkan. Anda masih mendengar item lain yang anda pilih untuk dimainkan termasuk muzik, video dan permainan."</string>
@@ -397,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Apabila anda berkongsi, merakam atau menghantar apl, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> mempunyai akses kepada apa-apa yang dipaparkan atau dimainkan pada apl tersebut. Jadi berhati-hati dengan kata laluan, butiran pembayaran, mesej atau maklumat sensitif lain."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Teruskan"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Kongsi atau rakam apl"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Benarkan apl ini berkongsi atau merakam?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Apabila anda berkongsi, merakam atau menghantar, apl ini mempunyai akses kepada apa-apa yang boleh dilihat pada skrin anda atau dimainkan pada peranti anda. Jadi berhati-hati dengan kata laluan, butiran pembayaran, mesej atau maklumat sensitif lain."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Apabila anda berkongsi, merakam atau menghantar apl, apl ini mempunyai akses kepada apa-apa yang dipaparkan atau dimainkan pada apl tersebut. Jadi berhati-hati dengan kata laluan, butiran pembayaran, mesej atau maklumat sensitif lain."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Disekat oleh pentadbir IT anda"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"Tangkapan skrin dilumpuhkan oleh dasar peranti"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Kosongkan semua"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Urus"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Sejarah"</string>
@@ -522,7 +511,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Buka kunci untuk menggunakan"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Terdapat masalah sewaktu mendapatkan kad anda. Sila cuba sebentar lagi"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Tetapan skrin kunci"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"Imbas kod QR"</string>
+ <string name="qr_code_scanner_title" msgid="1938155688725760702">"Pengimbas kod QR"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Profil kerja"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Mod pesawat"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Anda tidak akan mendengar penggera yang seterusnya <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -805,6 +794,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Besarkan skrin penuh"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Besarkan sebahagian skrin"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Tukar"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Benarkan penatalan pepenjuru"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Ubah saiz"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"Tukar jenis pembesaran"</string>
@@ -1035,4 +1026,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"Benarkan <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> mengakses semua log peranti?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"Benarkan akses satu kali"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Jangan benarkan"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"Log peranti merekodkan perkara yang berlaku pada peranti anda. Apl boleh menggunakan log ini untuk menemukan dan membetulkan masalah.\n\nSesetengah log mungkin mengandungi maklumat sensitif, jadi hanya benarkan apl yang anda percaya untuk mengakses semua log peranti. \n\nJika anda tidak membenarkan apl ini mengakses semua log peranti, apl ini masih boleh mengakses log sendiri. Pengilang peranti anda mungkin masih dapat mengakses sesetengah log atau maklumat pada peranti anda."</string>
</resources>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 51dbb5dd267d..2a00807fb52a 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"ဒီကွန်ပျူတာမှ အမြဲခွင့်ပြုရန်"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"ခွင့်ပြုရန်"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"USB အမှားပြင်ဆင်ခြင်း ခွင့်မပြုပါ"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"ဤစက်ပစ္စည်းသို့ လက်ရှိဝင်ရောက်ထားသည့် အသုံးပြုသူသည် USB အမှားပြင်ဆင်ခြင်းကို ဖွင့်၍မရပါ။ ဤဝန်ဆောင်မှုကို အသုံးပြုရန် အဓိကအသုံးပြုသူအဖြစ်သို့ ပြောင်းပါ။"</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"ဤစက်သို့ လက်ရှိလက်မှတ်ထိုးဝင်ထားသူသည် USB အမှားရှာပြင်ခြင်းကို ဖွင့်၍မရပါ။ ဤဝန်ဆောင်မှု အသုံးပြုရန် စီမံခန့်ခွဲသူအဖြစ်ပြောင်းပါ။"</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"စနစ်၏ ဘာသာစကားကို <xliff:g id="LANGUAGE">%1$s</xliff:g> သို့ ပြောင်းလိုသလား။"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"စက်နောက်တစ်ခုက စနစ်၏ ဘာသာစကားပြောင်းရန် တောင်းဆိုထားသည်"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"ဘာသာစကားပြောင်းရန်"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"ဤကွန်ရက်ကို အမြဲခွင့်ပြုပါ"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"ခွင့်ပြုရန်"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"ကြိုးမဲ့ အမှားရှာပြင်ခြင်းကို ခွင့်မပြုပါ"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"ဤစက်ပစ္စည်းသို့ လက်ရှိဝင်ရောက်ထားသည့် အသုံးပြုသူသည် ကြိုးမဲ့ အမှားပြင်ဆင်ခြင်းကို ဖွင့်၍မရပါ။ ဤဝန်ဆောင်မှုကို အသုံးပြုရန် အဓိကအသုံးပြုသူအဖြစ်သို့ ပြောင်းပါ။"</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"ဤစက်သို့ လက်ရှိလက်မှတ်ထိုးဝင်ထားသူသည် ကြိုးမဲ့ အမှားရှာပြင်ခြင်းကို ဖွင့်၍မရပါ။ ဤဝန်ဆောင်မှု အသုံးပြုရန် စီမံခန့်ခွဲသူအဖြစ်ပြောင်းပါ။"</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"USB ပို့တ် ပိတ်ပြီးပြီ"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"USB ပို့တ်ကို ပိတ်၍ သင့်ကိရိယာသို့ အရည် သို့မဟုတ် အမှိုက်စများ မဝင်စေရန် ကာကွယ်ပါ၊ မည်သည့် အပိုပစ္စည်းကိုမျှ အာရုံခံသိရှိနိုင်တော့မည် မဟုတ်ပါ။\n\nUSB ပို့တ်ကို ပြန်အသုံးပြုနိုင်သည့်အခါ သင့်ကိုအကြောင်းကြားပါမည်။"</string>
<string name="usb_port_enabled" msgid="531823867664717018">"အားသွင်းကိရိယာနှင့် ဆက်စပ်ပစ္စည်းများ သိရှိရန် USB ပို့တ် ဖွင့်ထားသည်"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"အသံ အကူအညီ"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"QR ကုဒ်ဖတ်စနစ်"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"သော့ဖွင့်ရန်"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"စက်ပစ္စည်းကို လော့ခ်ချထားသည်"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"မျက်နှာ စကင်ဖတ်နေသည်"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"ပို့ရန်"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"မျက်နှာကို မမှတ်မိပါ"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"လက်ဗွေကို အစားထိုးသုံးပါ"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"ဘလူးတုသ်ချိတ်ဆက်ထားမှု"</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"ဘက်ထရီရာခိုင်နှုန်းကို မသိပါ။"</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"လေယာဉ်ပျံမုဒ်"</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN ကို ဖွင့်ထားသည်။"</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"ဘက်ထရီ <xliff:g id="NUMBER">%d</xliff:g> ရာခိုင်နှုန်း။"</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"ဘက်ထရီ <xliff:g id="PERCENTAGE">%1$s</xliff:g> ရာခိုင်နှုန်း၊ သင်၏ အသုံးပြုမှုအပေါ် မူတည်၍ <xliff:g id="TIME">%2$s</xliff:g> ခန့်ကျန်သည်"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"ဘက်ထရီ <xliff:g id="PERCENTAGE">%1$d</xliff:g> ရာခိုင်နှုန်း၊ သင်၏ အသုံးပြုမှုအပေါ် မူတည်၍ <xliff:g id="TIME">%2$s</xliff:g> ခန့်ကျန်သည်"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"ဘက်ထရီအားသွင်းနေသည်၊ <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> %%။"</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"သတိပေးချက်များအားလုံးကို ကြည့်ရန်"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"TeleTypewriter ရရှိသည်။"</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"တုန်ခါခြင်း ဖုန်းမြည်သံ"</string>
@@ -215,7 +220,7 @@
<string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"ဖန်သားပြင် အနေအထားက အလျားလိုက်အဖြစ် ပုံသေ လုပ်ထားပါသည်"</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"ဖန်သားပြင် အနေအထားက ဒေါင်လိုက်အဖြစ် ပုံသေ လုပ်ထားပါသည်"</string>
<string name="dessert_case" msgid="9104973640704357717">"မုန့်ထည့်သော ပုံး"</string>
- <string name="start_dreams" msgid="9131802557946276718">"ဖန်သားပြင်အသုံးပြုမှု ချွေတာမှုစနစ်"</string>
+ <string name="start_dreams" msgid="9131802557946276718">"စခရင်နားချိန်"</string>
<string name="ethernet_label" msgid="2203544727007463351">"အီသာနက်"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"မနှောင့်ယှက်ရ"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"ဘလူးတုသ်"</string>
@@ -229,7 +234,7 @@
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"အော်တို-လည်"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"မျက်နှာပြင်အား အလိုအလျောက်လှည့်ခြင်း"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"တည်နေရာ"</string>
- <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"စကရင်ချွေတာစနစ်"</string>
+ <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"စကရင်နားချိန်"</string>
<string name="quick_settings_camera_label" msgid="5612076679385269339">"ကင်မရာသုံးခွင့်"</string>
<string name="quick_settings_mic_label" msgid="8392773746295266375">"မိုက်သုံးခွင့်"</string>
<string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"ရနိုင်သည်"</string>
@@ -386,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"အက်ပ်ဖြင့် မျှဝေ၊ ရိုက်ကူး (သို့) ကာစ်လုပ်သည့်အခါ <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> သည် ၎င်းအက်ပ်တွင် ပြထားသည့် (သို့) ဖွင့်ထားသည့် အရာအားလုံးကို တွေ့နိုင်သည်။ ထို့ကြောင့် စကားဝှက်၊ ငွေပေးချေမှု အချက်အလက်၊ မက်ဆေ့ဂျ် (သို့) အခြားအရေးကြီးအချက်အလက်များနှင့်ပတ်သက်၍ ဂရုစိုက်ပါ။"</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"ရှေ့ဆက်ရန်"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"အက်ပ် မျှဝေခြင်း (သို့) ရိုက်ကူးခြင်း"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"ဤအက်ပ်ကို မျှဝေ (သို့) ရိုက်ကူး ခွင့်ပြုမလား။"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"မျှဝေ၊ ရိုက်ကူး (သို့) ကာစ်လုပ်သည့်အခါ ဤအက်ပ်သည် သင့်ဖန်သားပြင်ရှိ မြင်နိုင်သည့် (သို့) သင့်စက်တွင် ဖွင့်ထားသည့် အရာအားလုံးကို တွေ့နိုင်သည်။ ထို့ကြောင့် စကားဝှက်၊ ငွေပေးချေမှု အချက်အလက်၊ မက်ဆေ့ဂျ် (သို့) အခြားသတိထားရမည့် အချက်အလက်များနှင့် ပတ်သက်၍ သတိပြုပါ။"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"အက်ပ်ဖြင့် မျှဝေ၊ ရိုက်ကူး (သို့) ကာစ်လုပ်သည့်အခါ ဤအက်ပ်သည် ၎င်းတွင် ပြထားသည့် (သို့) ဖွင့်ထားသည့် အရာအားလုံးကို တွေ့နိုင်သည်။ ထို့ကြောင့် စကားဝှက်၊ ငွေပေးချေမှု အချက်အလက်၊ မက်ဆေ့ဂျ် (သို့) အခြားသတိထားရမည့် အချက်အလက်များနှင့်ပတ်သက်၍ သတိပြုပါ။"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"သင်၏ IT စီမံခန့်ခွဲသူက ပိတ်ထားသည်"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"ကိရိယာဆိုင်ရာ မူဝါဒက ဖန်သားပြင်ပုံဖမ်းခြင်းကို ပိတ်ထားသည်"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"အားလုံးရှင်းရန်"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"စီမံရန်"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"မှတ်တမ်း"</string>
@@ -511,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"သုံးရန် လော့ခ်ဖွင့်ပါ"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"သင်၏ကတ်များ ရယူရာတွင် ပြဿနာရှိနေသည်၊ နောက်မှ ထပ်စမ်းကြည့်ပါ"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"လော့ခ်မျက်နှာပြင် ဆက်တင်များ"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"QR ကုဒ် စကင်ဖတ်ခြင်း"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"အလုပ် ပရိုဖိုင်"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"လေယာဉ်ပျံမုဒ်"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"<xliff:g id="WHEN">%1$s</xliff:g> ၌သင့်နောက်ထပ် နှိုးစက်ကို ကြားမည်မဟုတ်ပါ"</string>
@@ -794,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"ဖန်သားပြင်အပြည့် ချဲ့သည်"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"ဖန်သားပြင် တစ်စိတ်တစ်ပိုင်းကို ချဲ့ပါ"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"ခလုတ်"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"ထောင့်ဖြတ် လှိမ့်ခွင့်ပြုရန်"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"အရွယ်အစားပြန်ပြုပြင်ရန်"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"ချဲ့သည့်ပုံစံ ပြောင်းရန်"</string>
@@ -1024,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE၊ MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> ကို စက်မှတ်တမ်းအားလုံး သုံးခွင့်ပြုမလား။"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"တစ်ခါသုံး ဝင်ခွင့်ပေးရန်"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"ခွင့်မပြုပါ"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"သင့်စက်ရှိ အဖြစ်အပျက်များကို စက်မှတ်တမ်းများက မှတ်တမ်းတင်သည်။ အက်ပ်များက ပြဿနာများ ရှာဖွေပြီးဖြေရှင်းရန် ဤမှတ်တမ်းများကို သုံးနိုင်သည်။\n\nအချို့မှတ်တမ်းများတွင် သတိထားရမည့်အချက်အလက်များ ပါဝင်နိုင်သဖြင့် ယုံကြည်ရသည့် အက်ပ်များကိုသာ စက်မှတ်တမ်းအားလုံး သုံးခွင့်ပြုပါ။ \n\nဤအက်ပ်ကို စက်မှတ်တမ်းအားလုံး သုံးခွင့်မပြုသော်လည်း ၎င်းက ကိုယ်ပိုင်မှတ်တမ်းများ သုံးနိုင်သေးသည်။ သင့်စက်ရှိ အချို့မှတ်တမ်းများ (သို့) အချက်အလက်များကို သင့်စက်ထုတ်လုပ်သူက သုံးနိုင်ပါသေးသည်။"</string>
</resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index eba97317bbb9..b1da115e55b8 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"Tillat alltid fra denne datamaskinen"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"Tillat"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"USB-feilsøking er ikke tillatt"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"Brukeren som for øyeblikket er logget på denne enheten, kan ikke slå på USB-feilsøking. For å bruke denne funksjonen, bytt til hovedbrukeren."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"Brukeren som for øyeblikket er logget på denne enheten, kan ikke slå på USB-feilsøking. For å bruke denne funksjonen, bytt til en administratorbruker."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Vil du bytte systemspråk til <xliff:g id="LANGUAGE">%1$s</xliff:g>?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Bytte av systemspråk er forespurt av en annen enhet"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Bytt språk"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"Tillat alltid på dette nettverket"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"Tillat"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Trådløs feilsøking er ikke tillatt"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"Brukeren som for øyeblikket er logget på denne enheten, kan ikke slå på trådløs feilsøking. For å bruke denne funksjonen, bytt til primærbrukeren."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"Brukeren som for øyeblikket er logget på denne enheten, kan ikke slå på trådløs feilsøking. For å bruke denne funksjonen, bytt til en administratorbruker."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"USB-porten er deaktivert"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"For å beskytte enheten din mot væsker eller rusk er USB-porten deaktivert og kan ikke oppdage tilbehør.\n\nDu blir varslet når det er trygt å bruke USB-porten igjen."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"Registrering av ladere og tilbehør er slått på for USB-porten"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Talehjelp"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"QR-kodeskanner"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"Lås opp"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"Enheten er låst"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Skanning av ansikt"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Send"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"Ansiktet gjenkjennes ikke"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Bruk fingeravtrykk"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth er tilkoblet."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"Batteriprosenten er ukjent."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"Flymodus."</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN på."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"Batteri – <xliff:g id="NUMBER">%d</xliff:g> prosent."</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Batterinivået er <xliff:g id="PERCENTAGE">%1$s</xliff:g> prosent – omtrent <xliff:g id="TIME">%2$s</xliff:g> gjenstår basert på bruken din"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Batterinivået er <xliff:g id="PERCENTAGE">%1$d</xliff:g> prosent – omtrent <xliff:g id="TIME">%2$s</xliff:g> gjenstår basert på bruken din"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Batteriet lades – <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> prosent."</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"Se alle varslene"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"TeleTypewriter er aktivert."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Vibreringsmodus."</string>
@@ -386,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Når du deler, tar opp eller caster en app, har <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> tilgang til alt som vises eller spilles av i den aktuelle appen. Derfor bør du være forsiktig med passord, betalingsopplysninger, meldinger og annen sensitiv informasjon."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Fortsett"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Del eller ta opp en app"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Vil du tillate at denne appen deler eller tar opp?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Når du deler, tar opp eller caster noe, har denne appen tilgang til alt som vises på skjermen eller spilles av på enheten. Derfor bør du være forsiktig med passord, betalingsopplysninger, meldinger og annen sensitiv informasjon."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Når du deler, tar opp eller caster en app, har denne appen tilgang til alt som vises eller spilles av i den aktuelle appen. Derfor bør du være forsiktig med passord, betalingsopplysninger, meldinger og annen sensitiv informasjon."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Blokkert av IT-administratoren"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"Skjermdumper er deaktivert av enhetsinnstillingene"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Fjern alt"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Administrer"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Logg"</string>
@@ -511,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Lås opp for å bruke"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Det oppsto et problem med henting av kortene. Prøv på nytt senere"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Innstillinger for låseskjermen"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"Skann QR-koden"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Work-profil"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Flymodus"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Du hører ikke neste innstilte alarm <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -794,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Forstørr hele skjermen"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Forstørr en del av skjermen"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Bytt"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Tillat diagonal rulling"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Endre størrelse"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"Endre forstørringstype"</string>
@@ -1024,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE d. MMM"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"Vil du gi <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> tilgang til alle enhetslogger?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"Gi éngangstilgang"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Ikke tillat"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"Enhetslogger registrerer det som skjer på enheten din. Apper kan bruke disse loggene til å finne og løse problemer.\n\nNoen logger kan inneholde sensitiv informasjon, så du bør bare gi tilgang til alle enhetslogger til apper du stoler på. \n\nHvis du ikke gir denne appen tilgang til alle enhetslogger, har den fortsatt tilgang til sine egne logger. Enhetsprodusenten kan fortsatt ha tilgang til visse logger eller noe informasjon på enheten din."</string>
</resources>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index 23ff09be80e2..12b319e62c4e 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"यो कम्प्युटरबाट सधैँ अनुमति दिनुहोस्"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"अनुमति दिनुहोस्"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"USB डिबग गर्न अनुमति छैन"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"हाल यस डिभाइसमा साइन इन हुनुभएको प्रयोगकर्ताले USB डिबग सक्रिय गर्न सक्नुहुन्न। यो सुविधाको प्रयोग गर्न प्राथमिक प्रयोगकर्तामा बदल्नुहोस्‌।"</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"हालैमा यस डिभाइसमा साइन इन भएका प्रयोगकर्ताले USB डिबगिङ सक्रिय गर्न सक्दैनन्। यो सुविधा प्रयोग गर्न कृपया खाताका एड्मिनका रूपमा साइन इन गर्नुहोस्।"</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"तपाईं सिस्टमको भाषा बदलेर <xliff:g id="LANGUAGE">%1$s</xliff:g> बनाउन चाहनुहुन्छ?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"अर्को डिभाइसले सिस्टमको भाषा परिवर्तन गर्न अनुरोध गरेको छ"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"भाषा परिवर्तन गर्नुहोस्"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"यस नेटवर्कमा सधैँ अनुमति दिइयोस्"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"अनुमति दिनुहोस्"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"वायरलेस डिबगिङ सेवालाई अनुमति दिइएको छैन"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"हाल यस डिभाइसमा साइन इन हुनुभएका प्रयोगकर्ता वायरलेस डिबगिङ सक्रिय गर्न सक्नुहुन्न। यो सुविधाको प्रयोग गर्न प्राथमिक प्रयोगकर्ताको खातामार्फत साइन इन गर्नुहोस्।"</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"हालैमा यस डिभाइसमा साइन इन भएका प्रयोगकर्ताले USB डिबगिङ सक्रिय गर्न सक्दैनन्। यो सुविधा प्रयोग गर्न कृपया खाताका एड्मिनका रूपमा साइन इन गर्नुहोस्।"</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"USB पोर्ट असक्षम पारियो"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"तपाईंको यन्त्रलाई तरल पदार्थ वा धुलोबाट जोगाउन यसको USB पोर्ट असक्षम पारिएको छ र यसले कुनै पनि सहायक उपकरणहरू पहिचान गर्ने छैन।\n\nउक्त USB पोर्ट फेरि प्रयोग गर्दा हुन्छ भने तपाईंलाई यसबारे सूचित गरिने छ।"</string>
<string name="usb_port_enabled" msgid="531823867664717018">"चार्जर तथा सामानहरू पत्ता लगाउन सक्षम पारिएको USB पोर्ट"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"आवाज सहायता"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"QR कोड स्क्यानर"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"खोल्नुहोस्"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"यन्त्र लक गरिएको छ"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"अनुहार स्क्यान गर्दै"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"पठाउनुहोस्"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"अनुहार पहिचान गर्न सकिएन"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"बरु फिंगरप्रिन्ट प्रयोग गर्नुहोस्"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"ब्लुटुथ जडान भयो।"</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"ब्याट्रीमा कति प्रतिशत चार्ज छ भन्ने कुराको जानाकरी छैन।"</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"हवाइजहाज मोड।"</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN सक्रिय छ।"</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"ब्याट्री <xliff:g id="NUMBER">%d</xliff:g> प्रतिशत"</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"ब्याट्रीको चार्ज <xliff:g id="PERCENTAGE">%1$s</xliff:g> प्रतिशत छ, तपाईंको प्रयोगका आधारमा <xliff:g id="TIME">%2$s</xliff:g> बाँकी छ"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"ब्याट्रीको चार्ज <xliff:g id="PERCENTAGE">%1$d</xliff:g> प्रतिशत छ, तपाईंको प्रयोगका आधारमा <xliff:g id="TIME">%2$s</xliff:g> बाँकी छ"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"ब्याट्री चार्ज हुँदैछ, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> प्रतिशत भयो।"</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"सबै सूचनाहरू हेर्नुहोस्"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"टेलि टाइपराइटर सक्षम गरियो।"</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"बज्ने कम्पन हुन्छ।"</string>
@@ -386,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"तपाईंले सेयर गर्दा, रेकर्ड गर्दा वा कास्ट गर्दा<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ले तपाईंको स्क्रिनमा देखिने वा डिभाइसमा प्ले गरिएका सबै कुरा खिच्न सक्छ। त्यसैले पासवर्ड, भुक्तानीको विवरण, म्यासेज वा अन्य संवेदनशील जानकारी सुरक्षित राख्नुहोला।"</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"जारी राख्नुहोस्"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"सेयर वा रेकर्ड गर्नका लागि एप चयन गर्नुहोस्"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"यो एपलाई सेयर गर्न वा रेकर्ड गर्न दिने हो?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"यो एपले तपाईंले सेयर गर्दा, रेकर्ड गर्दा वा कास्ट गर्दा तपाईंको स्क्रिनमा देखिने वा डिभाइसमा प्ले गरिएका सबै कुरा खिच्न सक्छ। त्यसैले रेकर्ड गर्दा पासवर्ड, भुक्तानीको विवरण, म्यासेज वा अन्य संवेदनशील जानकारी सुरक्षित राख्नुहोला।"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"तपाईंले सेयर गर्दा, रेकर्ड गर्दा वा कास्ट गर्दा यो एपले तपाईंको स्क्रिनमा देखिने वा डिभाइसमा प्ले गरिएका सबै कुरा खिच्न सक्छ। त्यसैले पासवर्ड, भुक्तानीको विवरण, म्यासेज वा अन्य संवेदनशील जानकारी सुरक्षित राख्नुहोला।"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"तपाईंका सूचना प्रविधि व्यवस्थापकले ब्लक गर्नुभएको छ"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"डिभाइसको नीतिका कारण स्क्रिन क्याप्चर गर्ने सुविधा अफ गरिएको छ"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"सबै हटाउनुहोस्"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"व्यवस्थित गर्नुहोस्"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"इतिहास"</string>
@@ -511,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"यो वालेट प्रयोग गर्न डिभाइस अनलक गर्नुहोस्"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"तपाईंका कार्डहरू प्राप्त गर्ने क्रममा समस्या भयो, कृपया पछि फेरि प्रयास गर्नुहोस्"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"लक स्क्रिनसम्बन्धी सेटिङ"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"QR कोड स्क्यान गर्नुहोस्"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"कार्य प्रोफाइल"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"हवाइजहाज मोड"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"तपाईँले आफ्नो अर्को अलार्म <xliff:g id="WHEN">%1$s</xliff:g> सुन्नुहुने छैन"</string>
@@ -794,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"पूरै स्क्रिन जुम इन गर्नुहोस्"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"स्क्रिनको केही भाग म्याग्निफाइ गर्नुहोस्"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"बदल्नुहोस्"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"डायगोनल तरिकाले स्क्रोल गर्ने अनुमति दिनुहोस्"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"आकार बदल्नुहोस्"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"जुम इन गर्ने सुविधाको प्रकार बदल्नुहोस्"</string>
@@ -1024,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> लाई डिभाइसका सबै लग हेर्ने अनुमति दिने हो?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"एक पटक प्रयोग गर्ने अनुमति दिनुहोस्"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"अनुमति नदिनुहोस्"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"डिभाइसका लगले तपाईंको डिभाइसमा भएका विभिन्न गतिविधिको अभिलेख राख्छन्। एपहरू यी लगका आधारमा समस्या पत्ता लगाउन र तिनको समाधान गर्न सक्छन्।\n\nकेही लगहरूमा संवेदनशील जानकारी समावेश हुन सक्ने भएकाले आफूले भरोसा गर्ने एपलाई मात्र डिभाइसका सबै लग हेर्ने अनुमति दिनुहोस्। \n\nतपाईंले यो एपलाई डिभाइसका सबै लग हेर्ने अनुमति दिनुभएन भने पनि यसले आफ्नै लग भने हेर्न सक्छ। तपाईंको डिभाइसका उत्पादकले पनि तपाईंको डिभाइसमा भएका केही लग वा जानकारी हेर्न सक्ने सम्भावना हुन्छ।"</string>
</resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index a36f811fec53..e3848812a581 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"Altijd toestaan vanaf deze computer"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"Toestaan"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"USB-foutopsporing niet toegestaan"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"De gebruiker die momenteel is ingelogd op dit apparaat, kan USB-foutopsporing niet aanzetten. Als je deze functie wilt gebruiken, schakel je naar de primaire gebruiker."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"De gebruiker die momenteel is ingelogd op dit apparaat, kan USB-foutopsporing niet aanzetten. Als je deze functie wilt gebruiken, schakel je over naar een beheerdersaccount."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Wil je de systeemtaal wijzigen naar het <xliff:g id="LANGUAGE">%1$s</xliff:g>?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Wijziging van systeemtaal aangevraagd door een ander apparaat"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Taal wijzigen"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"Altijd toestaan in dit netwerk"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"Toestaan"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Draadloze foutopsporing niet toegestaan"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"De gebruiker die momenteel is ingelogd op dit apparaat, kan draadloze foutopsporing niet aanzetten. Als je deze functie wilt gebruiken, schakel je over naar de primaire gebruiker."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"De gebruiker die momenteel is ingelogd op dit apparaat, kan draadloze foutopsporing niet aanzetten. Als je deze functie wilt gebruiken, schakel je over naar een beheerdersaccount."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"USB-poort staat uit"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"De USB-poort staat uit en detecteert geen accessoires, zodat je apparaat wordt beschermd tegen vloeistof en vuil.\n\nJe ontvangt een melding wanneer je de USB-poort weer kunt gebruiken."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"USB-poort kan opladers en accessoires detecteren"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Spraakassistent"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Portemonnee"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"QR-codescanner"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"Ontgrendelen"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"Apparaat vergrendeld"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Gezicht scannen"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Verzenden"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"Gezicht niet herkend"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Vingerafdruk gebruiken"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth-verbinding ingesteld."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"Batterijpercentage onbekend."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"Vliegtuigmodus."</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN staat aan."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"Batterij: <xliff:g id="NUMBER">%d</xliff:g> procent."</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Batterij op <xliff:g id="PERCENTAGE">%1$s</xliff:g> procent, nog ongeveer <xliff:g id="TIME">%2$s</xliff:g> op basis van je gebruik"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Batterij op <xliff:g id="PERCENTAGE">%1$d</xliff:g> procent, nog ongeveer <xliff:g id="TIME">%2$s</xliff:g> op basis van je gebruik"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Batterij wordt opgeladen, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%% procent."</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"Alle meldingen bekijken"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"TeleTypewriter staat aan."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Belsoftware trilt."</string>
@@ -386,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Als je deelt, opneemt of cast, heeft <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> toegang tot alles dat wordt getoond of afgespeeld in die app. Wees daarom voorzichtig met wachtwoorden, betalingsgegevens, berichten en andere gevoelige informatie."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Doorgaan"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"App delen of opnemen"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Deze app toestaan om te delen of op te nemen?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Als je deelt, opneemt of cast, heeft deze app toegang tot alles dat zichtbaar is op je scherm of wordt afgespeeld op je apparaat. Wees daarom voorzichtig met wachtwoorden, betalingsgegevens, berichten en andere gevoelige informatie."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Als je deelt, opneemt of cast, heeft deze app toegang tot alles dat wordt getoond of afgespeeld in die app. Wees daarom voorzichtig met wachtwoorden, betalingsgegevens, berichten en andere gevoelige informatie."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Geblokkeerd door je IT-beheerder"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"Schermopname staat uit vanwege apparaatbeleid"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Alles wissen"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Beheren"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Geschiedenis"</string>
@@ -511,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Ontgrendelen om te gebruiken"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Er is een probleem opgetreden bij het ophalen van je kaarten. Probeer het later opnieuw."</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Instellingen voor vergrendelscherm"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"QR-code scannen"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Werkprofiel"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Vliegtuigmodus"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Je hoort je volgende wekker niet <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -794,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Volledig scherm vergroten"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Deel van het scherm vergroten"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Schakelen"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Diagonaal scrollen toestaan"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Formaat aanpassen"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"Vergrotingstype wijzigen"</string>
@@ -1024,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE d mmm"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"u:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> toegang geven tot alle apparaatlogboeken?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"Eenmalige toegang toestaan"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Niet toestaan"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"Apparaatlogboeken leggen vast wat er op je apparaat gebeurt. Apps kunnen deze logboeken gebruiken om problemen op te sporen en te verhelpen.\n\nSommige logboeken kunnen gevoelige informatie bevatten, dus geef alleen apps die je vertrouwt toegang tot alle apparaatlogboeken. \n\nAls je deze app geen toegang tot alle apparaatlogboeken geeft, heeft de app nog wel toegang tot de eigen logboeken. De fabrikant van je apparaat heeft misschien nog steeds toegang tot bepaalde logboeken of informatie op je apparaat."</string>
</resources>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index fe57b757fe04..09250c31717d 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"ସବୁବେଳେ ଏହି କମ୍ପ୍ୟୁଟର୍‌ରୁ ଅନୁମତି ଦିଅନ୍ତୁ"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"ଅନୁମତି ଦିଅନ୍ତୁ"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"USBରେ ଡିବଗ୍‍ କରାଯାଇପାରିବ ନାହିଁ"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"ସମ୍ପ୍ରତି ସାଇନ୍‍-ଇନ୍‍ କରିଥିବା ୟୁଜର୍‍ ଜଣକ ଏହି ଡିଭାଇସରେ USB ଡିବଗିଙ୍ଗ ଅନ୍‍ କରିପାରିବେ ନାହିଁ। ଏହି ବୈଶିଷ୍ଟ୍ୟ ବ୍ୟବହାର କରିବାକୁ, ପ୍ରାଥମିକ ୟୁଜର୍‍ରେ ସାଇନ୍‍-ଇନ୍‍ କରନ୍ତୁ।"</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"ୟୁଜର ବର୍ତ୍ତମାନ ସାଇନ ଇନ କରିଥିବା ଏହି ଡିଭାଇସରେ USB ଡିବଗିଂ ଚାଲୁ କରିପାରିବେ ନାହିଁ। ଏହି ଫିଚର ବ୍ୟବହାର କରିବା ପାଇଁ ଜଣେ ଆଡମିନ ୟୁଜର ଭାବେ ସ୍ୱିଚ କରନ୍ତୁ।"</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"ଆପଣ ସିଷ୍ଟମ ଭାଷା <xliff:g id="LANGUAGE">%1$s</xliff:g>କୁ ପରିବର୍ତ୍ତନ କରିବା ପାଇଁ ଚାହାଁନ୍ତି?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"ଅନ୍ୟ ଏକ ଡିଭାଇସ ଦ୍ୱାରା ସିଷ୍ଟମ ଭାଷା ପରିବର୍ତ୍ତନ ପାଇଁ ଅନୁରୋଧ କରାଯାଇଛି"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"ଭାଷା ପରିବର୍ତ୍ତନ କରନ୍ତୁ"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"ସର୍ବଦା ଏହି ନେଟୱାର୍କରେ ଅନୁମତି ଦିଅନ୍ତୁ"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"ଅନୁମତି ଦିଅନ୍ତୁ"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"ୱାୟାରଲେସ୍ ଡିବଗିଂ ପାଇଁ ଅନୁମତି ନାହିଁ"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"ଉପଯୋଗକର୍ତ୍ତା ବର୍ତ୍ତମାନ ସାଇନ୍-ଇନ୍ କରିଥିବା ଏହି ଡିଭାଇସରେ ୱାୟାରଲେସ୍ ଡିବଗିଂ ଚାଲୁ କରିପାରିବେ ନାହିଁ। ଏହି ଫିଚର୍ ବ୍ୟବହାର କରିବା ପାଇଁ ପ୍ରାଥମିକ ଉପଯୋଗକର୍ତ୍ତାରେ ସ୍ୱିଚ୍ କରନ୍ତୁ।"</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"ୟୁଜର ବର୍ତ୍ତମାନ ସାଇନ-ଇନ କରିଥିବା ଏହି ଡିଭାଇସରେ ୱାୟାରଲେସ ଡିବଗିଂ ଚାଲୁ କରିପାରିବେ ନାହିଁ। ଏହି ଫିଚର ବ୍ୟବହାର କରିବା ପାଇଁ ଜଣେ ଆଡମିନ ୟୁଜର ଭାବେ ସ୍ୱିଚ କରନ୍ତୁ।"</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"USB ପୋର୍ଟକୁ ଅକ୍ଷମ କରାଯାଇଛି"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"ଆପଣଙ୍କ ଡିଭାଇସ୍‌କୁ ତରଳ ପଦାର୍ଥ ଏବଂ ଧୂଳିରୁ ସୁରକ୍ଷିତ ରଖିବା ପାଇଁ, USB ପୋର୍ଟକୁ ଅକ୍ଷମ କରାଯାଇଛି ଏବଂ ଏହା କୌଣସି ଉପକରଣ ଚିହ୍ନଟ କରିବ ନାହିଁ। \n\n ଯେତେବେଳେ USB ପୋର୍ଟ ପୁଣିି ବ୍ୟବହାର କରିବାକୁ ସୁରକ୍ଷିତ ହେବ, ସେତେବେଳେ ଆପଣଙ୍କୁ ସୂଚିତ କରାଯିବ।"</string>
<string name="usb_port_enabled" msgid="531823867664717018">"ଚାର୍ଜର୍‍ ଏବଂ ଆକ୍ସେସରିଗୁଡ଼ିକୁ ଚିହ୍ନଟ କରିବାକୁ USB ପୋର୍ଟ ସକ୍ଷମ କରାଯାଇଛି"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"ଭଏସ୍‌ ସହାୟକ"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"ୱାଲେଟ୍"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"QR କୋଡ ସ୍କାନର"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"ଅନଲକ୍‌ କରନ୍ତୁ"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"ଡିଭାଇସ୍ ଲକ୍ ହୋଇଯାଇଛି"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"ଫେସ୍ ସ୍କାନିଙ୍ଗ କରାଯାଉଛି"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"ପଠାନ୍ତୁ"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"ଫେସ ଚିହ୍ନଟ ହୋଇପାରିବ ନାହିଁ"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"ଟିପଚିହ୍ନ ବ୍ୟବହାର କରନ୍ତୁ"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"ବ୍ଲୁଟୂଥ୍‍‌ ସଂଯୋଗ କରାଯାଇଛି।"</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"ବ୍ୟାଟେରୀ ଶତକଡ଼ା ଅଜଣା ଅଟେ।"</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"ଏରୋପ୍ଲେନ୍‍ ମୋଡ୍‌।"</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN ଅନ୍‍।"</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"ବ୍ୟାଟେରୀ <xliff:g id="NUMBER">%d</xliff:g> ଶତକଡ଼ା।"</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"ବ୍ୟାଟେରୀ <xliff:g id="PERCENTAGE">%1$s</xliff:g> ଶତକଡା, ଆପଣଙ୍କର ବ୍ୟବହାରକୁ ଆଧାର କରି ପାଖାପାଖି <xliff:g id="TIME">%2$s</xliff:g> ବାକି ଅଛି"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"ବ୍ୟାଟେରୀ <xliff:g id="PERCENTAGE">%1$d</xliff:g> ଶତକଡା, ଆପଣଙ୍କର ବ୍ୟବହାରକୁ ଆଧାର କରି ପାଖାପାଖି <xliff:g id="TIME">%2$s</xliff:g> ବାକି ଅଛି"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"ବ୍ୟାଟେରୀ ଚାର୍ଜ ହେଉଛି, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> ଶତକଡ଼ା।"</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"ସମସ୍ତ ବିଜ୍ଞପ୍ତି ଦେଖନ୍ତୁ"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"ଟେଲି-ଟାଇପରାଇଟର୍ ସକ୍ଷମ ଅଛି।"</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"ରିଙ୍ଗର୍‌ କମ୍ପନରେ ଅଛି।"</string>
@@ -305,28 +310,17 @@
<string name="sensor_privacy_mic_unblocked_toast_content" msgid="306555320557065068">"ମାଇକ୍ରୋଫୋନ ଉପଲବ୍ଧ"</string>
<string name="sensor_privacy_camera_unblocked_toast_content" msgid="7843105715964332311">"କ୍ୟାମେରା ଉପଲବ୍ଧ"</string>
<string name="sensor_privacy_mic_camera_unblocked_toast_content" msgid="7339355093282661115">"ମାଇକ୍ରୋଫୋନ ଏବଂ କ୍ୟାମେରା ଉପଲବ୍ଧ"</string>
- <!-- no translation found for sensor_privacy_mic_turned_on_dialog_title (6348853159838376513) -->
- <skip />
- <!-- no translation found for sensor_privacy_mic_turned_off_dialog_title (5760464281790732849) -->
- <skip />
- <!-- no translation found for sensor_privacy_mic_unblocked_dialog_content (4889961886199270224) -->
- <skip />
- <!-- no translation found for sensor_privacy_mic_blocked_no_exception_dialog_content (5864898470772965394) -->
- <skip />
- <!-- no translation found for sensor_privacy_mic_blocked_with_exception_dialog_content (810289713700437896) -->
- <skip />
- <!-- no translation found for sensor_privacy_camera_turned_on_dialog_title (8039095295100075952) -->
- <skip />
- <!-- no translation found for sensor_privacy_camera_turned_off_dialog_title (1936603903120742696) -->
- <skip />
- <!-- no translation found for sensor_privacy_camera_unblocked_dialog_content (7847190103011782278) -->
- <skip />
- <!-- no translation found for sensor_privacy_camera_blocked_dialog_content (3182428709314874616) -->
- <skip />
- <!-- no translation found for sensor_privacy_htt_blocked_dialog_content (3333321592997666441) -->
- <skip />
- <!-- no translation found for sensor_privacy_dialog_open_settings (1503088305279285048) -->
- <skip />
+ <string name="sensor_privacy_mic_turned_on_dialog_title" msgid="6348853159838376513">"ମାଇକ୍ରୋଫୋନ ଚାଲୁ କରାଯାଇଛି"</string>
+ <string name="sensor_privacy_mic_turned_off_dialog_title" msgid="5760464281790732849">"ମାଇକ୍ରୋଫୋନ ବନ୍ଦ କରାଯାଇଛି"</string>
+ <string name="sensor_privacy_mic_unblocked_dialog_content" msgid="4889961886199270224">"ସମସ୍ତ ଆପ୍ସ ଏବଂ ସେବା ପାଇଁ ମାଇକ୍ରୋଫୋନକୁ ସକ୍ଷମ କରାଯାଇଛି।"</string>
+ <string name="sensor_privacy_mic_blocked_no_exception_dialog_content" msgid="5864898470772965394">"ସମସ୍ତ ଆପ୍ସ ଏବଂ ସେବା ପାଇଁ ମାଇକ୍ରୋଫୋନ ଆକ୍ସେସକୁ ଅକ୍ଷମ କରାଯାଇଛି। ସେଟିଂସ &gt; ଗୋପନୀୟତା &gt; ମାଇକ୍ରୋଫୋନରେ ଆପଣ ମାଇକ୍ରୋଫୋନ ଆକ୍ସେସକୁ ସକ୍ଷମ କରିପାରିବେ।"</string>
+ <string name="sensor_privacy_mic_blocked_with_exception_dialog_content" msgid="810289713700437896">"ସମସ୍ତ ଆପ୍ସ ଏବଂ ସେବା ପାଇଁ ମାଇକ୍ରୋଫୋନ ଆକ୍ସେସକୁ ଅକ୍ଷମ କରାଯାଇଛି। ସେଟିଂସ &gt; ଗୋପନୀୟତା &gt; ମାଇକ୍ରୋଫୋନରେ ଆପଣ ଏହାକୁ ପରିବର୍ତ୍ତନ କରିପାରିବେ।"</string>
+ <string name="sensor_privacy_camera_turned_on_dialog_title" msgid="8039095295100075952">"କେମେରା ଚାଲୁ କରାଯାଇଛି"</string>
+ <string name="sensor_privacy_camera_turned_off_dialog_title" msgid="1936603903120742696">"କେମେରା ବନ୍ଦ କରାଯାଇଛି"</string>
+ <string name="sensor_privacy_camera_unblocked_dialog_content" msgid="7847190103011782278">"ସମସ୍ତ ଆପ୍ସ ଏବଂ ସେବା ପାଇଁ କେମେରାକୁ ସକ୍ଷମ କରାଯାଇଛି।"</string>
+ <string name="sensor_privacy_camera_blocked_dialog_content" msgid="3182428709314874616">"ସମସ୍ତ ଆପ୍ସ ଏବଂ ସେବା ପାଇଁ କେମେରା ଆକ୍ସେସକୁ ଅକ୍ଷମ କରାଯାଇଛି।"</string>
+ <string name="sensor_privacy_htt_blocked_dialog_content" msgid="3333321592997666441">"ମାଇକ୍ରୋଫୋନ ବଟନ ବ୍ୟବହାର କରିବା ପାଇଁ ସେଟିଂସରେ ମାଇକ୍ରୋଫୋନ ଆକ୍ସେସକୁ ସକ୍ଷମ କରନ୍ତୁ।"</string>
+ <string name="sensor_privacy_dialog_open_settings" msgid="1503088305279285048">"ସେଟିଂସ ଖୋଲନ୍ତୁ।"</string>
<string name="media_seamless_other_device" msgid="4654849800789196737">"ଅନ୍ୟ ଡିଭାଇସ୍"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"ସଂକ୍ଷିପ୍ତ ବିବରଣୀକୁ ଟୋଗଲ୍ କରନ୍ତୁ"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"ଆଲାର୍ମ, ରିମାଇଣ୍ଡର୍‌, ଇଭେଣ୍ଟ ଏବଂ ଆପଣ ନିର୍ଦ୍ଦିଷ୍ଟ କରିଥିବା କଲର୍‌ଙ୍କ ବ୍ୟତୀତ ଆପଣଙ୍କ ଧ୍ୟାନ ଅନ୍ୟ କୌଣସି ଧ୍ୱନୀ ଏବଂ ଭାଇବ୍ରେଶନ୍‌ରେ ଆକର୍ଷଣ କରାଯିବନାହିଁ। ମ୍ୟୁଜିକ୍‍, ଭିଡିଓ ଏବଂ ଗେମ୍‌ ସମେତ ନିଜେ ଚଲାଇବାକୁ ବାଛିଥିବା ଅନ୍ୟ ସବୁକିଛି ଆପଣ ଶୁଣିପାରିବେ।"</string>
@@ -397,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"ଆପଣ ସେୟାର, ରେକର୍ଡ କିମ୍ବା କାଷ୍ଟ କରିବା ସମୟରେ, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ଆପରେ ଦେଖାଯାଉଥିବା କିମ୍ବା ପ୍ଲେ ହେଉଥିବା ସବୁକିଛିକୁ ସେହି ଆପର ଆକ୍ସେସ ଅଛି। ତେଣୁ ପାସୱାର୍ଡ, ପେମେଣ୍ଟ ବିବରଣୀ, ମେସେଜ କିମ୍ବା ଅନ୍ୟ ସମ୍ବେଦନଶୀଳ ସୂଚନା ପ୍ରତି ସତର୍କ ରୁହନ୍ତୁ।"</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"ଜାରି ରଖନ୍ତୁ"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"ଏକ ଆପକୁ ସେୟାର କିମ୍ବା ରେକର୍ଡ କରନ୍ତୁ"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"ସେୟାର କିମ୍ବା ରେକର୍ଡ କରିବା ପାଇଁ ଏହି ଆପକୁ ଅନୁମତି ଦେବେ?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"ଆପଣ ସେୟାର, ରେକର୍ଡ ବା କାଷ୍ଟ କରିବା ସମୟରେ, ଆପଣଙ୍କ ସ୍କ୍ରିନରେ ଦେଖାଯାଉଥିବା କିମ୍ବା ଆପଣଙ୍କ ଡିଭାଇସରେ ପ୍ଲେ ହେଉଥିବା ସବୁକିଛିକୁ ଏହି ଆପର ଆକ୍ସେସ ଅଛି। ତେଣୁ ପାସୱାର୍ଡ, ପେମେଣ୍ଟ ବିବରଣୀ, ମେସେଜ କିମ୍ବା ଅନ୍ୟ ସମ୍ବେଦନଶୀଳ ସୂଚନା ପ୍ରତି ସତର୍କ ରୁହନ୍ତୁ।"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"ଆପଣ ସେୟାର, ରେକର୍ଡ ବା କାଷ୍ଟ କରିବା ସମୟରେ, ସେହି ଆପରେ ଦେଖାଯାଉଥିବା କିମ୍ବା ପ୍ଲେ ହେଉଥିବା ସବୁକିଛିକୁ ଏହି ଆପର ଆକ୍ସେସ ଅଛି। ତେଣୁ ପାସୱାର୍ଡ, ପେମେଣ୍ଟ ବିବରଣୀ, ମେସେଜ କିମ୍ବା ଅନ୍ୟ ସମ୍ବେଦନଶୀଳ ସୂଚନା ପ୍ରତି ସତର୍କ ରୁହନ୍ତୁ।"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"ଆପଣଙ୍କ IT ଆଡମିନଙ୍କ ଦ୍ୱାରା ବ୍ଲକ କରାଯାଇଛି"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"ଡିଭାଇସ ନୀତି ଦ୍ୱାରା ସ୍କ୍ରିନ କେପଚରିଂକୁ ଅକ୍ଷମ କରାଯାଇଛି"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"ସମସ୍ତ ଖାଲି କରନ୍ତୁ"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"ପରିଚାଳନା କରନ୍ତୁ"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"ଇତିହାସ"</string>
@@ -522,7 +511,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"ବ୍ୟବହାର କରିବାକୁ ଅନଲକ୍ କରନ୍ତୁ"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"ଆପଣଙ୍କ କାର୍ଡଗୁଡ଼ିକ ପାଇବାରେ ଏକ ସମସ୍ୟା ହୋଇଥିଲା। ଦୟାକରି ପରେ ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"ସ୍କ୍ରିନ୍ ଲକ୍ ସେଟିଂସ୍"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"QR କୋଡ ସ୍କାନ କରନ୍ତୁ"</string>
+ <string name="qr_code_scanner_title" msgid="1938155688725760702">"QR କୋଡ ସ୍କାନର"</string>
<string name="status_bar_work" msgid="5238641949837091056">"ୱର୍କ ପ୍ରୋଫାଇଲ୍‌"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"ଏରୋପ୍ଲେନ୍‍ ମୋଡ୍"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"<xliff:g id="WHEN">%1$s</xliff:g>ବେଳେ ଆପଣ ନିଜର ପରବର୍ତ୍ତୀ ଆଲାର୍ମ ଶୁଣିପାରିବେ ନାହିଁ"</string>
@@ -805,6 +794,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"ସମ୍ପୂର୍ଣ୍ଣ ସ୍କ୍ରିନକୁ ମ୍ୟାଗ୍ନିଫାଏ କରନ୍ତୁ"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"ସ୍କ୍ରିନର ଅଂଶ ମାଗ୍ନିଫାଏ କରନ୍ତୁ"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"ସ୍ୱିଚ୍ କରନ୍ତୁ"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"ଡାଏଗୋନାଲ ସ୍କ୍ରୋଲିଂକୁ ଅନୁମତି ଦିଅନ୍ତୁ"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"ରିସାଇଜ କରନ୍ତୁ"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"ମ୍ୟାଗ୍ନିଫିକେସନ ପ୍ରକାରକୁ ପରିବର୍ତ୍ତନ କରନ୍ତୁ"</string>
@@ -1035,4 +1026,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"ସମସ୍ତ ଡିଭାଇସ ଲଗକୁ ଆକ୍ସେସ କରିବା ପାଇଁ <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g>କୁ ଅନୁମତି ଦେବେ?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"ଗୋଟିଏ-ଥର ଆକ୍ସେସ ପାଇଁ ଅନୁମତି ଦିଅନ୍ତୁ"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"ଅନୁମତି ଦିଅନ୍ତୁ ନାହିଁ"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"ଆପଣଙ୍କ ଡିଭାଇସରେ ଯାହା ହୁଏ ତାହା ଡିଭାଇସ ଲଗଗୁଡ଼ିକ ରେକର୍ଡ କରେ। ସମସ୍ୟାଗୁଡ଼ିକୁ ଖୋଜି ସମାଧାନ କରିବାକୁ ଆପ୍ସ ଏହି ଲଗଗୁଡ଼ିକୁ ବ୍ୟବହାର କରିପାରିବ।\n\nକିଛି ଲଗରେ ସମ୍ବେଦନଶୀଳ ସୂଚନା ଥାଇପାରେ, ତେଣୁ ସମସ୍ତ ଡିଭାଇସ ଲଗକୁ ଆକ୍ସେସ କରିବା ପାଇଁ ଆପଣ ବିଶ୍ୱାସ କରୁଥିବା ଆପ୍ସକୁ ହିଁ କେବଳ ଅନୁମତି ଦିଅନ୍ତୁ। \n\nଯଦି ଆପଣ ସମସ୍ତ ଡିଭାଇସ ଲଗକୁ ଆକ୍ସେସ କରିବା ପାଇଁ ଏହି ଆପକୁ ଅନୁମତି ଦିଅନ୍ତି ନାହିଁ, ତେବେ ଏହା ନିଜର ଡିଭାଇସ ଲଗଗୁଡ଼ିକୁ ଏବେ ବି ଆକ୍ସେସ କରିପାରିବ। ଆପଣଙ୍କ ଡିଭାଇସର ନିର୍ମାତା ଏବେ ବି ଆପଣଙ୍କର ଡିଭାଇସରେ କିଛି ଲଗ କିମ୍ବା ସୂଚନାକୁ ଆକ୍ସେସ କରିବା ପାଇଁ ସକ୍ଷମ ହୋଇପାରନ୍ତି।"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index c119e8cad0e1..72e1435901d8 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"ਹਮੇਸ਼ਾਂ ਇਸ ਕੰਪਿਊਟਰ ਤੋਂ ਆਗਿਆ ਦਿਓ"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"ਕਰਨ ਦਿਓ"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"USB ਡਿਬੱਗਿੰਗ ਦੀ ਆਗਿਆ ਨਹੀਂ"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"The user currently signed in to this device can\'t turn on USB debugging. To use this feature, switch to the primary user."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"ਫ਼ਿਲਹਾਲ ਇਸ ਡੀਵਾਈਸ \'ਤੇ ਸਾਈਨ-ਇਨ ਕੀਤਾ ਵਰਤੋਂਕਾਰ USB ਡੀਬੱਗਿੰਗ ਨੂੰ ਚਾਲੂ ਨਹੀਂ ਕਰ ਸਕਦਾ ਹੈ। ਇਸ ਵਿਸ਼ੇਸ਼ਤਾ ਦੀ ਵਰਤੋਂ ਕਰਨ ਲਈ, ਪ੍ਰਸ਼ਾਸਕ ਵਰਤੋਂਕਾਰ \'ਤੇ ਸਵਿੱਚ ਕਰੋ।"</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"ਕੀ ਤੁਸੀਂ ਸਿਸਟਮ ਦੀ ਭਾਸ਼ਾ ਬਦਲ ਕੇ <xliff:g id="LANGUAGE">%1$s</xliff:g> ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"ਕਿਸੇ ਹੋਰ ਡੀਵਾਈਸ ਵੱਲੋਂ ਸਿਸਟਮ ਦੀ ਭਾਸ਼ਾ ਬਦਲਣ ਦੀ ਬੇਨਤੀ ਕੀਤੀ ਗਈ"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"ਭਾਸ਼ਾ ਬਦਲੋ"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"ਇਸ ਨੈੱਟਵਰਕ \'ਤੇ ਹਮੇਸ਼ਾਂ ਆਗਿਆ ਦਿਓ"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"ਆਗਿਆ ਦਿਓ"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"ਵਾਇਰਲੈੱਸ ਡੀਬੱਗਿੰਗ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"ਵਰਤਮਾਨ ਵਿੱਚ ਇਸ ਡੀਵਾਈਸ \'ਤੇ ਸਾਈਨ-ਇਨ ਕੀਤਾ ਵਰਤੋਂਕਾਰ ਵਾਇਰਲੈੱਸ ਡੀਬੱਗਿੰਗ ਨੂੰ ਚਾਲੂ ਨਹੀਂ ਕਰ ਸਕਦਾ। ਇਸ ਵਿਸ਼ੇਸ਼ਤਾ ਨੂੰ ਵਰਤਣ ਲਈ, ਮੁੱਖ ਵਰਤੋਂਕਾਰ \'ਤੇ ਬਦਲੋ।"</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"ਫ਼ਿਲਹਾਲ ਇਸ ਡੀਵਾਈਸ \'ਤੇ ਸਾਈਨ-ਇਨ ਕੀਤਾ ਵਰਤੋਂਕਾਰ ਵਾਇਰਲੈੱਸ ਡੀਬੱਗਿੰਗ ਨੂੰ ਚਾਲੂ ਨਹੀਂ ਕਰ ਸਕਦਾ। ਇਸ ਵਿਸ਼ੇਸ਼ਤਾ ਨੂੰ ਵਰਤਣ ਲਈ, ਪ੍ਰਸ਼ਾਸਕ ਵਰਤੋਂਕਾਰ \'ਤੇ ਸਵਿੱਚ ਕਰੋ।"</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"USB ਪੋਰਟ ਬੰਦ ਕੀਤਾ ਗਿਆ"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਨੂੰ ਪਾਣੀ ਅਤੇ ਧੂੜ-ਮਿੱਟੀ ਤੋਂ ਬਚਾਉਣ ਲਈ, USB ਪੋਰਟ ਨੂੰ ਬੰਦ ਕੀਤਾ ਗਿਆ ਹੈ ਅਤੇ ਕੋਈ ਵੀ ਐਕਸੈਸਰੀ ਪਛਾਣੀ ਨਹੀਂ ਜਾਵੇਗੀ।\n\nUSB ਪੋਰਟ ਨੂੰ ਦੁਬਾਰਾ ਵਰਤਣਾ ਠੀਕ ਹੋਣ \'ਤੇ ਤੁਹਾਨੂੰ ਸੂਚਿਤ ਕੀਤਾ ਜਾਵੇਗਾ।"</string>
<string name="usb_port_enabled" msgid="531823867664717018">"ਚਾਰਜਰਾਂ ਅਤੇ ਉਪਸਾਧਨਾਂ ਦੀ ਪਛਾਣ ਕਰਨ ਲਈ USB ਪੋਰਟ ਚਾਲੂ ਹੈ"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"ਅਵਾਜ਼ੀ ਸਹਾਇਕ"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"QR ਕੋਡ ਸਕੈਨਰ"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"ਅਣਲਾਕ ਕਰੋ"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"ਡੀਵਾਈਸ ਲਾਕ ਹੈ"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"ਚਿਹਰਾ ਸਕੈਨ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"ਭੇਜੋ"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"ਚਿਹਰੇ ਦੀ ਪਛਾਣ ਨਹੀਂ ਹੋਈ"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"ਇਸਦੀ ਬਜਾਏ ਫਿੰਗਰਪ੍ਰਿੰਟ ਵਰਤੋ"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth ਕਨੈਕਟ ਕੀਤੀ।"</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"ਬੈਟਰੀ ਪ੍ਰਤੀਸ਼ਤ ਅਗਿਆਤ ਹੈ।"</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"ਏਅਰਪਲੇਨ ਮੋਡ।"</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN ਚਾਲੂ ਹੈ।"</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"ਬੈਟਰੀ <xliff:g id="NUMBER">%d</xliff:g> ਪ੍ਰਤੀਸ਼ਤ ਹੈ।"</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"ਬੈਟਰੀ <xliff:g id="PERCENTAGE">%1$s</xliff:g> ਫ਼ੀਸਦ, ਤੁਹਾਡੀ ਵਰਤੋਂ ਦੇ ਆਧਾਰ \'ਤੇ ਲਗਭਗ <xliff:g id="TIME">%2$s</xliff:g> ਬਾਕੀ"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"ਬੈਟਰੀ <xliff:g id="PERCENTAGE">%1$d</xliff:g> ਫ਼ੀਸਦ, ਤੁਹਾਡੀ ਵਰਤੋਂ ਦੇ ਆਧਾਰ \'ਤੇ ਲਗਭਗ <xliff:g id="TIME">%2$s</xliff:g> ਬਾਕੀ"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"ਬੈਟਰੀ ਚਾਰਜ ਹੋ ਰਹੀ ਹੈ, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> ਪ੍ਰਤੀਸ਼ਤ ਹੋ ਗਈ।"</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"ਸਾਰੀਆਂ ਸੂਚਨਾਵਾਂ ਦੇਖੋ"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"ਟੈਲੀ ਟਾਈਪਰਾਈਟਰ ਸਮਰਥਿਤ।"</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"ਰਿੰਗਰ ਥਰਥਰਾਹਟ।"</string>
@@ -386,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"ਤੁਹਾਡੇ ਵੱਲੋਂ ਸਾਂਝਾ ਕਰਨ, ਰਿਕਾਰਡ ਕਰਨ, ਜਾਂ ਕਾਸਟ ਕਰਨ \'ਤੇ, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ਕੋਲ ਉਸ ਐਪ \'ਤੇ ਦਿਖਾਈ ਗਈ ਜਾਂ ਚਲਾਈ ਗਈ ਹਰੇਕ ਚੀਜ਼ ਤੱਕ ਪਹੁੰਚ ਹੁੰਦੀ ਹੈ। ਇਸ ਲਈ ਪਾਸਵਰਡਾਂ, ਭੁਗਤਾਨ ਵੇਰਵਿਆਂ, ਸੁਨੇਹਿਆਂ ਜਾਂ ਹੋਰ ਸੰਵੇਦਨਸ਼ੀਲ ਜਾਣਕਾਰੀ ਸੰਬੰਧੀ ਸਾਵਧਾਨ ਰਹੋ।"</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"ਜਾਰੀ ਰੱਖੋ"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"ਐਪ ਨੂੰ ਸਾਂਝਾ ਕਰੋ ਜਾਂ ਰਿਕਾਰਡ ਕਰੋ"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"ਕੀ ਇਸ ਐਪ ਨੂੰ ਸਾਂਝਾ ਕਰਨ ਜਾਂ ਰਿਕਾਰਡ ਕਰਨ ਦੀ ਆਗਿਆ ਦੇਣੀ ਹੈ?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"ਤੁਹਾਡੇ ਵੱਲੋਂ ਸਾਂਝਾ ਕਰਨ, ਰਿਕਾਰਡ ਕਰਨ, ਜਾਂ ਕਾਸਟ ਕਰਨ \'ਤੇ, ਇਸ ਐਪ ਕੋਲ ਤੁਹਾਡੀ ਸਕ੍ਰੀਨ \'ਤੇ ਦਿਸਦੀ ਜਾਂ ਤੁਹਾਡੇ ਡੀਵਾਈਸ \'ਤੇ ਚਲਾਈ ਗਈ ਹਰੇਕ ਚੀਜ਼ ਤੱਕ ਪਹੁੰਚ ਹੁੰਦੀ ਹੈ। ਇਸ ਲਈ ਪਾਸਵਰਡਾਂ, ਭੁਗਤਾਨ ਵੇਰਵਿਆਂ, ਸੁਨੇਹਿਆਂ ਜਾਂ ਹੋਰ ਸੰਵੇਦਨਸ਼ੀਲ ਜਾਣਕਾਰੀ ਸੰਬੰਧੀ ਸਾਵਧਾਨ ਰਹੋ।"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"ਤੁਹਾਡੇ ਵੱਲੋਂ ਸਾਂਝਾ ਕਰਨ, ਰਿਕਾਰਡ ਕਰਨ, ਜਾਂ ਕਾਸਟ ਕਰਨ \'ਤੇ, ਇਸ ਐਪ ਕੋਲ ਉਸ ਐਪ \'ਤੇ ਦਿਖਾਈ ਗਈ ਜਾਂ ਚਲਾਈ ਗਈ ਹਰੇਕ ਚੀਜ਼ ਤੱਕ ਪਹੁੰਚ ਹੁੰਦੀ ਹੈ। ਇਸ ਲਈ ਪਾਸਵਰਡਾਂ, ਭੁਗਤਾਨ ਵੇਰਵਿਆਂ, ਸੁਨੇਹਿਆਂ ਜਾਂ ਹੋਰ ਸੰਵੇਦਨਸ਼ੀਲ ਜਾਣਕਾਰੀ ਸੰਬੰਧੀ ਸਾਵਧਾਨ ਰਹੋ।"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"ਤੁਹਾਡੇ ਆਈ.ਟੀ. ਪ੍ਰਸ਼ਾਸਕ ਵੱਲੋਂ ਬਲਾਕ ਕੀਤਾ ਗਿਆ"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"ਡੀਵਾਈਸ ਨੀਤੀ ਦੇ ਕਾਰਨ ਸਕ੍ਰੀਨ ਕੈਪਚਰ ਕਰਨਾ ਬੰਦ ਹੈ"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"ਸਭ ਕਲੀਅਰ ਕਰੋ"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"ਪ੍ਰਬੰਧਨ ਕਰੋ"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"ਇਤਿਹਾਸ"</string>
@@ -511,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"ਵਰਤਣ ਲਈ ਅਣਲਾਕ ਕਰੋ"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"ਤੁਹਾਡੇ ਕਾਰਡ ਪ੍ਰਾਪਤ ਕਰਨ ਵਿੱਚ ਕੋਈ ਸਮੱਸਿਆ ਆਈ, ਕਿਰਪਾ ਕਰਕੇ ਬਾਅਦ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"ਲਾਕ ਸਕ੍ਰੀਨ ਸੈਟਿੰਗਾਂ"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"QR ਕੋਡ ਸਕੈਨ ਕਰੋ"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"ਹਵਾਈ-ਜਹਾਜ਼ ਮੋਡ"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"ਤੁਸੀਂ <xliff:g id="WHEN">%1$s</xliff:g> ਵਜੇ ਆਪਣਾ ਅਗਲਾ ਅਲਾਰਮ ਨਹੀਂ ਸੁਣੋਗੇ"</string>
@@ -794,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"ਪੂਰੀ ਸਕ੍ਰੀਨ ਨੂੰ ਵੱਡਦਰਸ਼ੀ ਕਰੋ"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"ਸਕ੍ਰੀਨ ਦੇ ਹਿੱਸੇ ਨੂੰ ਵੱਡਾ ਕਰੋ"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"ਸਵਿੱਚ"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"ਟੇਡੀ ਦਿਸ਼ਾ ਵਿੱਚ ਸਕ੍ਰੋਲ ਕਰਨ ਦਿਓ"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"ਆਕਾਰ ਬਦਲੋ"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"ਵੱਡਦਰਸ਼ੀਕਰਨ ਦੀ ਕਿਸਮ ਬਦਲੋ"</string>
@@ -1024,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"ਕੀ <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> ਨੂੰ ਸਾਰੇ ਡੀਵਾਈਸ ਲੌਗਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਦੇਣੀ ਹੈ?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"ਇੱਕ-ਵਾਰ ਲਈ ਪਹੁੰਚ ਦੀ ਆਗਿਆ ਦਿਓ"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"ਆਗਿਆ ਨਾ ਦਿਓ"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"ਡੀਵਾਈਸ ਲੌਗਾਂ ਵਿੱਚ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਦੀਆਂ ਕਾਰਵਾਈਆਂ ਰਿਕਾਰਡ ਹੁੰਦੀਆਂ ਹਨ। ਐਪਾਂ ਸਮੱਸਿਆਵਾਂ ਨੂੰ ਲੱਭਣ ਅਤੇ ਉਨ੍ਹਾਂ ਦਾ ਹੱਲ ਕਰਨ ਲਈ ਇਨ੍ਹਾਂ ਲੌਗਾਂ ਦੀ ਵਰਤੋਂ ਕਰ ਸਕਦੀਆਂ ਹਨ।\n\nਕੁਝ ਲੌਗਾਂ ਵਿੱਚ ਸੰਵੇਦਨਸ਼ੀਲ ਜਾਣਕਾਰੀ ਸ਼ਾਮਲ ਹੋ ਸਕਦੀ ਹੈ, ਇਸ ਲਈ ਸਿਰਫ਼ ਆਪਣੀਆਂ ਭਰੋਸੇਯੋਗ ਐਪਾਂ ਨੂੰ ਹੀ ਸਾਰੇ ਡੀਵਾਈਸ ਲੌਗਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿਓ। \n\nਜੇ ਤੁਸੀਂ ਇਸ ਐਪ ਨੂੰ ਸਾਰੇ ਡੀਵਾਈਸ ਲੌਗਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਨਹੀਂ ਦਿੰਦੇ ਹੋ, ਤਾਂ ਇਹ ਹਾਲੇ ਵੀ ਆਪਣੇ ਲੌਗਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰ ਸਕਦੀ ਹੈ। ਤੁਹਾਡਾ ਡੀਵਾਈਸ ਨਿਰਮਾਤਾ ਹਾਲੇ ਵੀ ਤੁਹਾਡੇ ਡੀਵਾਈਸ \'ਤੇ ਮੌਜੂਦ ਕੁਝ ਲੌਗਾਂ ਜਾਂ ਜਾਣਕਾਰੀ ਤੱਕ ਪਹੁੰਚ ਕਰ ਸਕਦਾ ਹੈ।"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index cb496fe35706..0543d40953a5 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"Zawsze zezwalaj z tego komputera"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"Zezwalaj"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"Debugowanie USB jest niedozwolone"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"Użytkownik obecnie zalogowany na tym urządzeniu nie może włączyć debugowania USB. Aby użyć tej funkcji, przełącz się na użytkownika głównego."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"Użytkownik obecnie zalogowany na tym urządzeniu nie może włączyć debugowania USB. Aby użyć tej funkcji, przełącz się na administratora."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Czy chcesz zmienić język systemu na <xliff:g id="LANGUAGE">%1$s</xliff:g>?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Inny użytkownik poprosił o zmianę języka systemu"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Zmień język"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"Zawsze zezwalaj w tej sieci"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"Zezwól"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Debugowanie bezprzewodowe jest niedozwolone"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"Użytkownik obecnie zalogowany na tym urządzeniu nie może włączyć debugowania bezprzewodowego. Aby użyć tej funkcji, przełącz się na głównego użytkownika."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"Użytkownik obecnie zalogowany na tym urządzeniu nie może włączyć debugowania bezprzewodowego. Aby użyć tej funkcji, przełącz się na administratora."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"Port USB wyłączony"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"Aby chronić urządzenie przed wilgocią i zanieczyszczeniami, port USB został wyłączony i nie wykryje żadnych akcesoriów.\n\nOtrzymasz powiadomienie, gdy będzie można znów używać portu."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"Port USB włączony, by wykrywać ładowarki i akcesoria"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Asystent głosowy"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Portfel"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"Skaner kodów QR"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"Odblokuj"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"Urządzenie zablokowane"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Skanowanie twarzy"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Wyślij"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"Nie można rozpoznać twarzy"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Użyj odcisku palca"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth połączony."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"Poziom naładowania baterii jest nieznany."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"Tryb samolotowy."</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"Sieć VPN włączona."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"Bateria: <xliff:g id="NUMBER">%d</xliff:g> procent."</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Bateria <xliff:g id="PERCENTAGE">%1$s</xliff:g> procent, jeszcze <xliff:g id="TIME">%2$s</xliff:g> (na podstawie Twojego sposobu korzystania)"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Bateria <xliff:g id="PERCENTAGE">%1$d</xliff:g> procent, jeszcze <xliff:g id="TIME">%2$s</xliff:g> (na podstawie Twojego sposobu korzystania)"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Ładuję baterię, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> procent."</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"Zobacz wszystkie powiadomienia"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"Dalekopis (TTY) włączony."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Dzwonek z wibracjami."</string>
@@ -305,28 +310,17 @@
<string name="sensor_privacy_mic_unblocked_toast_content" msgid="306555320557065068">"Mikrofon jest dostępny"</string>
<string name="sensor_privacy_camera_unblocked_toast_content" msgid="7843105715964332311">"Aparat jest dostępny"</string>
<string name="sensor_privacy_mic_camera_unblocked_toast_content" msgid="7339355093282661115">"Mikrofon i aparat są dostępne"</string>
- <!-- no translation found for sensor_privacy_mic_turned_on_dialog_title (6348853159838376513) -->
- <skip />
- <!-- no translation found for sensor_privacy_mic_turned_off_dialog_title (5760464281790732849) -->
- <skip />
- <!-- no translation found for sensor_privacy_mic_unblocked_dialog_content (4889961886199270224) -->
- <skip />
- <!-- no translation found for sensor_privacy_mic_blocked_no_exception_dialog_content (5864898470772965394) -->
- <skip />
- <!-- no translation found for sensor_privacy_mic_blocked_with_exception_dialog_content (810289713700437896) -->
- <skip />
- <!-- no translation found for sensor_privacy_camera_turned_on_dialog_title (8039095295100075952) -->
- <skip />
- <!-- no translation found for sensor_privacy_camera_turned_off_dialog_title (1936603903120742696) -->
- <skip />
- <!-- no translation found for sensor_privacy_camera_unblocked_dialog_content (7847190103011782278) -->
- <skip />
- <!-- no translation found for sensor_privacy_camera_blocked_dialog_content (3182428709314874616) -->
- <skip />
- <!-- no translation found for sensor_privacy_htt_blocked_dialog_content (3333321592997666441) -->
- <skip />
- <!-- no translation found for sensor_privacy_dialog_open_settings (1503088305279285048) -->
- <skip />
+ <string name="sensor_privacy_mic_turned_on_dialog_title" msgid="6348853159838376513">"Mikrofon włączony"</string>
+ <string name="sensor_privacy_mic_turned_off_dialog_title" msgid="5760464281790732849">"Mikrofon wyłączony"</string>
+ <string name="sensor_privacy_mic_unblocked_dialog_content" msgid="4889961886199270224">"Mikrofon jest włączony w przypadku wszystkich aplikacji i usług."</string>
+ <string name="sensor_privacy_mic_blocked_no_exception_dialog_content" msgid="5864898470772965394">"Dostęp do mikrofonu jest zablokowany w przypadku wszystkich aplikacji i usług. Możesz włączyć dostęp do mikrofonu, klikając Ustawienia &gt; Prywatność &gt; Mikrofon."</string>
+ <string name="sensor_privacy_mic_blocked_with_exception_dialog_content" msgid="810289713700437896">"Dostęp do mikrofonu jest zablokowany w przypadku wszystkich aplikacji i usług. Możesz to zmienić, klikając Ustawienia &gt; Prywatność &gt; Mikrofon."</string>
+ <string name="sensor_privacy_camera_turned_on_dialog_title" msgid="8039095295100075952">"Aparat włączony"</string>
+ <string name="sensor_privacy_camera_turned_off_dialog_title" msgid="1936603903120742696">"Aparat wyłączony"</string>
+ <string name="sensor_privacy_camera_unblocked_dialog_content" msgid="7847190103011782278">"Aparat jest włączony w przypadku wszystkich aplikacji i usług."</string>
+ <string name="sensor_privacy_camera_blocked_dialog_content" msgid="3182428709314874616">"Dostęp do aparatu jest zablokowany w przypadku wszystkich aplikacji i usług."</string>
+ <string name="sensor_privacy_htt_blocked_dialog_content" msgid="3333321592997666441">"Aby używać przycisku mikrofonu, włącz dostęp do mikrofonu w Ustawieniach."</string>
+ <string name="sensor_privacy_dialog_open_settings" msgid="1503088305279285048">"Otwórz ustawienia"</string>
<string name="media_seamless_other_device" msgid="4654849800789196737">"Inne urządzenie"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Przełącz Przegląd"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Nie będą Cię niepokoić żadne dźwięki ani wibracje z wyjątkiem alarmów, przypomnień, wydarzeń i połączeń od wybranych osób. Będziesz słyszeć wszystkie odtwarzane treści, takie jak muzyka, filmy czy gry."</string>
@@ -397,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Podczas udostępniania, nagrywania lub przesyłania treści aplikacja <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ma dostęp do wszystkiego, co jest w niej wyświetlane lub odtwarzane. Zachowaj ostrożność w przypadku haseł, danych do płatności, wiadomości i innych informacji poufnych."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Dalej"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Udostępnianie i nagrywanie za pomocą aplikacji"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Zezwolić tej aplikacji na udostępnianie lub nagrywanie?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Podczas udostępniania, nagrywania lub przesyłania treści ta aplikacja ma dostęp do wszystkiego, co jest widoczne na ekranie lub odtwarzane na urządzeniu. Zachowaj ostrożność w przypadku haseł, danych do płatności, wiadomości i innych informacji poufnych."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Podczas udostępniania, nagrywania lub przesyłania treści ta aplikacja ma dostęp do wszystkiego, co jest w niej wyświetlane lub odtwarzane. Zachowaj ostrożność w przypadku haseł, danych do płatności, wiadomości i innych informacji poufnych."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Zablokowane przez administratora IT"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"Zrzuty ekranu są wyłączone zgodnie z zasadami dotyczącymi urządzeń"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Usuń wszystkie"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Zarządzaj"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Historia"</string>
@@ -522,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Odblokuj, aby użyć"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Podczas pobierania kart wystąpił problem. Spróbuj ponownie później."</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Ustawienia ekranu blokady"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"Zeskanuj kod QR"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Profil służbowy"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Tryb samolotowy"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Nie usłyszysz swojego następnego alarmu <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -805,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Powiększanie pełnego ekranu"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Powiększ część ekranu"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Przełącz"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Zezwalaj na przewijanie poprzeczne"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Zmień rozmiar"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"Zmień typ powiększenia"</string>
@@ -1035,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"Zezwolić aplikacji <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> na dostęp do wszystkich dzienników urządzenia?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"Zezwól na jednorazowy dostęp"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Nie zezwalaj"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"Dzienniki urządzenia zapisują, co dzieje się na urządzeniu. Aplikacje mogą ich używać do wykrywania i rozwiązywania problemów.\n\nNiektóre dzienniki mogą zawierać poufne dane, dlatego na dostęp do wszystkich dzienników zezwalaj tylko aplikacjom, którym ufasz. \n\nNawet jeśli nie zezwolisz tej aplikacji na dostęp do wszystkich dzienników na urządzeniu, będzie mogła korzystać z własnych. Producent urządzenia nadal będzie mógł używać niektórych dzienników na urządzeniu."</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index cbc8fc7a2ee1..6e116be2fdf6 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"Sempre permitir a partir deste computador"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"Permitir"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"Depuração USB não permitida"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"O usuário conectado a este dispositivo não pode ativar a depuração USB. Para usar esse recurso, mude para o usuário principal \"NAME\"."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"O usuário conectado a este dispositivo não pode ativar a depuração USB. Para usar esse recurso, entre em uma conta de usuário administrador."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Quer mudar o idioma do sistema para <xliff:g id="LANGUAGE">%1$s</xliff:g>?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Mudança do idioma do sistema solicitada por outro dispositivo"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Alterar idioma"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"Sempre permitir nesta rede"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"Permitir"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Depuração por Wi-Fi não permitida"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"O usuário conectado a este dispositivo não pode ativar a depuração por Wi-Fi. Para usar esse recurso, conecte-se como o usuário principal."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"O usuário conectado a este dispositivo não pode ativar a depuração por Wi-Fi. Para usar esse recurso, entre em uma conta de usuário administrador."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"Porta USB desativada"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"Para proteger seu dispositivo de líquidos e detritos, a porta USB está desativada e não detectará nenhum acessório.\n\nVocê receberá uma notificação quando for seguro usar a porta USB novamente."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"Porta USB ativada para detectar carregadores e acessórios"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Assistência de voz"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Carteira"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"Leitor de código QR"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"Desbloquear"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"Dispositivo bloqueado"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Verificando rosto"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Enviar"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"Rosto não reconhecido"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Use a impressão digital"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth conectado."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"Porcentagem da bateria desconhecida."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"Modo avião."</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN ativada."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"Bateria em <xliff:g id="NUMBER">%d</xliff:g> por cento."</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Bateria com <xliff:g id="PERCENTAGE">%1$s</xliff:g> de carga, tempo restante aproximado, com base no seu uso: <xliff:g id="TIME">%2$s</xliff:g>"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Bateria com <xliff:g id="PERCENTAGE">%1$d</xliff:g> de carga, tempo restante aproximado, com base no seu uso: <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Bateria carregando: <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"Ver todas as notificações"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"TeleTYpewriter ativado."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Vibração da campainha."</string>
@@ -386,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Quando você compartilha, grava ou transmite um app, o <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> tem acesso a todas as informações visíveis na tela ou reproduzidas no dispositivo. Tenha cuidado com senhas, detalhes de pagamento, mensagens ou outras informações sensíveis."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Continuar"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Compartilhar ou gravar um app"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Permitir que este app compartilhe ou grave a tela?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Quando você compartilha, grava ou transmite a tela, este app tem acesso a todas as informações visíveis nela ou reproduzidas no dispositivo. Tenha cuidado com senhas, detalhes de pagamento, mensagens e outras informações sensíveis."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Quando você compartilha, grava ou transmite a tela, este app tem acesso a todas as informações visíveis nela ou reproduzidas no dispositivo. Tenha cuidado com senhas, detalhes de pagamento, mensagens e outras informações sensíveis."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Ação bloqueada pelo administrador de TI"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"A captura de tela foi desativada pela política do dispositivo"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Limpar tudo"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Gerenciar"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Histórico"</string>
@@ -511,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Desbloquear para usar"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Ocorreu um problema ao carregar os cards. Tente novamente mais tarde"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Configurações de tela de bloqueio"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"Ler código QR"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Perfil de trabalho"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Modo avião"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Você não ouvirá o próximo alarme às <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -794,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Ampliar toda a tela"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Ampliar parte da tela"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Trocar"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Permitir rolagem diagonal"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Redimensionar"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"Mudar tipo de ampliação"</string>
@@ -1024,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d de MMM"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"Permitir que o app <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> acesse todos os registros do dispositivo?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"Permitir o acesso único"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Não permitir"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"Os registros do dispositivo gravam o que acontece nele. Os apps podem usar esses registros para encontrar e corrigir problemas.\n\nAlguns registros podem conter informações sensíveis, então autorize o acesso a eles apenas para os apps em que você confia. \n\nSe você não permitir que esse app acesse todos os registros do dispositivo, ele ainda vai poder acessar os próprios. O fabricante do dispositivo também pode ter acesso a alguns registros ou informações."</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index d37ac018bcfd..70f09acc2c52 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"Permitir sempre a partir deste computador"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"Permitir"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"Depuração USB não permitida"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"O utilizador com sessão iniciada atualmente neste dispositivo não pode ativar a depuração USB. Para usar esta funcionalidade, mude para o utilizador principal."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"O utilizador com sessão iniciada atualmente neste dispositivo não pode ativar a depuração USB. Para usar esta funcionalidade, mude para um utilizador administrador."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Quer alterar o idioma do sistema para <xliff:g id="LANGUAGE">%1$s</xliff:g>?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Alteração do idioma do sistema solicitada por outro dispositivo"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Alterar idioma"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"Permitir sempre nesta rede"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"Permitir"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Depuração sem fios não permitida"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"O utilizador com sessão iniciada atualmente neste dispositivo não pode ativar a depuração sem fios. Para usar esta funcionalidade, mude para o utilizador principal."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"O utilizador com sessão iniciada atualmente neste dispositivo não pode ativar a depuração sem fios. Para usar esta funcionalidade, mude para um utilizador administrador."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"Porta USB desativada"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"Para proteger o dispositivo contra líquidos ou resíduos, a porta USB está desativada e não irá detetar quaisquer acessórios.\n\nSerá notificado quando for seguro utilizar a porta USB novamente."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"Porta USB ativada para detetar carregadores e acessórios"</string>
@@ -125,7 +125,7 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Assistente de voz"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Carteira"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"Leitor de códigos QR"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"Desbloquear"</string>
+ <string name="accessibility_unlock_button" msgid="3613812140816244310">"Desbloqueado"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"Dispositivo bloqueado"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"A analisar o rosto…"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Enviar"</string>
@@ -168,7 +168,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"Imposs. reconhecer rosto"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Usar impressão digital"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth ligado."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"Percentagem da bateria desconhecida."</string>
@@ -180,8 +180,10 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"Modo de avião"</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN ativada."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"Bateria a <xliff:g id="NUMBER">%d</xliff:g> por cento."</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Bateria a <xliff:g id="PERCENTAGE">%1$s</xliff:g> por cento, resta(m) cerca de <xliff:g id="TIME">%2$s</xliff:g> com base na sua utilização."</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Bateria a <xliff:g id="PERCENTAGE">%1$d</xliff:g> por cento, resta(m) cerca de <xliff:g id="TIME">%2$s</xliff:g> com base na sua utilização."</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Bateria a carregar (<xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> %%)."</string>
+ <string name="accessibility_battery_level_charging_paused" msgid="1716051308782906917">"Bateria a <xliff:g id="PERCENTAGE">%d</xliff:g> por cento. O carregamento foi pausado para proteção da bateria."</string>
+ <string name="accessibility_battery_level_charging_paused_with_estimate" msgid="4006089349465741762">"Bateria a <xliff:g id="PERCENTAGE">%1$d</xliff:g> por cento, resta(m) cerca de <xliff:g id="TIME">%2$s</xliff:g> com base na sua utilização. O carregamento foi pausado para proteção da bateria."</string>
<string name="accessibility_overflow_action" msgid="8555835828182509104">"Ver todas as notificações"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"Teletipo ativado."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Campainha em vibração."</string>
@@ -386,16 +388,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Quando está a partilhar, gravar ou transmitir uma app, a app <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> tem acesso a tudo o que é apresentado ou reproduzido nessa app. Por isso, tenha cuidado com palavras-passe, detalhes de pagamento, mensagens ou outras informações confidenciais."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Continuar"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Partilhe ou grave uma app"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Permitir que esta app partilhe ou grave?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Quando está a partilhar, gravar ou transmitir, esta app tem acesso a tudo o que está visível no seu ecrã ou é reproduzido no seu dispositivo. Por isso, tenha cuidado com palavras-passe, detalhes de pagamento, mensagens ou outras informações confidenciais."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Quando está a partilhar, gravar ou transmitir uma app, esta app tem acesso a tudo o que é apresentado ou reproduzido nessa app. Por isso, tenha cuidado com palavras-passe, detalhes de pagamento, mensagens ou outras informações confidenciais."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Bloqueado pelo administrador de TI"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"A captura de ecrã está desativada pela política do dispositivo"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Limpar tudo"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Gerir"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Histórico"</string>
@@ -511,7 +508,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Desbloquear para utilizar"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Ocorreu um problema ao obter os seus cartões. Tente mais tarde."</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Definições do ecrã de bloqueio"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"Leia o código QR"</string>
+ <string name="qr_code_scanner_title" msgid="1938155688725760702">"Leitor de códigos QR"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Perfil de trabalho"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Modo de avião"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Não vai ouvir o próximo alarme às <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -794,6 +791,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Ampliar o ecrã inteiro"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Ampliar parte do ecrã"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Mudar"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Permitir deslocamento da página na diagonal"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Redimensionar"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"Alterar tipo de ampliação"</string>
@@ -1024,4 +1023,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d de MMM"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"Permitir que a app <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> aceda a todos os registos do dispositivo?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"Permitir acesso único"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Não permitir"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"Os registos do dispositivo documentam o que ocorre no seu dispositivo. As apps podem usar esses registos para detetar e corrigir problemas.\n\nAlguns registos podem conter informações confidenciais e, por isso, o acesso a todos os registos do dispositivo só deve ser permitido às apps nas quais confia. \n\nSe não permitir o acesso desta app a todos os registos do dispositivo, esta pode ainda assim aceder aos próprios registos. O fabricante do dispositivo pode continuar a aceder a alguns registos ou informações no seu dispositivo."</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index cbc8fc7a2ee1..6e116be2fdf6 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"Sempre permitir a partir deste computador"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"Permitir"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"Depuração USB não permitida"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"O usuário conectado a este dispositivo não pode ativar a depuração USB. Para usar esse recurso, mude para o usuário principal \"NAME\"."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"O usuário conectado a este dispositivo não pode ativar a depuração USB. Para usar esse recurso, entre em uma conta de usuário administrador."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Quer mudar o idioma do sistema para <xliff:g id="LANGUAGE">%1$s</xliff:g>?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Mudança do idioma do sistema solicitada por outro dispositivo"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Alterar idioma"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"Sempre permitir nesta rede"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"Permitir"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Depuração por Wi-Fi não permitida"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"O usuário conectado a este dispositivo não pode ativar a depuração por Wi-Fi. Para usar esse recurso, conecte-se como o usuário principal."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"O usuário conectado a este dispositivo não pode ativar a depuração por Wi-Fi. Para usar esse recurso, entre em uma conta de usuário administrador."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"Porta USB desativada"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"Para proteger seu dispositivo de líquidos e detritos, a porta USB está desativada e não detectará nenhum acessório.\n\nVocê receberá uma notificação quando for seguro usar a porta USB novamente."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"Porta USB ativada para detectar carregadores e acessórios"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Assistência de voz"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Carteira"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"Leitor de código QR"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"Desbloquear"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"Dispositivo bloqueado"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Verificando rosto"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Enviar"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"Rosto não reconhecido"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Use a impressão digital"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth conectado."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"Porcentagem da bateria desconhecida."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"Modo avião."</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN ativada."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"Bateria em <xliff:g id="NUMBER">%d</xliff:g> por cento."</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Bateria com <xliff:g id="PERCENTAGE">%1$s</xliff:g> de carga, tempo restante aproximado, com base no seu uso: <xliff:g id="TIME">%2$s</xliff:g>"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Bateria com <xliff:g id="PERCENTAGE">%1$d</xliff:g> de carga, tempo restante aproximado, com base no seu uso: <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Bateria carregando: <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"Ver todas as notificações"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"TeleTYpewriter ativado."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Vibração da campainha."</string>
@@ -386,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Quando você compartilha, grava ou transmite um app, o <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> tem acesso a todas as informações visíveis na tela ou reproduzidas no dispositivo. Tenha cuidado com senhas, detalhes de pagamento, mensagens ou outras informações sensíveis."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Continuar"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Compartilhar ou gravar um app"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Permitir que este app compartilhe ou grave a tela?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Quando você compartilha, grava ou transmite a tela, este app tem acesso a todas as informações visíveis nela ou reproduzidas no dispositivo. Tenha cuidado com senhas, detalhes de pagamento, mensagens e outras informações sensíveis."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Quando você compartilha, grava ou transmite a tela, este app tem acesso a todas as informações visíveis nela ou reproduzidas no dispositivo. Tenha cuidado com senhas, detalhes de pagamento, mensagens e outras informações sensíveis."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Ação bloqueada pelo administrador de TI"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"A captura de tela foi desativada pela política do dispositivo"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Limpar tudo"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Gerenciar"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Histórico"</string>
@@ -511,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Desbloquear para usar"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Ocorreu um problema ao carregar os cards. Tente novamente mais tarde"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Configurações de tela de bloqueio"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"Ler código QR"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Perfil de trabalho"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Modo avião"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Você não ouvirá o próximo alarme às <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -794,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Ampliar toda a tela"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Ampliar parte da tela"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Trocar"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Permitir rolagem diagonal"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Redimensionar"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"Mudar tipo de ampliação"</string>
@@ -1024,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d de MMM"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"Permitir que o app <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> acesse todos os registros do dispositivo?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"Permitir o acesso único"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Não permitir"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"Os registros do dispositivo gravam o que acontece nele. Os apps podem usar esses registros para encontrar e corrigir problemas.\n\nAlguns registros podem conter informações sensíveis, então autorize o acesso a eles apenas para os apps em que você confia. \n\nSe você não permitir que esse app acesse todos os registros do dispositivo, ele ainda vai poder acessar os próprios. O fabricante do dispositivo também pode ter acesso a alguns registros ou informações."</string>
</resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 566788443388..42e62be8dcbd 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"Permite întotdeauna de pe acest computer"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"Permite"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"Remedierea erorilor prin USB nu este permisă"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"Utilizatorul conectat momentan pe acest dispozitiv nu poate activa remedierea erorilor prin USB. Pentru a folosi această funcție, comută la utilizatorul principal."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"Utilizatorul conectat momentan pe acest dispozitiv nu poate activa remedierea erorilor prin USB. Pentru a folosi această funcție, comută la administrator."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Schimbi limba de sistem la <xliff:g id="LANGUAGE">%1$s</xliff:g>?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Alt dispozitiv solicită schimbarea limbii de sistem"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Schimbă limba"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"Permite întotdeauna în această rețea"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"Permite"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Remedierea erorilor wireless nu este permisă"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"Utilizatorul conectat momentan pe acest dispozitiv nu poate activa remedierea erorilor wireless. Pentru a folosi această funcție, comută la utilizatorul principal."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"Utilizatorul conectat momentan pe acest dispozitiv nu poate activa remedierea erorilor wireless. Pentru a folosi această funcție, comută la administrator."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"Portul USB a fost dezactivat"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"Pentru a proteja dispozitivul de lichide sau reziduuri, portul USB este dezactivat și nu va detecta niciun accesoriu.\n\nVei primi o notificare când poți folosi din nou portul USB."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"Portul USB a fost activat pentru a detecta încărcătoarele și accesoriile"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Asistent vocal"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Portofel"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"Scanner de coduri QR"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"Deblochează"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"Dispozitiv blocat"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Scanarea chipului"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Trimite"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"Chip nerecunoscut"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Folosește amprenta"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Conectat prin Bluetooth."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"Procentajul bateriei este necunoscut."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"Mod Avion."</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"Rețea VPN activată"</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"Baterie: <xliff:g id="NUMBER">%d</xliff:g> la sută."</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Procentul rămas din baterie este <xliff:g id="PERCENTAGE">%1$s</xliff:g>. În baza utilizării, timpul rămas este de aproximativ <xliff:g id="TIME">%2$s</xliff:g>"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Procentul rămas din baterie este <xliff:g id="PERCENTAGE">%1$d</xliff:g>. În baza utilizării, timpul rămas este de aproximativ <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Bateria se încarcă, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> la sută."</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"Vezi toate notificările"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"TeleTypewriter activat."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Vibrare sonerie."</string>
@@ -386,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Când permiți accesul, înregistrezi sau proiectezi o aplicație, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> are acces la orice se afișează pe ecran sau se redă în aplicație. Ai grijă cu parolele, detaliile de plată, mesajele sau alte informații sensibile."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Continuă"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Permite accesul la o aplicație sau înregistreaz-o"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Permiți trimiterea sau înregistrarea din aplicație?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Când permiți accesul, înregistrezi sau proiectezi, aplicația are acces la orice este vizibil pe ecran sau se redă pe dispozitiv. Ai grijă cu parolele, detaliile de plată, mesajele sau alte informații sensibile."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Când permiți accesul, înregistrezi sau proiectezi o aplicație, aceasta are acces la orice se afișează pe ecran sau se redă în aplicație. Ai grijă cu parolele, detaliile de plată, mesajele sau alte informații sensibile."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Blocată de administratorul IT"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"Capturile de ecran sunt dezactivate de politica privind dispozitivele"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Șterge toate notificările"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Gestionează"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Istoric"</string>
@@ -511,7 +511,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Deblochează pentru a folosi"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"A apărut o problemă la preluarea cardurilor. Încearcă din nou mai târziu"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Setările ecranului de blocare"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"Scanează codul QR"</string>
+ <string name="qr_code_scanner_title" msgid="1938155688725760702">"Scanner de coduri QR"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Profil de serviciu"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Mod Avion"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Nu vei auzi următoarea alarmă <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -794,6 +794,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Mărește tot ecranul"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Mărește o parte a ecranului"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Comutator"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Permite derularea pe diagonală"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Redimensionează"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"Schimbă tipul de mărire"</string>
@@ -1024,4 +1026,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EE, z LLL"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"Permiți ca <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> să acceseze toate jurnalele dispozitivului?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"Permite accesul o dată"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Nu permite"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"Jurnalele dispozitivului înregistrează activitatea de pe dispozitivul tău. Aplicațiile pot folosi aceste jurnale pentru a identifica și a remedia probleme.\n\nUnele jurnale pot să conțină informații sensibile, prin urmare permite accesul la toate jurnalele dispozitivului doar aplicațiilor în care ai încredere. \n\nDacă nu permiți accesul aplicației la toate jurnalele dispozitivului, aceasta poate în continuare să acceseze propriile jurnale. Este posibil ca producătorul dispozitivului să acceseze în continuare unele jurnale sau informații de pe dispozitiv."</string>
</resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 3b820ec21272..1bfca048107d 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"Всегда разрешать отладку с этого компьютера"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"Разрешить"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"Отладка по USB запрещена"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"В этом аккаунте нельзя включить отладку по USB. Перейдите в аккаунт основного пользователя."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"В этом аккаунте нельзя включить отладку по USB. Перейдите в аккаунт администратора."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Изменить системный язык на <xliff:g id="LANGUAGE">%1$s</xliff:g>?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Получен запрос на изменение системного языка от другого устройства."</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Изменить язык"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"Всегда разрешать отладку в этой сети"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"Разрешить"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Отладка по Wi-Fi запрещена"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"В этом аккаунте нельзя включить отладку по Wi-Fi. Перейдите в аккаунт основного пользователя."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"В этом аккаунте нельзя включить отладку по Wi-Fi. Перейдите в аккаунт администратора."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"USB-порт отключен"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"Чтобы внутрь устройства не попала вода или грязь, USB-порт был отключен. Сейчас через него нельзя подсоединять другие устройства.\n\nКогда USB-порт снова можно будет использовать, вы получите уведомление."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"USB-порт активен и может распознавать аксессуары и зарядные устройства."</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Аудиоподсказки"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Кошелек"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"Сканер QR-кодов"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"Разблокировать."</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"Устройство заблокировано"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Сканирование лица"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Отправить"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"Лицо не распознано."</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Используйте отпечаток."</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth-соединение установлено."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"Уровень заряда батареи в процентах неизвестен."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"Режим полета."</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"Режим VPN включен."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"Заряд батареи в процентах: <xliff:g id="NUMBER">%d</xliff:g>."</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Заряд батареи в процентах: <xliff:g id="PERCENTAGE">%1$s</xliff:g>. Оценка оставшегося времени работы: <xliff:g id="TIME">%2$s</xliff:g>."</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Заряд батареи в процентах: <xliff:g id="PERCENTAGE">%1$d</xliff:g>. Оценка оставшегося времени работы: <xliff:g id="TIME">%2$s</xliff:g>."</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Зарядка батареи. Текущий заряд: <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> %%."</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"Показать все уведомления"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"Телетайп включен."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Вибровызов."</string>
@@ -386,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Когда вы демонстрируете, транслируете экран или записываете видео с него, приложение \"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>\" получает доступ ко всему, что видно и воспроизводится на экране устройства. Помните об этом, если соберетесь вводить или просматривать пароли, платежные данные, сообщения и другую конфиденциальную информацию."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Далее"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Демонстрация экрана или запись видео с него"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Разрешить приложению демонстрировать экран или записывать видео с него?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Когда вы демонстрируете, транслируете экран или записываете видео с него, это приложение получает доступ ко всему, что видно и воспроизводится на экране устройства. Помните об этом, если соберетесь вводить или просматривать пароли, платежные данные, сообщения и другую конфиденциальную информацию."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Когда вы демонстрируете, транслируете экран или записываете видео с него, это приложение получает доступ ко всему, что видно и воспроизводится на экране устройства. Помните об этом, если соберетесь вводить или просматривать пароли, платежные данные, сообщения и другую конфиденциальную информацию."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Заблокировано вашим администратором"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"Запись экрана отключена в соответствии с правилами для устройства."</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Очистить все"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Настроить"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"История"</string>
@@ -511,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Разблокировать для использования"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Не удалось получить информацию о картах. Повторите попытку позже."</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Настройки заблокированного экрана"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"Сканировать QR-код"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Рабочий профиль"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Режим полета"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Следующий будильник: <xliff:g id="WHEN">%1$s</xliff:g>. Звук отключен."</string>
@@ -794,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Увеличение всего экрана"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Увеличить часть экрана"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Переключить"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Разрешить прокручивать по диагонали"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Изменить размер"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"Изменить тип увеличения"</string>
@@ -1024,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"d MMM EEEE"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"Разрешить приложению \"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g>\" доступ ко всем журналам устройства?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"Разрешить разовый доступ"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Запретить"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"В журналы записывается информация о том, что происходит на устройстве. Приложения могут использовать их, чтобы находить и устранять неполадки.\n\nТак как некоторые журналы могут содержать конфиденциальную информацию, доступ ко всем журналам следует предоставлять только тем приложениям, которым вы доверяете. \n\nЕсли вы не предоставите такой доступ этому приложению, оно по-прежнему сможет просматривать свои журналы. Не исключено, что некоторые журналы или сведения на вашем устройстве будут по-прежнему доступны его производителю."</string>
</resources>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index 5696980036a8..8d06d379a184 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"සැම විටම මෙම පරිගණකයෙන් ඉඩ ලබා දෙන්න"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"ඉඩ දෙන්න"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"USB නිදොස්කරණය වෙත අවසර නැහැ"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"දැනට මෙම උපාංගයට පුරා ඇති පරිශීලකයාට USB නිදොස්කරණය ක්‍රියාත්මක කළ නොහැක. මෙම විශේෂාංගය භාවිතා කිරීම සඳහා, මූලික පරිශීලකයා වෙත මාරු වෙන්න."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"දැනට මෙම උපාංගයට පුරා ඇති පරිශීලකයාට USB නිදොස්කරණය ක්‍රියාත්මක කළ නොහැක. මෙම විශේෂාංගය භාවිතා කිරීම සඳහා, පරිපාලක පරිශීලකයෙකු වෙත මාරු වෙන්න."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"ඔබට පද්ධති භාෂාව <xliff:g id="LANGUAGE">%1$s</xliff:g> භාෂාවට වෙනස් කිරීමට අවශ්‍යද?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"වෙනත් උපාංගයකින් පද්ධති භාෂාව වෙනස් කිරීම ඉල්ලා ඇත"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"භාෂාව වෙනස් කරන්න"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"මෙම ජාලයේ සැමවිට ඉඩ දෙන්න"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"ඉඩ දෙන්න"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"නොරැහැන් නිදොස්කරණය ඉඩ දී නැත"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"මෙම උපාංගයට දැනට පුරා ඇති පරිශීලකට නොරැහැන් නිදොස්කරණය ක්‍රියාත්මක කළ නොහැකිය. මෙම විශේෂාංගය භාවිතට, මූලික පරිශීලක වෙත මාරු වෙන්න."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"මෙම උපාංගයට දැනට පුරා ඇති පරිශීලකට නොරැහැන් නිදොස්කරණය ක්‍රියාත්මක කළ නොහැකිය. මෙම විශේෂාංගය භාවිතට, පරිපාලක පරිශීලකයෙකු වෙත මාරු වෙන්න."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"USB තොට අබලයි"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"ඔබේ උපාංගය ද්‍රවවලින් හෝ කුණුවලින් ආරක්‍ෂා කිරීමට, USB තොට අබල කර තිබෙන අතර, එය කිසිම අමතරාංගයක් අනාවරණ නොකරයි.\n\nනැවතත් USB තොට භාවිත කිරීම හරි නම් ඔබව දැනුම් දෙනු ලැබේ."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"ආරෝපක සහ උපකාරක අංග අනාවරණ කිරීමට USB තොට සබල කර ඇත"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"හඬ සහාය"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"QR කේත ස්කෑනරය"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"අඟුල අරින්න"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"උපාංගය අගුලු දමා ඇත"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"මුහුණ ස්කෑන් කිරීම"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"යවන්න"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"මුහුණ හඳුනා ගත නොහැක"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"ඒ වෙනුවට ඇඟිලි සලකුණ භාවිත කරන්න"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"බ්ලූටූත් සම්බන්ධිතයි."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"බැටරි ප්‍රතිශතය නොදනී."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"අහස්යානා ආකාරය."</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN ක්‍රියාත්මකයි."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"බැටරි ප්‍රතිශතය <xliff:g id="NUMBER">%d</xliff:g>"</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"බැටරි ප්‍රතිශතය <xliff:g id="PERCENTAGE">%1$s</xliff:g>, ඔබේ භාවිතයට අනුව <xliff:g id="TIME">%2$s</xliff:g> ක් පමණ ඉතුරුයි"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"බැටරි ප්‍රතිශතය <xliff:g id="PERCENTAGE">%1$d</xliff:g>, ඔබේ භාවිතයට අනුව <xliff:g id="TIME">%2$s</xliff:g> ක් පමණ ඉතුරුයි"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"බැටරිය ආරෝපණය කරමින්, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"සියලු දැනුම්දීම් බලන්න"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"TeleTypewriter ක්‍රියාත්මකයි."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"හඬ නඟනය කම්පනය වේ."</string>
@@ -305,28 +310,17 @@
<string name="sensor_privacy_mic_unblocked_toast_content" msgid="306555320557065068">"මයික්‍රෆෝනය ලබා ගත හැකිය"</string>
<string name="sensor_privacy_camera_unblocked_toast_content" msgid="7843105715964332311">"කැමරාව ලබා ගත හැකිය"</string>
<string name="sensor_privacy_mic_camera_unblocked_toast_content" msgid="7339355093282661115">"මයික්‍රෆෝනය සහ කැමරාව ලබා ගත හැකිය"</string>
- <!-- no translation found for sensor_privacy_mic_turned_on_dialog_title (6348853159838376513) -->
- <skip />
- <!-- no translation found for sensor_privacy_mic_turned_off_dialog_title (5760464281790732849) -->
- <skip />
- <!-- no translation found for sensor_privacy_mic_unblocked_dialog_content (4889961886199270224) -->
- <skip />
- <!-- no translation found for sensor_privacy_mic_blocked_no_exception_dialog_content (5864898470772965394) -->
- <skip />
- <!-- no translation found for sensor_privacy_mic_blocked_with_exception_dialog_content (810289713700437896) -->
- <skip />
- <!-- no translation found for sensor_privacy_camera_turned_on_dialog_title (8039095295100075952) -->
- <skip />
- <!-- no translation found for sensor_privacy_camera_turned_off_dialog_title (1936603903120742696) -->
- <skip />
- <!-- no translation found for sensor_privacy_camera_unblocked_dialog_content (7847190103011782278) -->
- <skip />
- <!-- no translation found for sensor_privacy_camera_blocked_dialog_content (3182428709314874616) -->
- <skip />
- <!-- no translation found for sensor_privacy_htt_blocked_dialog_content (3333321592997666441) -->
- <skip />
- <!-- no translation found for sensor_privacy_dialog_open_settings (1503088305279285048) -->
- <skip />
+ <string name="sensor_privacy_mic_turned_on_dialog_title" msgid="6348853159838376513">"මයික්‍රෆෝනය ක්‍රියාත්මකයි"</string>
+ <string name="sensor_privacy_mic_turned_off_dialog_title" msgid="5760464281790732849">"මයික්‍රෆෝනය ක්‍රියාවිරහිතයි"</string>
+ <string name="sensor_privacy_mic_unblocked_dialog_content" msgid="4889961886199270224">"සියලු යෙදුම් සහ සේවා සඳහා මයික්‍රෆෝනය සබල කර ඇත."</string>
+ <string name="sensor_privacy_mic_blocked_no_exception_dialog_content" msgid="5864898470772965394">"සියලු යෙදුම් සහ සේවා සඳහා මයික්‍රෆෝන ප්‍රවේශය අබල කර ඇත. ඔබට සැකසීම් &gt; පෞද්ගලිකත්වය &gt; මයික්‍රෆෝනය තුළ මයික්‍රෆෝන ප්‍රවේශය සබල කළ හැක."</string>
+ <string name="sensor_privacy_mic_blocked_with_exception_dialog_content" msgid="810289713700437896">"සියලු යෙදුම් සහ සේවා සඳහා මයික්‍රෆෝන ප්‍රවේශය අබල කර ඇත. ඔබට මෙය සැකසීම් &gt; පෞද්ගලිකත්වය &gt; මයික්‍රෆෝනය තුළ වෙනස් කළ හැක."</string>
+ <string name="sensor_privacy_camera_turned_on_dialog_title" msgid="8039095295100075952">"කැමරාව ක්‍රියාත්මක කර ඇත"</string>
+ <string name="sensor_privacy_camera_turned_off_dialog_title" msgid="1936603903120742696">"කැමරාව ක්‍රියාවිරහිතයි"</string>
+ <string name="sensor_privacy_camera_unblocked_dialog_content" msgid="7847190103011782278">"සියලු යෙදුම් සහ සේවා සඳහා කැමරාව සබල කර ඇත."</string>
+ <string name="sensor_privacy_camera_blocked_dialog_content" msgid="3182428709314874616">"සියලු යෙදුම් සහ සේවා සඳහා කැමරා ප්‍රවේශය අබල කර ඇත."</string>
+ <string name="sensor_privacy_htt_blocked_dialog_content" msgid="3333321592997666441">"මයික්‍රෆෝන බොත්තම භාවිතය සඳහා, සැකසීම් තුළ මයික්‍රෆෝන ප්‍රවේශය සබල කරන්න."</string>
+ <string name="sensor_privacy_dialog_open_settings" msgid="1503088305279285048">"සැකසීම් විවෘත කරන්න."</string>
<string name="media_seamless_other_device" msgid="4654849800789196737">"වෙනත් උපාංගය"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"දළ විශ්ලේෂණය ටොගල කරන්න"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"එලාම සිහිකැඳවීම්, සිදුවීම්, සහ ඔබ සඳහන් කළ අමතන්නන් හැර, ශබ්ද සහ කම්පනවලින් ඔබට බාධා නොවනු ඇත. සංගීතය, වීඩියෝ, සහ ක්‍රීඩා ඇතුළු ඔබ වාදනය කිරීමට තෝරන ලද සියලු දේ ඔබට තවම ඇසෙනු ඇත."</string>
@@ -397,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"ඔබ යෙදුමක් බෙදා ගන්නා විට, පටිගත කරන විට හෝ විකාශය කරන විට, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> හට එම යෙදුමේ පෙන්වන හෝ වාදනය කරන ඕනෑම දෙයකට ප්‍රවේශය ඇත. එබැවින් මුරපද, ගෙවීම් විස්තර, පණිවිඩ හෝ වෙනත් සංවේදී තොරතුරු සමග ප්‍රවේශම් වන්න."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"ඉදිරියට යන්න"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"යෙදුමක් බෙදා ගන්න හෝ පටිගත කරන්න"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"මෙම යෙදුම බෙදා ගැනීමට හෝ පටිගත කිරීමට ඉඩ දෙන්න ද?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"ඔබ බෙදා ගන්නා විට, පටිගත කරන විට, හෝ විකාශය කරන විට, හට ඔබේ තිරයේ පෙනෙන හෝ ඔබේ උපාංගයේ වාදනය වන ඕනෑම දෙයකට ප්‍රවේශය ඇත. එබැවින් මුරපද, ගෙවීම් විස්තර, පණිවිඩ හෝ වෙනත් සංවේදී තොරතුරු සමග ප්‍රවේශම් වන්න."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"ඔබ යෙදුමක් බෙදා ගන්නා විට, පටිගත කරන විට හෝ විකාශය කරන විට, හට එම යෙදුමේ පෙන්වන හෝ වාදනය කරන ඕනෑම දෙයකට ප්‍රවේශය ඇත. එබැවින් මුරපද, ගෙවීම් විස්තර, පණිවිඩ හෝ වෙනත් සංවේදී තොරතුරු සමග ප්‍රවේශම් වන්න."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"ඔබේ IT පරිපාලක විසින් අවහිර කර ඇත"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"උපාංග ප්‍රතිපත්තිය මගින් තිර ග්‍රහණය කිරීම අබල කර ඇත"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"සියල්ල හිස් කරන්න"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"කළමනාකරණය කරන්න"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"ඉතිහාසය"</string>
@@ -522,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"භාවිත කිරීමට අගුලු හරින්න"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"ඔබගේ කාඩ්පත ලබා ගැනීමේ ගැටලුවක් විය, කරුණාකර පසුව නැවත උත්සාහ කරන්න"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"අගුලු තිර සැකසීම්"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"QR කේතය ස්කෑන් කරන්න"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"කාර්යාල පැතිකඩ"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"ගුවන්යානා ප්‍රකාරය"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"ඔබට ඔබේ ඊළඟ එලාමය <xliff:g id="WHEN">%1$s</xliff:g> නොඇසෙනු ඇත"</string>
@@ -805,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"පූර්ණ තිරය විශාලනය කරන්න"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"තිරයේ කොටසක් විශාලනය කරන්න"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"ස්විචය"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"විකර්ණ අනුචලනයට ඉඩ දෙන්න"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"ප්‍රතිප්‍රමාණය කරන්න"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"විශාලන වර්ගය වෙනස් කරන්න"</string>
@@ -1035,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> හට සියලු උපාංග ලොග ප්‍රවේශ වීමට ඉඩ දෙන්න ද?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"එක් වරක් ප්‍රවේශය ඉඩ දෙන්න"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"ඉඩ නොදෙන්න"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"උපාංග ලොග ඔබේ උපාංගයෙහි සිදු වන දේ වාර්තා කරයි. ගැටලු සොයා ගැනීමට සහ නිරාකරණයට යෙදුම්වලට මෙම ලොග භාවිතා කළ හැක.\n\nසමහර ලොගවල සංවේදී තතු අඩංගු විය හැකි බැවින්, ඔබ විශ්වාස කරන යෙදුම්වලට පමණක් සියලු උපාංග ලොග වෙත ප්‍රවේශ වීමට ඉඩ දෙන්න. \n\nඔබ මෙම යෙදුමට සියලු උපාංග ලොග වෙත ප්‍රවේශ වීමට ඉඩ නොදෙන්නේ නම්, එයට තවමත් එහිම ලොග වෙත ප්‍රවේශ විය හැක. ඔබේ උපාංග නිෂ්පාදකයාට තවමත් ඔබේ උපාංගයෙහි සමහර ලොග හෝ තතු වෙත ප්‍රවේශ විය හැක."</string>
</resources>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 6aaafc12323a..2cd11631697c 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"Vždy povoliť z tohto počítača"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"Povoliť"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"Ladenie cez USB nie je povolené"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"Používateľ, ktorý je práve prihlásený v tomto zariadení, nemôže zapnúť ladenie USB. Ak chcete použiť túto funkciu, prepnite na hlavného používateľa."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"Používateľ, ktorý je práve prihlásený v tomto zariadení, nemôže zapnúť ladenie USB. Ak chcete použiť túto funkciu, prepnite na správcu."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Chcete zmeniť jazyk systému na možnosť <xliff:g id="LANGUAGE">%1$s</xliff:g>?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Zmenu jazyka systému vyžiadalo iné zariadenie"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Zmeniť jazyk"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"Vždy povoliť v tejto sieti"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"Povoliť"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Bezdrôtové ladenie nie je povolené"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"Používateľ, ktorý je práve prihlásený v tomto zariadení, nemôže zapnúť bezdrôtové ladenie. Ak chcete použiť túto funkciu, prepnite na hlavného používateľa."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"Používateľ, ktorý je práve prihlásený v tomto zariadení, nemôže zapnúť bezdrôtové ladenie. Ak chcete použiť túto funkciu, prepnite na správcu."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"Port USB je deaktivovaný"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"Port USB je deaktivovaný na zaistenie ochrany zariadenia pred tekutinami alebo nečistotami a nerozpoznáva príslušenstvo.\n\nKeď ho budete môcť znova použiť, upozorníme vás."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"Bol povolený port USB na zisťovanie nabíjačiek a príslušenstva"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Hlasový asistent"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Peňaženka"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"Skener QR kódov"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"Odomknúť"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"Zariadenie je uzamknuté"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Skenovanie tváre"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Odoslať"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"Tvár sa nedá rozpoznať"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Používať radšej odtlačok"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth pripojené."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"Percento batérie nie je známe."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"Režim v lietadle."</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN je zapnuté."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"Batéria <xliff:g id="NUMBER">%d</xliff:g> percent."</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Percentá batérie: <xliff:g id="PERCENTAGE">%1$s</xliff:g>. Na základe vášho používania zostáva <xliff:g id="TIME">%2$s</xliff:g>."</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Percentá batérie: <xliff:g id="PERCENTAGE">%1$d</xliff:g>. Na základe vášho používania zostáva <xliff:g id="TIME">%2$s</xliff:g>."</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Nabíja sa batéria, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> %%."</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"Zobraziť všetky upozornenia"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"Rozhranie TeleTypewriter je povolené."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Vibračné zvonenie."</string>
@@ -386,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Počas zdieľania, nahrávania alebo prenosu bude mať aplikácia <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> prístup k všetkému obsahu, ktorý sa v nej bude zobrazovať alebo prehrávať. Preto venujte zvýšenú pozornosť heslám, platobným údajom, správam a ďalším citlivým údajom."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Pokračovať"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Aplikácia na zdieľanie alebo nahrávanie"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Chcete povoliť tejto aplikácii zdieľať alebo nahrávať?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Počas zdieľania, nahrávania alebo prenosu bude mať táto aplikácia prístup k všetkému na obrazovke, prípadne k obsahu, ktorý sa bude v zariadení prehrávať. Venujte preto zvýšenú pozornosť heslám, platobným údajom, správam a ďalším citlivým údajom."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Počas zdieľania, nahrávania alebo prenosu bude mať táto aplikácia prístup k všetkému obsahu, ktorý sa v nej bude zobrazovať alebo prehrávať. Venujte preto zvýšenú pozornosť heslám, platobným údajom, správam či ďalším citlivým údajom."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Blokované vaším správcom IT"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"Snímanie obrazovky je zakázané pravidlami pre zariadenie"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Vymazať všetko"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Spravovať"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"História"</string>
@@ -511,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Odomknúť a použiť"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Pri načítavaní kariet sa vyskytol problém. Skúste to neskôr."</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Nastavenia uzamknutej obrazovky"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"Skenovanie QR kódu"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Pracovný profil"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Režim v lietadle"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Váš budík o <xliff:g id="WHEN">%1$s</xliff:g> sa nespustí"</string>
@@ -794,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Zväčšenie celej obrazovky"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Zväčšiť časť obrazovky"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Prepnúť"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Povoliť diagonálne posúvanie"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Zmeniť veľkosť"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"Zmeniť typ zväčšenia"</string>
@@ -1024,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d. MMM"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"Chcete povoliť aplikácii <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> prístup k všetkým denníkom zariadenia?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"Povoliť jednorazový prístup"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Nepovoliť"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"Denníky zariadenia zaznamenávajú, čo sa deje vo vašom zariadení. Aplikácie môžu pomocou týchto denníkov vyhľadávať a riešiť problémy.\n\nNiektoré denníky môžu obsahovať citlivé údaje, preto povoľte prístup k všetkým denníkom zariadenia iba dôveryhodným aplikáciám. \n\nAk tejto aplikácii nepovolíte prístup k všetkým denníkom zariadenia, stále bude mať prístup k vlastným denníkom. Výrobca vášho zariadenia bude mať naďalej prístup k niektorým denníkom alebo informáciám vo vašom zariadení."</string>
</resources>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 36eead3ce44e..f97f83464f01 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"Vedno dovoli iz tega računalnika"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"Dovoli"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"Odpravljanje napak s povezavo USB ni dovoljeno"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"Uporabnik, trenutno prijavljen v napravo, ne more vklopiti odpravljanja napak s povezavo USB. Če želite uporabljati to funkcijo, preklopite na primarnega uporabnika."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"Uporabnik, trenutno prijavljen v napravo, ne more vklopiti odpravljanja napak s povezavo USB. Če želite uporabljati to funkcijo, preklopite na skrbniškega uporabnika."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Ali želite jezik sistema spremeniti na jezik <xliff:g id="LANGUAGE">%1$s</xliff:g>?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Spremembo jezika sistema je zahtevala druga naprava."</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Spremeni jezik"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"Vedno dovoli v tem omrežju"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"Dovoli"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Brezžično odpravljanje napak ni dovoljeno"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"Uporabnik, trenutno prijavljen v napravo, ne more vklopiti brezžičnega odpravljanja napak. Če želite uporabljati to funkcijo, preklopite na primarnega uporabnika."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"Uporabnik, trenutno prijavljen v napravo, ne more vklopiti brezžičnega odpravljanja napak. Če želite uporabljati to funkcijo, preklopite na skrbniškega uporabnika."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"Vrata USB so onemogočena"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"Zaradi zaščite naprave pred tekočino ali umazanijo so vrata USB onemogočena in ne bodo zaznala nobene dodatne opreme.\n\nKo bo znova varno uporabljati vrata USB, boste obveščeni."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"Vrata USB so omogočena za zaznavanje polnilnikov in dodatne opreme"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Glasovni pomočnik"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Google Denarnica"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"Optični bralnik kod QR"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"Odkleni"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"Naprava je zaklenjena."</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Optično branje obraza"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Pošlji"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"Obraz ni bil prepoznan."</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Uporabite prstni odtis."</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Povezava Bluetooth vzpostavljena."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"Neznan odstotek napolnjenosti baterije."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"Način za letalo."</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"Omrežje VPN je vklopljeno."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"Baterija <xliff:g id="NUMBER">%d</xliff:g> odstotkov."</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Napolnjenost baterije je <xliff:g id="PERCENTAGE">%1$s</xliff:g>, glede na način uporabe imate na voljo še približno <xliff:g id="TIME">%2$s</xliff:g>"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Napolnjenost baterije je <xliff:g id="PERCENTAGE">%1$d</xliff:g>, glede na način uporabe imate na voljo še približno <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Baterija se polni, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> odstotkov."</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"Prikaži vsa obvestila"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"TeleTypewriter omogočen."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Zvonjenje z vibriranjem."</string>
@@ -305,28 +310,17 @@
<string name="sensor_privacy_mic_unblocked_toast_content" msgid="306555320557065068">"Mikrofon je na voljo"</string>
<string name="sensor_privacy_camera_unblocked_toast_content" msgid="7843105715964332311">"Kamera je na voljo"</string>
<string name="sensor_privacy_mic_camera_unblocked_toast_content" msgid="7339355093282661115">"Mikrofon in kamera sta na voljo"</string>
- <!-- no translation found for sensor_privacy_mic_turned_on_dialog_title (6348853159838376513) -->
- <skip />
- <!-- no translation found for sensor_privacy_mic_turned_off_dialog_title (5760464281790732849) -->
- <skip />
- <!-- no translation found for sensor_privacy_mic_unblocked_dialog_content (4889961886199270224) -->
- <skip />
- <!-- no translation found for sensor_privacy_mic_blocked_no_exception_dialog_content (5864898470772965394) -->
- <skip />
- <!-- no translation found for sensor_privacy_mic_blocked_with_exception_dialog_content (810289713700437896) -->
- <skip />
- <!-- no translation found for sensor_privacy_camera_turned_on_dialog_title (8039095295100075952) -->
- <skip />
- <!-- no translation found for sensor_privacy_camera_turned_off_dialog_title (1936603903120742696) -->
- <skip />
- <!-- no translation found for sensor_privacy_camera_unblocked_dialog_content (7847190103011782278) -->
- <skip />
- <!-- no translation found for sensor_privacy_camera_blocked_dialog_content (3182428709314874616) -->
- <skip />
- <!-- no translation found for sensor_privacy_htt_blocked_dialog_content (3333321592997666441) -->
- <skip />
- <!-- no translation found for sensor_privacy_dialog_open_settings (1503088305279285048) -->
- <skip />
+ <string name="sensor_privacy_mic_turned_on_dialog_title" msgid="6348853159838376513">"Mikrofon je vklopljen"</string>
+ <string name="sensor_privacy_mic_turned_off_dialog_title" msgid="5760464281790732849">"Mikrofon je izklopljen"</string>
+ <string name="sensor_privacy_mic_unblocked_dialog_content" msgid="4889961886199270224">"Mikrofon je omogočen za vse aplikacije in storitve."</string>
+ <string name="sensor_privacy_mic_blocked_no_exception_dialog_content" msgid="5864898470772965394">"Dostop do mikrofona je onemogočen za vse aplikacije in storitve. Dostop do mikrofona lahko omogočite v »Nastavitve« &gt; »Zasebnost« &gt; »Mikrofon«."</string>
+ <string name="sensor_privacy_mic_blocked_with_exception_dialog_content" msgid="810289713700437896">"Dostop do mikrofona je onemogočen za vse aplikacije in storitve. To lahko spremenite v »Nastavitve« &gt; »Zasebnost« &gt; »Mikrofon«."</string>
+ <string name="sensor_privacy_camera_turned_on_dialog_title" msgid="8039095295100075952">"Fotoaparat je vklopljen"</string>
+ <string name="sensor_privacy_camera_turned_off_dialog_title" msgid="1936603903120742696">"Fotoaparat je izklopljen"</string>
+ <string name="sensor_privacy_camera_unblocked_dialog_content" msgid="7847190103011782278">"Fotoaparat je omogočen za vse aplikacije in storitve."</string>
+ <string name="sensor_privacy_camera_blocked_dialog_content" msgid="3182428709314874616">"Dostop do fotoaparata je onemogočen za vse aplikacije in storitve."</string>
+ <string name="sensor_privacy_htt_blocked_dialog_content" msgid="3333321592997666441">"Za uporabo gumba z mikrofonom omogočite dostop do mikrofona v nastavitvah."</string>
+ <string name="sensor_privacy_dialog_open_settings" msgid="1503088305279285048">"Odpri nastavitve"</string>
<string name="media_seamless_other_device" msgid="4654849800789196737">"Druga naprava"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Vklop/izklop pregleda"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Ne bodo vas motili zvoki ali vibriranje, razen v primeru alarmov, opomnikov, dogodkov in klicateljev, ki jih določite. Še vedno pa boste slišali vse, kar se boste odločili predvajati, vključno z glasbo, videoposnetki in igrami."</string>
@@ -397,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Pri deljenju, snemanju ali predvajanju aplikacije ima aplikacija <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> dostop do vsega, kar je prikazano ali predvajano v tej aplikaciji, zato bodite previdni z gesli, podatki za plačilo, sporočili ali drugimi občutljivimi podatki."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Naprej"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Deljenje ali snemanje aplikacije"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Ali tej aplikaciji dovolite deljenje ali snemanje?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Pri deljenju, snemanju ali predvajanju ima ta aplikacija dostop do vsega, kar je prikazano na zaslonu ali se predvaja v napravi. Zato bodite previdni z gesli, podatki za plačilo, sporočili ali drugimi občutljivimi podatki."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Pri deljenju, snemanju ali predvajanju aplikacije ima ta aplikacija dostop do vsega, kar je prikazano ali predvajano v tisti aplikaciji, zato bodite previdni z gesli, podatki za plačilo, sporočili ali drugimi občutljivimi podatki."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Blokiral skrbnik za IT"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"Zajemanje zaslonske slike je onemogočil pravilnik za naprave."</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Izbriši vse"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Upravljaj"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Zgodovina"</string>
@@ -522,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Odklenite za uporabo"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Pri pridobivanju kartic je prišlo do težave. Poskusite znova pozneje."</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Nastavitve zaklepanja zaslona"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"Optično branje kode QR"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Profil za Android Work"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Način za letalo"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Naslednjega alarma ob <xliff:g id="WHEN">%1$s</xliff:g> ne boste slišali"</string>
@@ -805,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Povečanje celotnega zaslona"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Povečava dela zaslona"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Stikalo"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Dovoli diagonalno pomikanje"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Spremeni velikost"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"Sprememba vrste povečave"</string>
@@ -1035,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d. MMM"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"Ali aplikaciji <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> dovolite dostop do vseh dnevnikov naprave?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"Dovoli enkratni dostop"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Ne dovoli"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"V dnevnikih naprave se beleži dogajanje v napravi. Aplikacije lahko te dnevnike uporabijo za iskanje in odpravljanje težav.\n\nNekateri dnevniki morda vsebujejo občutljive podatke, zato dostop do vseh dnevnikov naprave omogočite le aplikacijam, ki jim zaupate. \n\nČe tej aplikaciji ne dovolite dostopa do vseh dnevnikov naprave, bo aplikacija kljub temu lahko dostopala do svojih dnevnikov. Proizvajalec naprave bo morda lahko kljub temu dostopal do nekaterih dnevnikov ali podatkov v napravi."</string>
</resources>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index e73a3228f736..19417a5d8c87 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"Lejo gjithmonë nga ky kompjuter"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"Lejo"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"Korrigjimi përmes USB-së nuk lejohet"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"Përdoruesi i identifikuar aktualisht në këtë pajisje nuk mund ta aktivizojë korrigjimin përmes USB-së. Për ta përdorur këtë veçori, kalo te përdoruesi parësor."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"Përdoruesi i identifikuar aktualisht në këtë pajisje nuk mund ta aktivizojë korrigjimin e USB-së. Për ta përdorur këtë funksion, kalo te përdoruesi administrator."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Dëshiron ta ndryshosh gjuhën e sistemit në <xliff:g id="LANGUAGE">%1$s</xliff:g>?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Një pajisje tjetër kërkoi ndryshimin e gjuhës së sistemit"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Ndrysho gjuhën"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"Lejo gjithmonë në këtë rrjet"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"Lejo"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Korrigjimi përmes Wi-Fi nuk lejohet"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"Përdoruesi i identifikuar aktualisht në këtë pajisje nuk mund ta aktivizojë korrigjimin përmes Wi-Fi. Për ta përdorur këtë veçori, kalo te përdoruesi parësor."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"Përdoruesi i identifikuar aktualisht në këtë pajisje nuk mund ta aktivizojë korrigjimin përmes Wi-Fi. Për ta përdorur këtë veçori, kalo te përdoruesi administrator."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"Porta e USB-së është çaktivizuar"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"Për të mbrojtur pajisjen tënde nga lëngjet apo papastërtitë, porta e USB-së është çaktivizuar dhe nuk do t\'i dallojë aksesorët.\n\nDo të njoftohesh kur të mos jetë problem përdorimi përsëri i portës USB."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"Porta USB është aktivizuar për të zbuluar karikuesit dhe aksesorët"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Ndihma zanore"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Portofoli"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"Skaneri i kodeve QR"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"Shkyç"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"Pajisja është e kyçur"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Po skanon fytyrën"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Dërgo"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"Fytyra nuk mund të njihet"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Përdor më mirë gjurmën e gishtit"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Pajisja është lidhur me \"bluetooth\"."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"Përqindja e baterisë e panjohur."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"modaliteti i aeroplanit"</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN-ja është aktive."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"Bateria ka edhe <xliff:g id="NUMBER">%d</xliff:g> për qind."</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Bateria <xliff:g id="PERCENTAGE">%1$s</xliff:g> përqind, rreth <xliff:g id="TIME">%2$s</xliff:g> të mbetura bazuar në përdorimin tënd"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Bateria <xliff:g id="PERCENTAGE">%1$d</xliff:g> përqind, rreth <xliff:g id="TIME">%2$s</xliff:g> të mbetura bazuar në përdorimin tënd"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Bateria po karikohet, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"Shiko të gjitha njoftimet"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"Teletajpi është i aktivizuar."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Zile me dridhje."</string>
@@ -386,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Gjatë shpërndarjes, regjistrimit ose transmetimit të një aplikacioni, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ka qasje te çdo gjë e dukshme në ekranin tënd ose që po luhet në atë aplikacion. Prandaj, ki kujdes me fjalëkalimet, detajet e pagesës, mesazhet ose informacione të tjera të ndjeshme."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Vazhdo"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Shpërndaj ose regjistro një aplikacion"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Të lejohet që ky aplikacion të shpërndajë ose të regjistrojë?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Gjatë shpërndarjes, regjistrimit ose transmetimit, ky aplikacion ka qasje te çdo gjë e dukshme në ekranin tënd ose që po luhet në pajisjen tënde. Prandaj ki kujdes me fjalëkalimet, detajet e pagesës, mesazhet ose informacionet e tjera të ndjeshme."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Gjatë shpërndarjes, regjistrimit ose transmetimit, ky aplikacioni ka qasje te çdo gjë e dukshme në ekranin tënd ose që po luhet në atë aplikacion. Prandaj, ki kujdes me fjalëkalimet, detajet e pagesës, mesazhet ose informacionet e tjera të ndjeshme."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"U bllokua nga administratori yt i teknologjisë së informacionit"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"Regjistrimi i ekranit është çaktivizuar nga politika e pajisjes."</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Pastroji të gjitha"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Menaxho"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Historiku"</string>
@@ -511,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Shkyçe për ta përdorur"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Pati një problem me marrjen e kartave të tua. Provo përsëri më vonë"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Cilësimet e ekranit të kyçjes"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"Skano kodin QR"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Profili i punës"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Modaliteti i aeroplanit"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Nuk do ta dëgjosh alarmin e radhës në <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -794,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Zmadho ekranin e plotë"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Zmadho një pjesë të ekranit"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Ndërro"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Lejo lëvizjen diagonale"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Ndrysho përmasat"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"Ndrysho llojin e zmadhimit"</string>
@@ -1024,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"Të lejohet që <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> të ketë qasje te të gjitha evidencat e pajisjes?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"Lejo qasjen vetëm për një herë"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Mos lejo"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"Evidencat e pajisjes regjistrojnë çfarë ndodh në pajisjen tënde. Aplikacionet mund t\'i përdorin këto evidenca për të gjetur dhe rregulluar problemet.\n\nDisa evidenca mund të përmbajnë informacione delikate, ndaj lejo vetëm aplikacionet që u beson të kenë qasje te të gjitha evidencat e pajisjes. \n\nNëse nuk e lejon këtë aplikacion që të ketë qasje te të gjitha evidencat e pajisjes, ai mund të vazhdojë të ketë qasje tek evidencat e tij. Prodhuesi i pajisjes sate mund të jetë ende në gjendje që të ketë qasje te disa evidenca ose informacione në pajisjen tënde."</string>
</resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 6d0c201ae9e3..0d3a80208c14 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"Увек дозволи са овог рачунара"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"Дозволи"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"Отклањање грешака на USB-у није дозвољено"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"Корисник који је тренутно пријављен на овај уређај не може да укључи отклањање грешака на USB-у. Да бисте користили ову функцију, пребаците на примарног корисника."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"Корисник који је тренутно пријављен на овај уређај не може да укључи отклањање грешака са USB-а. Да бисте користили ову функцију, пређите на корисника са администраторским правима."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Да ли желите да промените језик система на <xliff:g id="LANGUAGE">%1$s</xliff:g>?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Други уређај је затражио промену језика система"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Промени језик"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"Увек дозволи на овој мрежи"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"Дозволи"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Бежично отклањање грешака није дозвољено"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"Корисник који је тренутно пријављен на овај уређај не може да укључи бежично отклањање грешака. Да бисте користили ову функцију, пређите на примарног корисника."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"Корисник који је тренутно пријављен на овај уређај не може да укључи бежично отклањање грешака. Да бисте користили ову функцију, пређите на корисника са администраторским правима."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"USB порт је онемогућен"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"Да би се уређај заштитио од течности или нечистоће, USB порт је онемогућен и неће откривати додатну опрему.\n\nОбавестићемо вас када поново будете могли да користите USB порт."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"USB порт је омогућен ради откривања пуњача и додатне опреме"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Гласовна помоћ"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Новчаник"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"Скенер QR кода"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"Откључајте"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"Уређај је закључан"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Скенирање лица"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Пошаљи"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"Лице није препознато"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Користите отисак прста"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth је прикључен."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"Проценат напуњености батерије није познат."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"Режим рада у авиону."</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN је укључен."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"Батерија је на <xliff:g id="NUMBER">%d</xliff:g> посто."</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Батерија је на <xliff:g id="PERCENTAGE">%1$s</xliff:g> посто, преостало време на основу коришћења је <xliff:g id="TIME">%2$s</xliff:g>"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Батерија је на <xliff:g id="PERCENTAGE">%1$d</xliff:g> посто, преостало време на основу коришћења је <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Батерија се пуни, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> посто."</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"Погледајте сва обавештења"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"TeleTypewriter је омогућен."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Вибрација звона."</string>
@@ -305,28 +310,17 @@
<string name="sensor_privacy_mic_unblocked_toast_content" msgid="306555320557065068">"Микрофон је доступан"</string>
<string name="sensor_privacy_camera_unblocked_toast_content" msgid="7843105715964332311">"Камера је доступна"</string>
<string name="sensor_privacy_mic_camera_unblocked_toast_content" msgid="7339355093282661115">"Микрофон и камера су доступни"</string>
- <!-- no translation found for sensor_privacy_mic_turned_on_dialog_title (6348853159838376513) -->
- <skip />
- <!-- no translation found for sensor_privacy_mic_turned_off_dialog_title (5760464281790732849) -->
- <skip />
- <!-- no translation found for sensor_privacy_mic_unblocked_dialog_content (4889961886199270224) -->
- <skip />
- <!-- no translation found for sensor_privacy_mic_blocked_no_exception_dialog_content (5864898470772965394) -->
- <skip />
- <!-- no translation found for sensor_privacy_mic_blocked_with_exception_dialog_content (810289713700437896) -->
- <skip />
- <!-- no translation found for sensor_privacy_camera_turned_on_dialog_title (8039095295100075952) -->
- <skip />
- <!-- no translation found for sensor_privacy_camera_turned_off_dialog_title (1936603903120742696) -->
- <skip />
- <!-- no translation found for sensor_privacy_camera_unblocked_dialog_content (7847190103011782278) -->
- <skip />
- <!-- no translation found for sensor_privacy_camera_blocked_dialog_content (3182428709314874616) -->
- <skip />
- <!-- no translation found for sensor_privacy_htt_blocked_dialog_content (3333321592997666441) -->
- <skip />
- <!-- no translation found for sensor_privacy_dialog_open_settings (1503088305279285048) -->
- <skip />
+ <string name="sensor_privacy_mic_turned_on_dialog_title" msgid="6348853159838376513">"Микрофон је укључен"</string>
+ <string name="sensor_privacy_mic_turned_off_dialog_title" msgid="5760464281790732849">"Микрофон је искључен"</string>
+ <string name="sensor_privacy_mic_unblocked_dialog_content" msgid="4889961886199270224">"Микрофон је омогућен за све апликације и услуге."</string>
+ <string name="sensor_privacy_mic_blocked_no_exception_dialog_content" msgid="5864898470772965394">"Приступ микрофону је онемогућен за све апликације и услуге. Можете да омогућите приступ микрофону у Подешавањима &gt; Приватност &gt; Микрофон."</string>
+ <string name="sensor_privacy_mic_blocked_with_exception_dialog_content" msgid="810289713700437896">"Приступ микрофону је онемогућен за све апликације и услуге. То можете да промените у Подешавањима &gt; Приватност &gt; Микрофон."</string>
+ <string name="sensor_privacy_camera_turned_on_dialog_title" msgid="8039095295100075952">"Камера је укључена"</string>
+ <string name="sensor_privacy_camera_turned_off_dialog_title" msgid="1936603903120742696">"Камера је искључена"</string>
+ <string name="sensor_privacy_camera_unblocked_dialog_content" msgid="7847190103011782278">"Камера је омогућена за све апликације и услуге."</string>
+ <string name="sensor_privacy_camera_blocked_dialog_content" msgid="3182428709314874616">"Приступ камери је онемогућен за све апликације и услуге."</string>
+ <string name="sensor_privacy_htt_blocked_dialog_content" msgid="3333321592997666441">"Да бисте користили дугме микрофона, омогућите приступ микрофону у Подешавањима."</string>
+ <string name="sensor_privacy_dialog_open_settings" msgid="1503088305279285048">"Отвори Подешавања."</string>
<string name="media_seamless_other_device" msgid="4654849800789196737">"Други уређај"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Укључи/искључи преглед"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Неће вас узнемиравати звукови и вибрације осим за аларме, подсетнике, догађаје и позиваоце које наведете. И даље ћете чути све што одаберете да пустите, укључујући музику, видео снимке и игре."</string>
@@ -397,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Када делите, снимате или пребацујете апликацију, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> има приступ комплетном садржају који је видљив или се пушта у тој апликацији. Будите пажљиви са лозинкама, информацијама о плаћању, порукама или другим осетљивим информацијама."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Настави"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Делите или снимите апликацију"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Желите да дозволите овој апликацији да дели или снима?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Када делите, снимате или пребацујете, ова апликација има приступ комплетном садржају који је видљив на екрану или се пушта на уређају. Будите пажљиви са лозинкама, информацијама о плаћању, порукама или другим осетљивим информацијама."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Када делите, снимате или пребацујете апликацију, ова апликација има приступ комплетном садржају који је видљив или се пушта у тој апликацији. Будите пажљиви са лозинкама, информацијама о плаћању, порукама или другим осетљивим информацијама."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Блокира ИТ администратор"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"Снимање екрана је онемогућено смерницама за уређај"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Обриши све"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Управљајте"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Историја"</string>
@@ -522,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Откључај ради коришћења"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Дошло је до проблема при преузимању картица. Пробајте поново касније"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Подешавања закључаног екрана"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"Скенирајте QR кôд"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Пословни профил"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Режим рада у авиону"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Нећете чути следећи аларм у <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -805,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Увећајте цео екран"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Увећајте део екрана"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Пређи"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Дозволи дијагонално скроловање"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Промени величину"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"Промени тип увећања"</string>
@@ -1035,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"ДДД, д. МММ"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"с:мин"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"ч:мин"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"Желите да дозволите да <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> приступа свим евиденцијама уређаја?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"Дозволи једнократан приступ"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Не дозволи"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"Евиденције уређаја региструју шта се дешава на уређају. Апликације могу да користе те евиденције да би пронашле и решиле проблеме.\n\nНеке евиденције могу да садрже осетљиве информације, па приступ свим евиденцијама уређаја треба да дозвољавате само апликацијама у које имате поверења. \n\nАко не дозволите овој апликацији да приступа свим евиденцијама уређаја, она и даље може да приступа сопственим евиденцијама. Произвођач уређаја ће можда и даље моћи да приступа неким евиденцијама или информацијама на уређају."</string>
</resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 2eac10ff82ed..d56167e0149e 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"Tillåt alltid på den här datorn"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"Tillåt"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"USB-felsökning är inte tillåtet"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"Användaren som är inloggad på enheten för närvarande kan inte aktivera USB-felsökning. Byt till den primära användaren om du vill använda den här funktionen."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"Användaren som är inloggad på enheten för närvarande kan inte aktivera USB-felsökning. Byt till administratörsanvändaren om du vill använda den här funktionen."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Vill du ändra systemspråket till <xliff:g id="LANGUAGE">%1$s</xliff:g>?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Ändring av systemspråk har begärts av en annan enhet"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Ändra språk"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"Tillåt alltid i det här nätverket"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"Tillåt"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Trådlös felsökning är inte tillåtet"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"Användaren som är inloggad på enheten för närvarande kan inte aktivera trådlös felsökning. Byt till den primära användaren om du vill använda den här funktionen."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"Användaren som är inloggad på enheten för närvarande kan inte aktivera trådlös felsökning. Byt till administratörsanvändaren om du vill använda den här funktionen."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"USB-porten har inaktiverats"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"USB-porten har inaktiverats för att skydda enheten mot vätska eller smuts. Inga tillbehör kommer att hittas.\n\nDu meddelas när det går att använda USB-porten igen."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"USB-porten har aktiverats för identifiering av laddare och tillbehör"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Röstassistent"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"QR-skanner"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"Lås upp"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"Enheten är låst"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Registrerar ansikte"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Skicka"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"Ansiktet kändes inte igen"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Använd fingeravtryck"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth ansluten."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"Okänd batterinivå."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"Flygplansläge"</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN har aktiverats."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"Batteri <xliff:g id="NUMBER">%d</xliff:g> procent."</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Batteri: <xliff:g id="PERCENTAGE">%1$s</xliff:g> procent, cirka <xliff:g id="TIME">%2$s</xliff:g> kvar utifrån din användning"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Batteri: <xliff:g id="PERCENTAGE">%1$d</xliff:g> procent, cirka <xliff:g id="TIME">%2$s</xliff:g> kvar utifrån din användning"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Batteriet laddas, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> procent."</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"Visa alla aviseringar"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"TeleTypewriter aktiverad."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Vibrerande ringsignal."</string>
@@ -386,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"När du delar, spelar in eller castar en app har <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> åtkomst till allt som visas eller spelas upp i appen. Så var försiktig med lösenord, betalningsuppgifter, meddelanden och andra känsliga uppgifter."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Fortsätt"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Dela eller spela in en app"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Vill du tillåta att den här appen delar eller spelar in?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"När du delar, spelar in eller castar har den här appen åtkomst till allt som visas på skärmen eller spelas upp på enheten. Så var försiktig med lösenord, betalningsuppgifter, meddelanden och andra känsliga uppgifter."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"När du delar, spelar in eller castar en app har den här appen åtkomst till allt som visas eller spelas upp i appen. Så var försiktig med lösenord, betalningsuppgifter, meddelanden och andra känsliga uppgifter."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Blockeras av IT-administratören"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"Skärminspelning är inaktiverat av enhetspolicyn"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Rensa alla"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Hantera"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Historik"</string>
@@ -511,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Lås upp för att använda"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Det gick inte att hämta dina kort. Försök igen senare."</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Inställningar för låsskärm"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"Skanna QR-kod"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Jobbprofil"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Flygplansläge"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Nästa alarm, kl. <xliff:g id="WHEN">%1$s</xliff:g>, kommer inte att höras"</string>
@@ -794,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Förstora hela skärmen"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Förstora en del av skärmen"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Reglage"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Tillåt diagonal scrollning"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Ändra storlek"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"Ändra förstoringstyp"</string>
@@ -1024,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h.mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk.mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"Vill du tillåta att <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> får åtkomst till alla enhetsloggar?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"Tillåt engångsåtkomst"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Tillåt inte"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"I enhetsloggar registreras vad som händer på enheten. Appar kan använda dessa loggar för att hitta och åtgärda problem.\n\nVissa loggar kan innehålla känsliga uppgifter, så du ska bara bevilja appar du litar på åtkomst till alla enhetsloggar. \n\nEn app har åtkomst till sina egna loggar även om du inte ger den åtkomst till alla enhetsloggar. Enhetens tillverkare kan fortfarande ha åtkomst till vissa loggar eller viss information på enheten."</string>
</resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 47fbdc43da30..c28244ab7383 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"Ruhusu kutoka kwenye kompyuta hii kila wakati"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"Ruhusu"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"Utatuzi wa USB hauruhusiwi"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"Mtumiaji aliyeingia katika akaunti kwa kutumia kifaa hiki kwa sasa hawezi kuwasha utatuzi wa USB. Ili utumie kipengele hiki, tumia akaunti ya mtumiaji wa msingi."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"Mtumiaji aliyeingia katika akaunti kwenye kifaa hiki kwa sasa hawezi kuwasha utatuzi wa USB. Ili utumie kipengele hiki, tumia akaunti ya mtumiaji msimamizi."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Ungependa kubadilisha lugha ya mfumo kuwa <xliff:g id="LANGUAGE">%1$s</xliff:g>?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Mabadiliko ya lugha ya mfumo yameombwa na kifaa kingine"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Badilisha lugha"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"Ruhusu kila wakati kwenye mtandao huu"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"Ruhusu"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Utatuzi usiotumia waya hauruhusiwi"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"Mtumiaji aliyeingia katika akaunti kwenye kifaa hiki kwa sasa hawezi kuwasha utatuzi usiotumia waya. Ili utumie kipengele hiki, badilisha utumie akaunti ya mtumiaji wa msingi."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"Mtumiaji aliyeingia katika akaunti kwenye kifaa hiki kwa sasa hawezi kuwasha utatuzi usiotumia waya. Ili utumie kipengele hiki, badilisha utumie akaunti ya mtumiaji msimamizi."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"Mlango wa USB umezimwa"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"Ili ulinde kifaa chako dhidi ya vitu vyenye unyevu au uchafu, mlango wa USB umezimwa na hautatambua vifaa vyovyote.\n\nUtaarifiwa itapokuwa sawa kutumia mlango wa USB tena."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"Mlango wa USB umewezeshwa ili utambue chaja na vifuasi"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Mapendekezo ya Sauti"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Pochi"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"Kichanganuzi cha Msimbo wa QR"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"Fungua"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"Kifaa kimefungwa"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Inachanganua uso"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Tuma"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"Imeshindwa kutambua uso"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Badala yake, tumia alama ya kidole"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth imeunganishwa."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"Asilimia ya betri haijulikani."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"Hali ya ndegeni."</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN imewashwa."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"Asilimia <xliff:g id="NUMBER">%d</xliff:g> ya betri"</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Betri ina asilimia <xliff:g id="PERCENTAGE">%1$s</xliff:g>, zimesalia takribani <xliff:g id="TIME">%2$s</xliff:g> kulingana na jinsi unavyoitumia"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Betri ina asilimia <xliff:g id="PERCENTAGE">%1$d</xliff:g>, zimesalia takribani <xliff:g id="TIME">%2$s</xliff:g> kulingana na jinsi unavyoitumia"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Betri inachaji, asilimia <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>."</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"Angalia arifa zote"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"Kichapishaji cha Tele kimewezeshwa."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Mtetemo wa mlio"</string>
@@ -386,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Unapotuma, kurekodi au kushiriki programu, programu ya <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> inaweza kufikia kitu chochote kitakachoonekana au kuchezwa kwenye programu hiyo. Hivyo kuwa mwangalifu na manenosiri, maelezo ya malipo, ujumbe au maelezo mengine nyeti."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Endelea"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Shiriki au rekodi programu"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Ungependa kuruhusu programu hii ishiriki au irekodi?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Unapotuma, kurekodi au kushiriki, programu hii inaweza kufikia kitu chochote kitakachoonekana kwenye skrini yako au kuchezwa kwenye kifaa chako. Hivyo kuwa mwangalifu na manenosiri, maelezo ya malipo, ujumbe au maelezo mengine nyeti."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Unapotuma, kurekodi au kushiriki programu, programu hii inaweza kufikia kitu chochote kitakachoonekana au kuchezwa kwenye programu hiyo. Hivyo kuwa mwangalifu na manenosiri, maelezo ya malipo, ujumbe au maelezo mengine nyeti."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Umezuiwa na msimamizi wako wa TEHAMA"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"Mchakato wa kurekodi skrini umezimwa na sera ya kifaa"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Futa zote"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Dhibiti"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Historia"</string>
@@ -511,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Fungua ili utumie"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Hitilafu imetokea wakati wa kuleta kadi zako, tafadhali jaribu tena baadaye"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Mipangilio ya kufunga skrini"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"Changanua msimbo wa QR"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Wasifu wa kazini"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Hali ya ndegeni"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Hutasikia kengele yako inayofuata ya saa <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -794,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Kuza skrini nzima"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Kuza sehemu ya skrini"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Swichi"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Ruhusu usogezaji wa kimshazari"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Badilisha ukubwa"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"Badili aina ya ukuzaji"</string>
@@ -1024,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"saa:dk"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:dk"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"Ungependa kuruhusu <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> ifikie kumbukumbu zote za kifaa?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"Ruhusu ufikiaji wa mara moja"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Usiruhusu"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"Kumbukumbu za kifaa hurekodi kinachofanyika kwenye kifaa chako. Programu zinaweza kutumia kumbukumbu hizi ili kutambua na kurekebisha hitilafu.\n\nHuenda baadhi ya kumbukumbu zikawa na taarifa nyeti, hivyo ruhusu tu programu unazoziamini kufikia kumbukumbu zote za kifaa. \n\nIwapo hutaruhusu programu hii ifikie kumbukumbu zote za kifaa, bado inaweza kufikia kumbukumbu zake yenyewe. Huenda mtengenezaji wa kifaa chako bado akaweza kufikia baadhi ya kumbukumbu au taarifa zilizopo kwenye kifaa chako."</string>
</resources>
diff --git a/packages/SystemUI/res/values-sw600dp-land/dimens.xml b/packages/SystemUI/res/values-sw600dp-land/dimens.xml
index b24ce122208f..6c7cab51f440 100644
--- a/packages/SystemUI/res/values-sw600dp-land/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp-land/dimens.xml
@@ -24,6 +24,7 @@
<!-- margin from keyguard status bar to clock. For split shade it should be
keyguard_split_shade_top_margin - status_bar_header_height_keyguard = 8dp -->
<dimen name="keyguard_clock_top_margin">8dp</dimen>
+ <dimen name="keyguard_smartspace_top_offset">0dp</dimen>
<!-- QS-->
<dimen name="qs_panel_padding_top">16dp</dimen>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index f836e9521baa..ccf7b6b61872 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"இந்தக் கணினியிலிருந்து எப்போதும் அனுமதி"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"அனுமதி"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"USB பிழைதிருத்தம் அனுமதிக்கப்படவில்லை"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"தற்போது இந்தச் சாதனத்தில் உள்நுழைந்துள்ள பயனரால் USB பிழைதிருத்தத்தை இயக்க முடியாது. இந்த அம்சத்தை இயக்க, முதன்மைப் பயனருக்கு மாறவும்."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"தற்போது இந்தச் சாதனத்தில் உள்நுழைந்துள்ள பயனரால் USB பிழைதிருத்தத்தை இயக்க முடியாது. இந்த அம்சத்தைப் பயன்படுத்த நிர்வாகப் பயனராக உள்நுழையவும்."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"சிஸ்டம் மொழியை <xliff:g id="LANGUAGE">%1$s</xliff:g> மொழிக்கு மாற்ற விரும்புகிறீர்களா?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"சிஸ்டம் மொழியை மாற்றும்படி வேறொரு சாதனம் கோருகிறது"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"மொழியை மாற்று"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"இந்த நெட்வொர்க்கில் எப்போதும் அனுமதி"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"அனுமதி"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"வைஃபை பிழைதிருத்தம் அனுமதிக்கப்படவில்லை"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"தற்போது இந்தச் சாதனத்தில் உள்நுழைந்துள்ள பயனரால் வைஃபை பிழைதிருத்தத்தை இயக்க முடியாது. இந்த அம்சத்தை இயக்க முதன்மைப் பயனருக்கு மாறவும்."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"தற்போது இந்தச் சாதனத்தில் உள்நுழைந்துள்ள பயனரால் வைஃபை பிழைதிருத்தத்தை இயக்க முடியாது. இந்த அம்சத்தைப் பயன்படுத்த நிர்வாகப் பயனராக உள்நுழையவும்."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"USB போர்ட் முடக்கப்பட்டது"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"தேவையற்றவையில் இருந்து உங்கள் சாதனத்தைப் பாதுகாக்க USB போர்ட் முடக்கப்பட்டுள்ளது. மேலும் எந்தத் துணைக் கருவிகளையும் அது கண்டறியாது.\n\nUSB போர்ட்டை மீண்டும் எப்போது பயன்படுத்தலாம் என்பதைப் பற்றி உங்களுக்குத் தெரிவிக்கப்படும்."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"சார்ஜர்களையும் துணைக்கருவிகளையும் கண்டறிவதற்காக USB போர்ட் இயக்கப்பட்டுள்ளது"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"குரல் உதவி"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"QR குறியீடு ஸ்கேனர்"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"அன்லாக் செய்"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"சாதனம் பூட்டப்பட்டுள்ளது"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"முகத்தை ஸ்கேன் செய்கிறது"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"அனுப்பு"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"முகத்தை கண்டறிய இயலவில்லை"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"கைரேகையை உபயோகிக்கவும்"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"புளூடூத் இணைக்கப்பட்டது."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"பேட்டரி சதவீதம் தெரியவில்லை."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"விமானப் பயன்முறை."</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN இயக்கத்தில் உள்ளது."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"பேட்டரி சக்தி <xliff:g id="NUMBER">%d</xliff:g> சதவிகிதம் உள்ளது."</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"பேட்டரி: <xliff:g id="PERCENTAGE">%1$s</xliff:g> சதவீதம், உபயோகத்தின் அடிப்படையில் <xliff:g id="TIME">%2$s</xliff:g> மீதமுள்ளது"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"பேட்டரி: <xliff:g id="PERCENTAGE">%1$d</xliff:g> சதவீதம், உபயோகத்தின் அடிப்படையில் <xliff:g id="TIME">%2$s</xliff:g> மீதமுள்ளது"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"பேட்டரி சார்ஜ் ஆகிறது, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> சதவீதம் உள்ளது."</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"எல்லா அறிவிப்புகளையும் காட்டும்"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"TeleTypewriter இயக்கப்பட்டது."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"ரிங்கர் அதிர்வு."</string>
@@ -386,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"ஓர் ஆப்ஸை நீங்கள் பகிரும்போதோ ரெக்கார்டு செய்யும்போதோ அலைபரப்பும்போதோ அந்த ஆப்ஸில் காட்டப்படும் அல்லது பிளே செய்யப்படும் அனைத்தையும் <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ஆப்ஸால் அணுக முடியும். எனவே கடவுச்சொற்கள், பேமெண்ட் விவரங்கள், மெசேஜ்கள், பிற பாதுகாக்கப்பட வேண்டிய தகவல்கள் ஆகியவை குறித்து கவனத்துடன் இருங்கள்."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"தொடர்க"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"ஆப்ஸைப் பகிர்தல் அல்லது ரெக்கார்டு செய்தல்"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"பகிர்வதற்கோ ரெக்கார்டு செய்வதற்கோ இந்த ஆப்ஸை அனுமதிக்கவா?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"நீங்கள் பகிரும்போதோ ரெக்கார்டு செய்யும்போதோ அலைபரப்பும்போதோ திரையில் காட்டப்படும்/சாதனத்தில் பிளே செய்யப்படும் அனைத்தையும் இந்த ஆப்ஸால் அணுக முடியும். எனவே கடவுச்சொற்கள், பேமெண்ட் விவரங்கள், மெசேஜ்கள் அல்லது பாதுகாக்கப்பட வேண்டிய பிற தகவல்கள் குறித்துக் கவனமாக இருங்கள்."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"ஓர் ஆப்ஸை நீங்கள் பகிரும்போதோ ரெக்கார்டு செய்யும்போதோ அலைபரப்பும்போதோ அதில் காட்டப்படும்/பிளே செய்யப்படும் அனைத்தையும் இந்த ஆப்ஸால் அணுக முடியும். எனவே கடவுச்சொற்கள், பேமெண்ட் விவரங்கள், மெசேஜ்கள் அல்லது பாதுகாக்கப்பட வேண்டிய பிற தகவல்கள் குறித்துக் கவனமாக இருங்கள்."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"உங்கள் IT நிர்வாகி தடுத்துள்ளார்"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"\'திரையைப் படமெடுத்தல்\' சாதனக் கொள்கையின்படி முடக்கப்பட்டுள்ளது"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"எல்லாவற்றையும் அழி"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"நிர்வகி"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"இதுவரை வந்த அறிவிப்புகள்"</string>
@@ -511,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"பயன்படுத்துவதற்கு அன்லாக் செய்க"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"உங்கள் கார்டுகளின் விவரங்களைப் பெறுவதில் சிக்கல் ஏற்பட்டது, பிறகு முயலவும்"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"பூட்டுத் திரை அமைப்புகள்"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"QR குறியீட்டை ஸ்கேன் செய்தல்"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"பணிக் கணக்கு"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"விமானப் பயன்முறை"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"அடுத்த அலாரத்தை <xliff:g id="WHEN">%1$s</xliff:g> மணிக்கு கேட்க மாட்டீர்கள்"</string>
@@ -794,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"முழுத்திரையைப் பெரிதாக்கும்"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"திரையின் ஒரு பகுதியைப் பெரிதாக்கும்"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"ஸ்விட்ச்"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"குறுக்கே ஸ்க்ரோல் செய்வதை அனுமதி"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"அளவை மாற்று"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"பெரிதாக்கல் வகையை மாற்று"</string>
@@ -1024,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"சாதனப் பதிவுகள் அனைத்தையும் <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> அணுக அனுமதிக்கவா?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"ஒருமுறை அணுகலை அனுமதி"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"அனுமதிக்க வேண்டாம்"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"உங்கள் சாதனத்தில் நடப்பவற்றைச் சாதனப் பதிவுகள் ரெக்கார்டு செய்யும். சிக்கல்களைக் கண்டறிந்து சரிசெய்ய ஆப்ஸ் இந்தப் பதிவுகளைப் பயன்படுத்தலாம்.\n\nபாதுகாக்க வேண்டிய தகவல்கள் சில பதிவுகளில் இருக்கக்கூடும் என்பதால் சாதனப் பதிவுகள் அனைத்தையும் அணுக நீங்கள் நம்பும் ஆப்ஸை மட்டுமே அனுமதிக்கவும். \n\nசாதனப் பதிவுகள் அனைத்தையும் அணுக இந்த ஆப்ஸை நீங்கள் அனுமதிக்கவில்லை என்றாலும் அதற்குச் சொந்தமான பதிவுகளை அதனால் அணுக முடியும். உங்கள் சாதனத்திலுள்ள சில பதிவுகளையோ தகவல்களையோ சாதன உற்பத்தியாளரால் தொடர்ந்து அணுக முடியும்."</string>
</resources>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 002a4b24f726..98a8e37c73e4 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"ఈ కంప్యూటర్ నుండి ఎల్లప్పుడూ అనుమతించండి"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"అనుమతించండి"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"USB డీబగ్గింగ్‌కి అనుమతి లేదు"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"ఈ పరికరానికి ప్రస్తుతం సైన్ ఇన్ చేసిన వినియోగదారు USB డీబగ్గింగ్ ఆన్ చేయలేరు. ఈ ఫీచర్ ఉపయోగించడానికి, ప్రాథమిక వినియోగదారుకి మారాలి."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"ఈ పరికరానికి ప్రస్తుతం సైన్ ఇన్ చేసిన యూజర్ USB డీబగ్గింగ్ ఆన్ చేయలేరు. ఈ ఫీచర్ ఉపయోగించడానికి, అడ్మిన్ యూజర్‌కు స్విచ్ అవ్వండి."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"మీరు సిస్టమ్ భాషను <xliff:g id="LANGUAGE">%1$s</xliff:g> భాషకు మార్చాలనుకుంటున్నారా?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"మరొక పరికరం ద్వారా సిస్టమ్ భాష మార్పు రిక్వెస్ట్ చేయబడింది"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"భాషను మార్చండి"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"ఈ నెట్‌వర్క్ నుండి ఎల్లప్పుడూ అనుమతించండి"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"అనుమతించండి"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"వైర్‌లెస్ డీబగ్గింగ్‌కి అనుమతి లేదు"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"ఈ పరికరానికి ప్రస్తుతం సైన్ ఇన్ చేసిన యూజర్, వైర్‌లెస్ డీబగ్గింగ్ ఆన్ చేయలేరు. ఈ ఫీచర్ ఉపయోగించడానికి, ప్రాథమిక యూజర్ కి స్విచ్ అవ్వండి."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"ఈ పరికరానికి ప్రస్తుతం సైన్ ఇన్ చేసిన యూజర్, వైర్‌లెస్ డీబగ్గింగ్ ఆన్ చేయలేరు. ఈ ఫీచర్ ఉపయోగించడానికి, అడ్మిన్ యూజర్‌కు స్విచ్ అవ్వండి."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"USB పోర్ట్‌ నిలిపివేయబడింది"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"మీ పరికరంలోకి నీరు లేదా చెత్తాచెదారం చేరిపోకుండా కాపాడటానికి, USB పోర్ట్ నిలిపివేయబడుతుంది, అలాగే యాక్సెసరీలు వేటిని గుర్తించదు.\n\nUSB పోర్ట్‌ను ఉపయోగించడం సురక్షితమేనని నిర్ధారించుకున్న తర్వాత, మళ్లీ మీకో నోటిఫికేషన్‌ రూపంలో తెలియజేయబడుతుంది."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"ఛార్జర్‌లు, యాక్సెసరీలను గుర్తించే విధంగా USB పోర్ట్ ప్రారంభించబడింది"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"వాయిస్ అసిస్టెంట్"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"QR కోడ్ స్కానర్"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"అన్‌లాక్ చేయి"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"పరికరం లాక్ చేయబడింది"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"ముఖాన్ని స్కాన్ చేస్తోంది"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"పంపు"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"ముఖం గుర్తించడం కుదరలేదు"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"బదులుగా వేలిముద్రను ఉపయోగించండి"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"బ్లూటూత్ కనెక్ట్ చేయబడింది."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"బ్యాటరీ శాతం తెలియదు."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"ఎయిర్‌ప్లేన్ మోడ్."</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPNలో."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"బ్యాటరీ <xliff:g id="NUMBER">%d</xliff:g> శాతం."</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"బ్యాటరీ <xliff:g id="PERCENTAGE">%1$s</xliff:g> శాతం ఉంది, మీ వినియోగాన్ని బట్టి <xliff:g id="TIME">%2$s</xliff:g> పని చేస్తుంది"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"బ్యాటరీ <xliff:g id="PERCENTAGE">%1$d</xliff:g> శాతం ఉంది, మీ వినియోగాన్ని బట్టి <xliff:g id="TIME">%2$s</xliff:g> పని చేస్తుంది"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"బ్యాటరీ ఛార్జ్ అవుతోంది, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> శాతం వద్ద ఉంది."</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"అన్ని నోటిఫికేషన్‌లను చూడండి"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"టెలిటైప్‌రైటర్ ప్రారంభించబడింది."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"రింగర్ వైబ్రేట్‌లో ఉంది."</string>
@@ -386,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"మీరు ఏదైనా యాప్‌ను షేర్ చేస్తున్నప్పుడు, రికార్డ్ చేస్తున్నప్పుడు, లేదా ప్రసారం చేస్తున్నప్పుడు, ఆ యాప్‌లో చూపబడిన దేనికైనా లేదా ప్లే అయిన దేనికైనా <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>‌కు యాక్సెస్ ఉంటుంది. కాబట్టి, పాస్‌వర్డ్‌లు, పేమెంట్ వివరాలు, మెసేజ్‌లు, లేదా ఏదైనా ఇతర సున్నితమైన సమాచారం పట్ల జాగ్రత్త వహించండి."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"కొనసాగించండి"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"యాప్‌ను షేర్ చేయండి లేదా రికార్డ్ చేయండి"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"షేర్ చేయడానికి లేదా రికార్డ్ చేయడానికి ఈ యాప్‌ను అనుమతించాలా?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"మీరు షేర్ చేస్తున్నప్పుడు, రికార్డ్ చేస్తున్నప్పుడు, లేదా ప్రసారం చేస్తున్నప్పుడు, ఈ యాప్ మీ స్క్రీన్‌పై కనిపించే దేనికైనా లేదా మీ పరికరంలో ప్లే అయిన దేనికైనా యాక్సెస్‌ను కలిగి ఉంటుంది. కాబట్టి, పాస్‌వర్డ్‌లు, పేమెంట్ వివరాలు, మెసేజ్‌లు, లేదా ఏదైనా ఇతర సున్నితమైన సమాచారం పట్ల జాగ్రత్త వహించండి."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"మీరు ఏదైనా యాప్‌ను షేర్ చేస్తున్నప్పుడు, రికార్డ్ చేస్తున్నప్పుడు, లేదా ప్రసారం చేస్తున్నప్పుడు, ఆ యాప్‌లో చూపబడిన దేనికైనా లేదా ప్లే అయిన దేనికైనా ఈ యాప్ యాక్సెస్‌ను కలిగి ఉంటుంది. కాబట్టి, పాస్‌వర్డ్‌లు, పేమెంట్ వివరాలు, మెసేజ్‌లు, లేదా ఏదైనా ఇతర సున్నితమైన సమాచారం పట్ల జాగ్రత్త వహించండి."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"మీ IT అడ్మిన్ ద్వారా బ్లాక్ చేయబడింది"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"పరికర పాలసీ ద్వారా స్క్రీన్ క్యాప్చర్ చేయడం డిజేబుల్ చేయబడింది"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"అన్నీ క్లియర్ చేయండి"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"మేనేజ్ చేయండి"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"హిస్టరీ"</string>
@@ -511,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"ఉపయోగించడానికి అన్‌లాక్ చేయండి"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"మీ కార్డ్‌లను పొందడంలో సమస్య ఉంది, దయచేసి తర్వాత మళ్లీ ట్రై చేయండి"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"లాక్ స్క్రీన్ సెట్టింగ్‌లు"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"QR కోడ్‌ను స్కాన్ చేయండి"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"ఆఫీస్ ప్రొఫైల్‌"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"ఎయిర్‌ప్లేన్ మోడ్"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"మీరు <xliff:g id="WHEN">%1$s</xliff:g> సెట్ చేసిన మీ తర్వాత అలారం మీకు వినిపించదు"</string>
@@ -794,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"ఫుల్ స్క్రీన్‌ను మ్యాగ్నిఫై చేయండి"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"స్క్రీన్‌లో భాగాన్ని మ్యాగ్నిఫై చేయండి"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"స్విచ్ చేయి"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"వికర్ణ స్క్రోలింగ్‌ను అనుమతించండి"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"సైజ్ మార్చండి"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"మ్యాగ్నిఫికేషన్ రకాన్ని మార్చండి"</string>
@@ -1024,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"అన్ని పరికర లాగ్‌లను యాక్సెస్ చేయడానికి <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g>‌ను అనుమతించాలా?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"వన్-టైమ్ యాక్సెస్‌ను అనుమతించండి"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"అనుమతించవద్దు"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"మీ పరికరంలో జరిగే దాన్ని పరికర లాగ్‌లు రికార్డ్ చేస్తాయి. సమస్యలను కనుగొని, పరిష్కరించడానికి యాప్‌లు ఈ లాగ్‌లను ఉపయోగిస్తాయి.\n\nకొన్ని లాగ్‌లలో గోప్యమైన సమాచారం ఉండవచ్చు, కాబట్టి మీరు విశ్వసించే యాప్‌లను మాత్రమే అన్ని పరికర లాగ్‌లను యాక్సెస్ చేయడానికి అనుమతించండి. \n\nఅన్ని పరికర లాగ్‌లను యాక్సెస్ చేయడానికి మీరు ఈ యాప్‌ను అనుమతించకపోతే, అది తన స్వంత లాగ్‌లను ఇప్పటికి యాక్సెస్ చేయగలదు. మీ పరికర తయారీదారు ఇప్పటికీ మీ పరికరంలో కొన్ని లాగ్‌లు లేదా సమాచారాన్ని యాక్సెస్ చేయగలరు."</string>
</resources>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index fa8118e2c0c7..567e17d9bd2c 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"อนุญาตจากคอมพิวเตอร์เครื่องนี้เสมอ"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"อนุญาต"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"ไม่อนุญาตให้แก้ไขข้อบกพร่องผ่าน USB"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"ผู้ใช้ที่ลงชื่อเข้าใช้อุปกรณ์อยู่ในขณะนี้ไม่สามารถเปิดการแก้ไขข้อบกพร่องผ่าน USB ได้ หากต้องการใช้ฟีเจอร์นี้ ให้เปลี่ยนไปเป็นผู้ใช้หลัก"</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"ผู้ใช้ที่ลงชื่อเข้าใช้อุปกรณ์อยู่ในขณะนี้เปิดการแก้ไขข้อบกพร่อง USB ไม่ได้ โปรดเปลี่ยนไปเป็นผู้ใช้ที่ดูแลระบบเพื่อใช้ฟีเจอร์นี้"</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"คุณต้องการเปลี่ยนภาษาของระบบเป็นภาษา<xliff:g id="LANGUAGE">%1$s</xliff:g>ใช่ไหม"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"คำขอเปลี่ยนภาษาของระบบโดยอุปกรณ์อื่น"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"เปลี่ยนภาษา"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"อนุญาตเสมอในเครือข่ายนี้"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"อนุญาต"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"ไม่อนุญาตให้แก้ไขข้อบกพร่องผ่าน Wi-Fi"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"ผู้ใช้ที่ลงชื่อเข้าใช้อุปกรณ์อยู่ในขณะนี้เปิดการแก้ไขข้อบกพร่องผ่าน Wi-Fi ไม่ได้ โปรดเปลี่ยนไปเป็นผู้ใช้หลักเพื่อใช้ฟีเจอร์นี้"</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"ผู้ใช้ที่ลงชื่อเข้าใช้อุปกรณ์อยู่ในขณะนี้เปิดการแก้ไขข้อบกพร่องผ่าน Wi-Fi ไม่ได้ โปรดเปลี่ยนไปเป็นผู้ใช้ที่ดูแลระบบเพื่อใช้ฟีเจอร์นี้"</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"พอร์ต USB ถูกปิดใช้"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"พอร์ต USB ปิดใช้อยู่และจะไม่ตรวจหาอุปกรณ์เสริมใดๆ เพื่อปกป้องอุปกรณ์จากของเหลวและฝุ่นละออง \n\nคุณจะได้รับแจ้งเมื่อใช้พอร์ต USB ได้อีกครั้ง"</string>
<string name="usb_port_enabled" msgid="531823867664717018">"เปิดใช้พอร์ต USB แล้วเพื่อตรวจหาที่ชาร์จและอุปกรณ์เสริม"</string>
@@ -125,7 +125,7 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"ตัวช่วยเสียง"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"เครื่องมือสแกนคิวอาร์โค้ด"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"ปลดล็อก"</string>
+ <string name="accessibility_unlock_button" msgid="3613812140816244310">"ปลดล็อกแล้ว"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"อุปกรณ์ถูกล็อก"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"กำลังสแกนใบหน้า"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"ส่ง"</string>
@@ -168,7 +168,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"ไม่รู้จักใบหน้า"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"ใช้ลายนิ้วมือแทน"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"เชื่อมต่อบลูทูธแล้ว"</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"ไม่ทราบเปอร์เซ็นต์แบตเตอรี่"</string>
@@ -180,8 +180,10 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"โหมดบนเครื่องบิน"</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN เปิดอยู่"</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"แบตเตอรี่ <xliff:g id="NUMBER">%d</xliff:g> เปอร์เซ็นต์"</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"แบตเตอรี่ <xliff:g id="PERCENTAGE">%1$s</xliff:g> เปอร์เซ็นต์ ใช้ได้อีกประมาณ <xliff:g id="TIME">%2$s</xliff:g> ทั้งนี้ขึ้นอยู่กับการใช้งานของคุณ"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"แบตเตอรี่ <xliff:g id="PERCENTAGE">%1$d</xliff:g> เปอร์เซ็นต์ ใช้ได้อีกประมาณ <xliff:g id="TIME">%2$s</xliff:g> ทั้งนี้ขึ้นอยู่กับการใช้งานของคุณ"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"กำลังชาร์จแบตเตอรี่ <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> เปอร์เซ็นต์"</string>
+ <string name="accessibility_battery_level_charging_paused" msgid="1716051308782906917">"แบตเตอรี่ <xliff:g id="PERCENTAGE">%d</xliff:g> เปอร์เซ็นต์ หยุดชาร์จชั่วคราวเพื่อยืดอายุแบตเตอรี่"</string>
+ <string name="accessibility_battery_level_charging_paused_with_estimate" msgid="4006089349465741762">"แบตเตอรี่ <xliff:g id="PERCENTAGE">%1$d</xliff:g> เปอร์เซ็นต์ ใช้ได้<xliff:g id="TIME">%2$s</xliff:g> ทั้งนี้ขึ้นอยู่กับการใช้งานของคุณ หยุดชาร์จชั่วคราวเพื่อยืดอายุแบตเตอรี่"</string>
<string name="accessibility_overflow_action" msgid="8555835828182509104">"ดูการแจ้งเตือนทั้งหมด"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"เปิดใช้งาน TeleTypewriter อยู่"</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"เสียงเรียกเข้าแบบสั่น"</string>
@@ -386,16 +388,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"เมื่อกำลังแชร์ บันทึก หรือแคสต์แอป \"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>\" จะมีสิทธิ์เข้าถึงทุกสิ่งที่แสดงหรือเล่นอยู่ในแอปดังกล่าว ดังนั้นโปรดระวังเกี่ยวกับรหัสผ่าน รายละเอียดการชำระเงิน ข้อความ หรือข้อมูลที่ละเอียดอ่อนอื่นๆ"</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"ต่อไป"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"แชร์หรือบันทึกแอป"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"อนุญาตให้แอปนี้แชร์หรือบันทึกไหม"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"เมื่อกำลังแชร์ บันทึก หรือแคสต์ แอปนี้จะมีสิทธิ์เข้าถึงทุกสิ่งที่ปรากฏบนหน้าจอหรือเล่นอยู่ในอุปกรณ์ ดังนั้นโปรดระวังเกี่ยวกับรหัสผ่าน รายละเอียดการชำระเงิน ข้อความ หรือข้อมูลที่ละเอียดอ่อนอื่นๆ"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"เมื่อกำลังแชร์ บันทึก หรือแคสต์แอป แอปนี้จะมีสิทธิ์เข้าถึงทุกสิ่งที่แสดงหรือเล่นอยู่ในแอปดังกล่าว ดังนั้นโปรดระวังเกี่ยวกับรหัสผ่าน รายละเอียดการชำระเงิน ข้อความ หรือข้อมูลที่ละเอียดอ่อนอื่นๆ"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"ผู้ดูแลระบบไอทีบล็อกไว้"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"การจับภาพหน้าจอปิดใช้โดยนโยบายด้านอุปกรณ์"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"ล้างทั้งหมด"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"จัดการ"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"ประวัติ"</string>
@@ -511,7 +508,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"ปลดล็อกเพื่อใช้"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"เกิดปัญหาในการดึงข้อมูลบัตรของคุณ โปรดลองอีกครั้งในภายหลัง"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"การตั้งค่าหน้าจอล็อก"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"สแกนคิวอาร์โค้ด"</string>
+ <string name="qr_code_scanner_title" msgid="1938155688725760702">"เครื่องมือสแกนคิวอาร์โค้ด"</string>
<string name="status_bar_work" msgid="5238641949837091056">"โปรไฟล์งาน"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"โหมดบนเครื่องบิน"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"คุณจะไม่ได้ยินเสียงปลุกครั้งถัดไปในเวลา <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -794,6 +791,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"ขยายเป็นเต็มหน้าจอ"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"ขยายบางส่วนของหน้าจอ"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"เปลี่ยน"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"อนุญาตการเลื่อนแบบทแยงมุม"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"ปรับขนาด"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"เปลี่ยนประเภทการขยาย"</string>
@@ -1024,4 +1023,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE d MMM"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"HH:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"อนุญาตให้ \"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g>\" เข้าถึงบันทึกทั้งหมดของอุปกรณ์ไหม"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"อนุญาตสิทธิ์เข้าถึงแบบครั้งเดียว"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"ไม่อนุญาต"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"บันทึกของอุปกรณ์เก็บข้อมูลสิ่งที่เกิดขึ้นในอุปกรณ์ แอปสามารถใช้บันทึกเหล่านี้เพื่อค้นหาและแก้ไขปัญหา\n\nบันทึกบางรายการอาจมีข้อมูลที่ละเอียดอ่อน คุณจึงควรอนุญาตเฉพาะแอปที่เชื่อถือได้ให้เข้าถึงบันทึกทั้งหมดของอุปกรณ์ \n\nหากคุณไม่อนุญาตให้แอปนี้เข้าถึงบันทึกทั้งหมดของอุปกรณ์ แอปจะยังเข้าถึงบันทึกของตัวเองได้อยู่ ผู้ผลิตอุปกรณ์อาจยังเข้าถึงบันทึกหรือข้อมูลบางรายการในอุปกรณ์ของคุณได้"</string>
</resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 1451ab9308ed..f11d0ec34a79 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"Palaging payagan mula sa computer na ito"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"Payagan"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"Hindi pinapayagan ang pagde-debug sa pamamagitan ng USB"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"Hindi mao-on ng user na kasalukuyang naka-sign in sa device na ito ang pag-debug ng USB. Upang magamit ang feature na ito, lumipat sa pangunahing user."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"Hindi mao-on ng user na kasalukuyang naka-sign in sa device na ito ang pag-debug ng USB. Para magamit ang feature na ito, lumipat sa admin user."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Gusto mo bang gawing <xliff:g id="LANGUAGE">%1$s</xliff:g> ang wika ng system?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Hiniling ng ibang device na palitan ang wika ng system"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Palitan ang wika"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"Palaging payagan sa network na ito"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"Payagan"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Hindi pinapayagan ang wireless na pag-debug"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"Hindi mao-on ng user na kasalukuyang naka-sign in sa device na ito ang wireless na pag-debug. Para magamit ang feature na ito, lumipat sa pangunahing user."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"Hindi mao-on ng user na kasalukuyang naka-sign in sa device na ito ang wireless na pag-debug. Para magamit ang feature na ito, lumipat sa admin user."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"Na-disable ang USB port"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"Para protektahan ang iyong device sa likido o dumi, na-disable ang USB port at hindi ito makaka-detect ng anumang accessory.\n\nAabisuhan ka kapag ayos nang gamitin ulit ang USB port."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"Na-enable ang USB port para ma-detect ang mga charger at accessory"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Voice Assist"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"Scanner ng QR Code"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"I-unlock"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"Naka-lock ang device"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Sina-scan ang mukha"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Ipadala"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"Hindi makilala ang mukha"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Gumamit ng fingerprint"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Nakakonekta ang Bluetooth."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"Hindi alam ang porsyento ng baterya."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"Mode na eroplano."</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"Naka-on ang VPN."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"Baterya <xliff:g id="NUMBER">%d</xliff:g> (na) porsyento."</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> (na) porsyento ang baterya, nasa <xliff:g id="TIME">%2$s</xliff:g> ang natitira batay sa paggamit mo"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> (na) porsyento ang baterya, nasa <xliff:g id="TIME">%2$s</xliff:g> ang natitira batay sa paggamit mo"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Nagcha-charge ang baterya, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> (na) porsyento."</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"Tingnan ang lahat ng notification"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"Pinapagana ang TeleTypewriter."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Pag-vibrate ng ringer."</string>
@@ -386,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Kapag nagbabahagi, nagre-record, o nagka-cast ka ng app, may access ang <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> sa kahit anong ipinapakita o pine-play sa app na iyon. Kaya mag-ingat sa mga password, detalye ng pagbabayad, mensahe, o iba pang impormasyon."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Magpatuloy"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Ibahagi o i-record ang isang app"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Payagan ang app na ito na magbahagi o mag-record?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Kapag nagbabahagi, nagre-record, o nagka-cast ka, may access ang app na ito sa kahit anong nakikita sa iyong screen o pine-play sa device mo. Kaya mag-ingat sa mga password, detalye ng pagbabayad, mensahe, o iba pang sensitibong impormasyon."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Kapag nagbabahagi, nagre-record, o nagka-cast ka ng app, may access ang app na ito sa kahit anong ipinapakita o pine-play sa app na iyon. Kaya mag-ingat sa mga password, detalye ng pagbabayad, mensahe, o iba pang impormasyon."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Na-block ng iyong IT admin"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"Naka-disable ang pag-screen capture ayon sa patakaran ng device"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"I-clear lahat"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Pamahalaan"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"History"</string>
@@ -511,7 +511,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"I-unlock para magamit"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Nagkaproblema sa pagkuha ng iyong mga card, pakisubukan ulit sa ibang pagkakataon"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Mga setting ng lock screen"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"I-scan ang QR code"</string>
+ <string name="qr_code_scanner_title" msgid="1938155688725760702">"Scanner ng QR code"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Profile sa trabaho"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Airplane mode"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Hindi mo maririnig ang iyong susunod na alarm ng <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -794,6 +794,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"I-magnify ang buong screen"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"I-magnify ang isang bahagi ng screen"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Switch"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Payagan ang diagonal na pag-scroll"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"I-resize"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"Palitan ang uri ng pag-magnify"</string>
@@ -1024,4 +1026,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"Payagan ang <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> na i-access ang lahat ng log ng device?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"Payagan ang isang beses na pag-access"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Huwag payagan"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"Nire-record ng mga log ng device kung ano ang nangyayari sa iyong device. Magagamit ng mga app ang mga log na ito para maghanap at mag-ayos ng mga isyu.\n\nPosibleng maglaman ang ilang log ng sensitibong impormasyon, kaya ang mga app lang na pinagkakatiwalaan mo ang payagang maka-access sa lahat ng log ng device. \n\nKung hindi mo papayagan ang app na ito na i-access ang lahat ng log ng device, maa-access pa rin nito ang mga sarili nitong log. Posible pa ring ma-access ng manufacturer ng iyong device ang ilang log o impormasyon sa device mo."</string>
</resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 098091a8714d..11b8d7e6bcd8 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"Bu bilgisayardan her zaman izin ver"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"İzin ver"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"USB hata ayıklama işlevine izin verilmiyor"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"Bu cihazda geçerli olarak oturum açmış olan kullanıcı, USB hata ayıklama özelliğini açamaz. Bu özelliği kullanmak için birincil kullanıcıya geçin."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"Şu anda bu cihazda oturum açan kullanıcı, USB hata ayıklamayı açamaz. Bu özelliği kullanabilmek için yönetici olan kullanıcıya geçin."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Sistem dilini <xliff:g id="LANGUAGE">%1$s</xliff:g> olarak değiştirmek istiyor musunuz?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Başka bir cihaz tarafından sistem dilinin değiştirilmesi istendi"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Dili değiştir"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"Bu ağda her zaman izin ver"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"İzin ver"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Kablosuz hata ayıklamaya izin verilmiyor"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"Bu cihazda şu anda oturum açmış olan kullanıcı, kablosuz hata ayıklama özelliğini açamaz. Bu özelliği kullanmak için birincil kullanıcıya geçin."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"Bu cihazda şu anda oturum açmış olan kullanıcı, kablosuz hata ayıklama özelliğini açamaz. Bu özelliği kullanmak için yönetici kullanıcıya geçin."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"USB bağlantı noktası devre dışı bırakıldı"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"Cihazınızı sıvılardan veya tozlardan korumak için USB bağlantı noktası devre dışı bırakıldı ve aksesuarları algılamayacak.\n\nUSB bağlantı noktasını tekrar sorunsuz kullanabileceğiniz zaman bilgilendirileceksiniz."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"USB bağlantı noktası, şarj cihazlarını ve aksesuarları algılamak üzere etkinleştirildi"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Sesli Yardım"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Cüzdan"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"QR kodu tarayıcı"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"Kilidi aç"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"Cihaz kilitlendi"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Yüz taranıyor"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Gönder"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"Yüz tanınamadı"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Bunun yerine parmak izi kullanın"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth bağlandı."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"Pil yüzdesi bilinmiyor."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"Uçak modu."</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN açık."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"Pil yüzdesi: <xliff:g id="NUMBER">%d</xliff:g>"</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Pil yüzde <xliff:g id="PERCENTAGE">%1$s</xliff:g> dolu. Kullanımınıza göre yaklaşık <xliff:g id="TIME">%2$s</xliff:g> süresi kaldı"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Pil yüzde <xliff:g id="PERCENTAGE">%1$d</xliff:g> dolu. Kullanımınıza göre yaklaşık <xliff:g id="TIME">%2$s</xliff:g> süresi kaldı"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Pil şarj oluyor, yüzde <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>."</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"Tüm bildirimleri göster"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"TeleTypewriter etkin."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Telefon zili titreşim."</string>
@@ -386,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Bir uygulamayı paylaşma, kaydetme ve yayınlama özelliklerini kullandığınızda <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>, söz konusu uygulamada gösterilen veya oynatılan her şeye erişebilir. Dolayısıyla şifreler, ödeme ayrıntıları, mesajlar veya diğer hassas bilgiler konusunda dikkatli olun."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Devam"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Uygulamayı paylaşın veya kaydedin"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Bu uygulamanın paylaşım ve kayıt yapmasına izin verilsin mi?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Paylaşım, kayıt ve yayınlama özelliklerini kullandığınızda, ekranınızda görünen veya cihazınızda oynatılan her şeye erişebilir. Dolayısıyla şifreler, ödeme ayrıntıları, mesajlar veya diğer hassas bilgiler konusunda dikkatli olun."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Bir uygulamayı paylaşma, kaydetme ve yayınlama özelliklerini kullandığınızda , söz konusu uygulamada gösterilen veya oynatılan her şeye erişebilir. Dolayısıyla şifreler, ödeme ayrıntıları, mesajlar veya diğer hassas bilgiler konusunda dikkatli olun."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"BT yöneticiniz tarafından engellendi"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"Ekran görüntüsü alma, cihaz politikası tarafından devre dışı bırakıldı"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Tümünü temizle"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Yönet"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Geçmiş"</string>
@@ -511,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Kullanmak için kilidi aç"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Kartlarınız alınırken bir sorun oluştu. Lütfen daha sonra tekrar deneyin"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Kilit ekranı ayarları"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"QR kodunu tara"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"İş profili"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Uçak modu"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"<xliff:g id="WHEN">%1$s</xliff:g> olarak ayarlanmış bir sonraki alarmınızı duymayacaksınız"</string>
@@ -794,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Tam ekran büyütme"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Ekranın bir parçasını büyütün"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Geç"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Çapraz kaydırmaya izin ver"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Yeniden boyutlandır"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"Büyütme türünü değiştir"</string>
@@ -1024,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"d MMM, EEE"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:dd"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> uygulamasının tüm cihaz günlüklerine erişmesine izin verilsin mi?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"Tek seferlik erişim izni ver"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"İzin verme"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"Cihaz günlükleri, cihazınızda olanları kaydeder. Uygulamalar, sorunları bulup düzeltmek için bu günlükleri kullanabilir.\n\nBazı günlükler hassas bilgiler içerebileceği için yalnızca güvendiğiniz uygulamaların tüm cihaz günlüklerine erişmesine izin verin. \n\nBu uygulamanın tüm cihaz günlüklerine erişmesine izin vermeseniz de kendi günlüklerine erişmeye devam edebilir. Ayrıca, cihaz üreticiniz de cihazınızdaki bazı günlüklere veya bilgilere erişmeye devam edebilir."</string>
</resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index ef05be6106dc..972ee114334c 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"Завжди дозволяти з цього комп’ютера"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"Дозволити"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"Ви не можете вмикати налагодження USB"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"Користувач поточного облікового запису не може вмикати налагодження USB. Щоб увімкнути цю функцію, увійдіть в обліковий запис основного користувача."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"Користувач поточного облікового запису не може вмикати налагодження через USB. Щоб увімкнути цю функцію, увійдіть в обліковий запис адміністратора."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Змінити мову системи на таку: <xliff:g id="LANGUAGE">%1$s</xliff:g>?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Запит на змінення мови системи надіслано з іншого пристрою"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Змінити мову"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"Завжди дозволяти в цій мережі"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"Дозволити"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Налагодження через Wi-Fi заборонене"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"Користувач поточного облікового запису не може вмикати налагодження через Wi-Fi. Щоб активувати цю функцію, увійдіть в обліковий запис основного користувача."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"Користувач поточного облікового запису не може вмикати налагодження через Wi-Fi. Щоб активувати цю функцію, увійдіть в обліковий запис адміністратора."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"USB-порт вимкнено"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"Щоб захистити ваш пристрій від рідини та сміття, USB-порт вимкнено. Він не виявлятиме жодних аксесуарів.\n\nКоли USB-порт можна буде використовувати, ви отримаєте сповіщення."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"Порт USB виявлятиме зарядні пристрої та аксесуари"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Голосові підказки"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Гаманець"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"Сканер QR-коду"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"Розблокувати"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"Пристрій заблоковано"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Сканування обличчя"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Надіслати"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"Обличчя не розпізнано"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Скористайтеся відбитком"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth під’єднано."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"Відсоток заряду акумулятора невідомий."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"Режим польоту."</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"Мережу VPN увімкнено."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"Заряд акумулятора у відсотках: <xliff:g id="NUMBER">%d</xliff:g>."</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Згідно з даними про використання залишилося <xliff:g id="PERCENTAGE">%1$s</xliff:g> заряду акумулятора – близько <xliff:g id="TIME">%2$s</xliff:g>"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Згідно з даними про використання залишилося <xliff:g id="PERCENTAGE">%1$d</xliff:g> заряду акумулятора – близько <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Акумулятор заряджається, поточний заряд <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> відсотків."</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"Переглянути всі сповіщення"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"Телетайп увімкнено."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Дзвінок на вібросигналі."</string>
@@ -386,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Коли ви показуєте, записуєте або транслюєте додаток, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> отримує доступ до всього, що відображається або відтворюється в цьому додатку. Тому будьте уважні з паролями, повідомленнями, платіжною й іншою конфіденційною інформацією."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Продовжити"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Показувати або записувати додаток"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Дозволити цьому додатку показувати або записувати екран?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Коли ви показуєте, записуєте або транслюєте екран, цей додаток отримує доступ до всього, що відображається на екрані чи відтворюється на пристрої. Тому будьте уважні з паролями, повідомленнями, платіжною й іншою конфіденційною інформацією."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Коли ви показуєте, записуєте або транслюєте додаток, доступ до всього, що відображається або відтворюється в ньому, отримує цей додаток. Тому будьте уважні з паролями, повідомленнями, платіжною й іншою конфіденційною інформацією."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Заблоковано адміністратором"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"Запис екрана вимкнено згідно з правилами для пристрою"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Очистити все"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Керувати"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Історія"</string>
@@ -511,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Розблокувати, щоб використовувати"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Не вдалось отримати ваші картки. Повторіть спробу пізніше."</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Параметри блокування екрана"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"Сканувати QR-код"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Робочий профіль"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Режим польоту"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Наступний сигнал о <xliff:g id="WHEN">%1$s</xliff:g> не пролунає"</string>
@@ -794,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Збільшення всього екрана"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Збільшити частину екрана"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Перемкнути"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Дозволити прокручування по діагоналі"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Змінити розмір"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"Змінити тип збільшення"</string>
@@ -1024,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"Надати додатку <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> доступ до всіх журналів пристрою?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"Надати доступ лише цього разу"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Не надавати"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"У журналах пристрою реєструється все, що відбувається на ньому. За допомогою цих журналів додатки можуть виявляти й усувати проблеми.\n\nДеякі журнали можуть містити конфіденційні дані, тому надавати доступ до всіх журналів пристрою слід лише надійним додаткам. \n\nЯкщо додаток не має доступу до всіх журналів пристрою, він усе одно може використовувати власні журнали. Виробник вашого пристрою все одно може використовувати деякі журнали чи інформацію на ньому."</string>
</resources>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index f1992a72d014..6e2b3647fa99 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"اس کمپیوٹر سے ہمیشہ اجازت دیں"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"اجازت دیں"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"‏USB ڈیبگ کرنے کی اجازت نہیں ہے"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"‏اس آلہ پر فی الحال سائن ان کردہ صارف USB ڈیبگنگ آن نہیں کر سکتا۔ اس خصوصیت کا استعمال کرنے کیلئے، ابتدائی صارف پر سوئچ کریں۔"</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"‏اس آلہ پر فی الحال سائن ان کردہ صارف USB ڈیبگنگ آن نہیں کر سکتا۔ اس خصوصیت کا استعمال کرنے کے لیے، منتظم صارف پر سوئچ کریں۔"</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"کیا آپ سسٹم کی زبان کو <xliff:g id="LANGUAGE">%1$s</xliff:g> میں تبدیل کرنا چاہتے ہیں؟"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"کسی دوسرے آلے کے ذریعے سسٹم کی زبان میں تبدیلی کی درخواست کی گئی"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"زبان تبدیل کریں"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"اس نیٹ ورک پر ہمیشہ اجازت دیں"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"اجازت دیں"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"وائرلیس ڈیبگنگ کرنے کی اجازت نہیں ہے"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"اس آلہ پر فی الحال سائن ان کردہ صارف وائرلیس ڈیبگنگ آن نہیں کر سکتا۔ اس خصوصیت کا استعمال کرنے کے ليے، ابتدائی صارف پر سوئچ کریں۔"</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"اس آلہ پر فی الحال سائن ان کردہ صارف وائرلیس ڈیبگنگ آن نہیں کر سکتا۔ اس خصوصیت کا استعمال کرنے کے ليے، منتظم صارف پر سوئچ کریں۔"</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"‏USB پورٹ غیر فعال ہو گیا"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"‏آپ کے آلے کی سیال یا دھول سے حفاظت کرنے کے لیے، USB پورٹ کو غیر فعال کر دیا گیا ہے اور یہ کسی لوازم کا پتہ نہیں لگا پائے گا۔\n\nUSB پورٹ کا دوبارہ استعمال کرنا ٹھیک ہونے پر آپ کو مطلع کیا جائے گا۔"</string>
<string name="usb_port_enabled" msgid="531823867664717018">"‏چارجرز اور لوازمات کا پتا لگانے کے لیے USB پورٹ فعال ہے"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"صوتی معاون"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"والٹ"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"‏QR کوڈ اسکینر"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"غیر مقفل کریں"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"آلہ مقفل کر دیا گیا"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"اسکیننگ چہرہ"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"بھیجیں"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"چہرے کی پہچان نہیں ہو سکی"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"اس کے بجائے فنگر پرنٹ استعمال کریں"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"بلوٹوتھ مربوط ہے۔"</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"بیٹری کی فیصد نامعلوم ہے۔"</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"ہوائی جہاز وضع۔"</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"‏VPN آن ہے۔"</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"بیٹری <xliff:g id="NUMBER">%d</xliff:g> فیصد۔"</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"آپ کے استعمال کی بنیاد پر بیٹری <xliff:g id="PERCENTAGE">%1$s</xliff:g> فیصد، تقریباً <xliff:g id="TIME">%2$s</xliff:g> باقی ہے"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"آپ کے استعمال کی بنیاد پر بیٹری <xliff:g id="PERCENTAGE">%1$d</xliff:g> فیصد، تقریباً <xliff:g id="TIME">%2$s</xliff:g> باقی ہے"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"بیٹری چارج ہو رہی ہے، اس وقت <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> فیصد ہے۔"</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"تمام اطلاعات دیکھیں"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"ٹیلی ٹائپ رائٹر فعال ہے۔"</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"رنگر وائبریٹ۔"</string>
@@ -305,28 +310,17 @@
<string name="sensor_privacy_mic_unblocked_toast_content" msgid="306555320557065068">"مائیکروفون دستیاب ہے"</string>
<string name="sensor_privacy_camera_unblocked_toast_content" msgid="7843105715964332311">"کیمرا دستیاب ہے"</string>
<string name="sensor_privacy_mic_camera_unblocked_toast_content" msgid="7339355093282661115">"مائیکروفون اور کیمرا دستیاب ہیں"</string>
- <!-- no translation found for sensor_privacy_mic_turned_on_dialog_title (6348853159838376513) -->
- <skip />
- <!-- no translation found for sensor_privacy_mic_turned_off_dialog_title (5760464281790732849) -->
- <skip />
- <!-- no translation found for sensor_privacy_mic_unblocked_dialog_content (4889961886199270224) -->
- <skip />
- <!-- no translation found for sensor_privacy_mic_blocked_no_exception_dialog_content (5864898470772965394) -->
- <skip />
- <!-- no translation found for sensor_privacy_mic_blocked_with_exception_dialog_content (810289713700437896) -->
- <skip />
- <!-- no translation found for sensor_privacy_camera_turned_on_dialog_title (8039095295100075952) -->
- <skip />
- <!-- no translation found for sensor_privacy_camera_turned_off_dialog_title (1936603903120742696) -->
- <skip />
- <!-- no translation found for sensor_privacy_camera_unblocked_dialog_content (7847190103011782278) -->
- <skip />
- <!-- no translation found for sensor_privacy_camera_blocked_dialog_content (3182428709314874616) -->
- <skip />
- <!-- no translation found for sensor_privacy_htt_blocked_dialog_content (3333321592997666441) -->
- <skip />
- <!-- no translation found for sensor_privacy_dialog_open_settings (1503088305279285048) -->
- <skip />
+ <string name="sensor_privacy_mic_turned_on_dialog_title" msgid="6348853159838376513">"مائیکروفون کو آن کر دیا گیا"</string>
+ <string name="sensor_privacy_mic_turned_off_dialog_title" msgid="5760464281790732849">"مائیکروفون کو آف کر دیا گیا"</string>
+ <string name="sensor_privacy_mic_unblocked_dialog_content" msgid="4889961886199270224">"مائیکروفون سبھی ایپس اور سروسز کے لیے فعال ہو گیا۔"</string>
+ <string name="sensor_privacy_mic_blocked_no_exception_dialog_content" msgid="5864898470772965394">"‏مائیکروفون تک رسائی سبھی ایپس اور سروسز کے لیے غیر فعال ہو گئی۔ آپ مائیکروفون تک رسائی کو ترتیبات &gt; رازداری &gt; مائیکروفون میں فعال کر سکتے ہیں۔"</string>
+ <string name="sensor_privacy_mic_blocked_with_exception_dialog_content" msgid="810289713700437896">"‏مائیکروفون تک رسائی سبھی ایپس اور سروسز کے لیے غیر فعال ہو گئی۔ آپ اسے ترتیبات &gt; رازداری &gt; مائیکروفون میں اسے تبدیل کر سکتے ہیں۔"</string>
+ <string name="sensor_privacy_camera_turned_on_dialog_title" msgid="8039095295100075952">"کیمرا آن ہو گیا"</string>
+ <string name="sensor_privacy_camera_turned_off_dialog_title" msgid="1936603903120742696">"کیمرا آف ہو گیا"</string>
+ <string name="sensor_privacy_camera_unblocked_dialog_content" msgid="7847190103011782278">"کیمرا سبھی ایپس اور سروسز کے لیے فعال ہو گیا۔"</string>
+ <string name="sensor_privacy_camera_blocked_dialog_content" msgid="3182428709314874616">"کیمرا تک رسائی سبھی ایپس اور سروسز کے لیے غیر فعال ہو گئی۔"</string>
+ <string name="sensor_privacy_htt_blocked_dialog_content" msgid="3333321592997666441">"مائیکروفون بٹن کو استعمال کرنے کے لیے، ترتیبات میں مائیکروفون تک رسائی کو فعال کریں۔"</string>
+ <string name="sensor_privacy_dialog_open_settings" msgid="1503088305279285048">"ترتیبات کھولیں۔"</string>
<string name="media_seamless_other_device" msgid="4654849800789196737">"دوسرا آلہ"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"مجموعی جائزہ ٹوگل کریں"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"الارمز، یاددہانیوں، ایونٹس اور آپ کے متعین کردہ کالرز کے علاوہ، آپ آوازوں اور وائبریشنز سے ڈسٹرب نہیں ہوں گے۔ موسیقی، ویڈیوز اور گیمز سمیت آپ ابھی بھی ہر وہ چیز سنیں گے جسے چلانے کا آپ انتخاب کرتے ہیں۔"</string>
@@ -397,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"جب آپ اشتراک، ریکارڈنگ یا کاسٹ کر رہے ہوتے ہیں تو <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> کو آپ کی اسکرین پر دکھائی گئی یا آپ کے آلے پر چلائی گئی ہر چیز تک رسائی حاصل ہوتی ہے۔ اس لیے پاس ورڈز، ادائیگی کی تفصیلات، پیغامات، یا دیگر حساس معلومات کے سلسلے میں محتاط رہیں۔"</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"جاری رکھیں"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"ایپ کا اشتراک یا ریکارڈ کریں"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"اس ایپ کو اشتراک یا ریکارڈ کرنے کی اجازت دیں؟"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"جب آپ اشتراک، ریکارڈنگ یا کاسٹ کر رہے ہوتے ہیں تو اس ایپ کو آپ کی اسکرین پر دکھائی دینے والی یا آپ کے آلے پر چلنے والی ہر چیز تک رسائی حاصل ہوتی ہے۔ اس لیے پاس ورڈز، ادائیگی کی تفصیلات، پیغامات، یا دیگر حساس معلومات کے سلسلے میں محتاط رہیں۔"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"جب آپ اشتراک، ریکارڈنگ یا کاسٹ کر رہے ہوتے ہیں تو اس ایپ کو آپ کی اسکرین پر دکھائی گئی یا آپ کے آلے پر چلائی گئی ہر چیز تک رسائی حاصل ہوتی ہے۔ اس لیے پاس ورڈز، ادائیگی کی تفصیلات، پیغامات، یا دیگر حساس معلومات کے سلسلے میں محتاط رہیں۔"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"‏آپ کے IT منتظم نے مسدود کر دیا"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"اسکرین کو کیپچر کرنا آلہ کی پالیسی کے ذریعے غیر فعال ہے"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"سبھی کو صاف کریں"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"نظم کریں"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"سرگزشت"</string>
@@ -522,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"استعمال کرنے کے لیے غیر مقفل کریں"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"آپ کے کارڈز حاصل کرنے میں ایک مسئلہ درپیش تھا، براہ کرم بعد میں دوبارہ کوشش کریں"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"مقفل اسکرین کی ترتیبات"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"‏QR کوڈ اسکین کریں"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"دفتری پروفائل"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"ہوائی جہاز وضع"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"آپ کو <xliff:g id="WHEN">%1$s</xliff:g> بجے اپنا اگلا الارم سنائی نہیں دے گا"</string>
@@ -805,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"فُل اسکرین کو بڑا کریں"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"اسکرین کا حصہ بڑا کریں"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"سوئچ کریں"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"وتری سکرولنگ کی اجازت دیں"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"سائز تبدیل کریں"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"میگنیفیکیشن کی قسم کو تبدیل کریں"</string>
@@ -1035,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> کو آلے کے تمام لاگز تک رسائی کی اجازت دیں؟"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"یک وقتی رسائی کی اجازت دیں"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"اجازت نہ دیں"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"آپ کے آلے پر جو ہوتا ہے آلے کے لاگز اسے ریکارڈ کر لیتے ہیں۔ ایپس ان لاگز کا استعمال مسائل کو تلاش کرنے اور ان کو حل کرنے کے لیے کر سکتی ہیں۔\n\nکچھ لاگز میں حساس معلومات شامل ہو سکتی ہیں، اس لیے صرف اپنی بھروسے مند ایپس کو ہی آلے کے تمام لاگز تک رسائی کی اجازت دیں۔ \n\nاگر آپ اس ایپ کو آلے کے تمام لاگز تک رسائی کی اجازت نہیں دیتے ہیں تب بھی یہ اپنے لاگز تک رسائی حاصل کر سکتی ہے۔ آپ کے آلے کا مینوفیکچرر اب بھی آپ کے آلے پر کچھ لاگز یا معلومات تک رسائی حاصل کر سکتا ہے۔"</string>
</resources>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 96e031a92775..b12ea3dd7a52 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"Doimo ushbu kompyuterdan ruxsat berilsin"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"Ruxsat berish"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"USB orqali nosozliklarni tuzatishga ruxsat berilmagan"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"Ayni paytda ushbu qurilmaga o‘z hisobi bilan kirgan foydalanuvchi USB orqali nosozliklarni aniqlash funksiyasini yoqa olmaydi. Bu funksiyadan foydalanish uchun asosiy foydalanuvchi profiliga o‘ting."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"Ayni paytda ushbu qurilmaga o‘z hisobi bilan kirgan foydalanuvchi USB orqali nosozliklarni tuzatish funksiyasini yoqa olmaydi. Bu funksiyadan foydalanish uchun administrator profiliga oʻting."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Tizim tilini <xliff:g id="LANGUAGE">%1$s</xliff:g> tiliga oʻzgartirishni istaysizmi?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Tizim tilini oʻzgartirishni boshqa qurilma soʻragan"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Tilni almashtirish"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"Bu tarmoqda doim ruxsat etilsin"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"Ruxsat"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Wi-Fi orqali debagging taqiqlandi"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"Ayni paytda ushbu qurilmaga oʻz hisobi bilan kirgan foydalanuvchi Wi-Fi orqali debagging funksiyasini yoqa olmaydi. Bu funksiyadan foydalanish uchun asosiy foydalanuvchi profiliga oʻting."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"Ayni paytda ushbu qurilmaga oʻz hisobi bilan kirgan foydalanuvchi Wi-Fi orqali debagging funksiyasini yoqa olmaydi. Bu funksiyadan foydalanish uchun administrator profiliga oʻting."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"USB port faolsizlashtirildi"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"Qurilmangizni suyuqlik va turli parchalardan himoya qilish uchun USB port faolsizlashtiriladi va hech qanday aksessuarni aniqlay olmaydi.\n\nUSB portdan xavfsiz foydalanish mumkin boʻlganda, sizga xabar beriladi."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"Quvvatlash moslamalari va aksessuarlarni aniqlash uchun USB port yoqildi"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Ovozli yordam"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"QR kod skaneri"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"Qulfdan chiqarish"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"Qurilma qulflandi"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Yuzni skanerlash"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Yuborish"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"Yuz aniqlanmadi"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Barmoq izi orqali urining"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth ulandi."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"Batareya quvvati foizi nomaʼlum."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"Parvoz rejimi"</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN yoniq."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"Batareya <xliff:g id="NUMBER">%d</xliff:g> foiz."</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Batareya quvvati <xliff:g id="PERCENTAGE">%1$s</xliff:g> foiz, joriy holatda yana <xliff:g id="TIME">%2$s</xliff:g> qoldi"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Batareya quvvati <xliff:g id="PERCENTAGE">%1$d</xliff:g> foiz, joriy holatda yana <xliff:g id="TIME">%2$s</xliff:g> qoldi"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Batareya quvvat olmoqda, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> foiz."</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"Barcha bildirishnomalarni ko‘rish"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"TeleTypewriter yoqildi."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Vibratsiyali qo‘ng‘iroq"</string>
@@ -386,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Ulashish, yozib olish va translatsiya qilish vaqtida <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ilovasi ekranda chiqadigan yoki qurilmada ijro qilinadigan kontentni koʻra oladi. Shu sababli parollar, toʻlov tafsilotlari, xabarlar yoki boshqa maxfiy axborot chiqmasligi uchun ehtiyot boʻling."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Davom etish"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Ilovada ulashish yoki yozib olish"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Bu ilovaga ulashish yoki yozib olish uchun ruxsat berilsinmi?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Ulashish, yozib olish va translatsiya qilish vaqtida bu ilova ekranda chiqadigan yoki qurilmada ijro qilinadigan kontentni koʻra oladi. Shu sababli parollar, toʻlov tafsilotlari, xabarlar yoki boshqa maxfiy axborot chiqmasligi uchun ehtiyot boʻling."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Ulashish, yozib olish va translatsiya qilish vaqtida bu ilova ekranda chiqadigan yoki qurilmada ijro qilinadigan kontentni koʻra oladi. Shu sababli parollar, toʻlov tafsilotlari, xabarlar yoki boshqa maxfiy axborot chiqmasligi uchun ehtiyot boʻling."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"AT administratoringiz tomonidan bloklangan"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"Ekranni tasvirga olish qurilmadan foydalanish tartibi tomonidan faolsizlantirilgan"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Hammasini tozalash"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Boshqarish"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Tarix"</string>
@@ -511,7 +511,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Foydalanish uchun qulfdan chiqarish"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Bildirgilarni yuklashda xatolik yuz berdi, keyinroq qaytadan urining"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Qulflangan ekran sozlamalari"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"QR kodni skanerlash"</string>
+ <string name="qr_code_scanner_title" msgid="1938155688725760702">"QR kod skaneri"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Ish profili"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Parvoz rejimi"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Keyingi signal (<xliff:g id="WHEN">%1$s</xliff:g>) chalinmaydi"</string>
@@ -794,6 +794,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Ekranni toʻliq kattalashtirish"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Ekran qismini kattalashtirish"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Almashtirish"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Diagonal aylantirishga ruxsat berish"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Oʻlchamini oʻzgartirish"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"Kattalashtirish turini oʻzgartirish"</string>
@@ -1024,4 +1026,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"s:dd"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> ilovasining qurilmadagi barcha jurnallarga kirishiga ruxsat berilsinmi?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"Bir matalik foydalanishga ruxsat berish"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Rad etish"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"Qurilma jurnaliga qurilma bilan yuz bergan hodisalar qaydlari yoziladi. Ilovalar bu jurnal qaydlari yordamida muammolarni topishi va bartaraf qilishi mumkin.\n\nAyrim jurnal qaydlarida maxfiy axborotlar yozilishi mumkin, shu sababli qurilmadagi barcha jurnal qaydlariga ruxsatni faqat ishonchli ilovalarga bering. \n\nBu ilovaga qurilmadagi barcha jurnal qaydlariga ruxsat berilmasa ham, u oʻzining jurnalini ocha oladi. Qurilma ishlab chiqaruvchisi ham ayrim jurnallar yoki qurilma haqidagi axborotlarni ocha oladi."</string>
</resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index b253a91a0576..1af2e0e2ac7c 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"Luôn cho phép từ máy tính này"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"Cho phép"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"Không cho phép chế độ gỡ lỗi qua USB"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"Người dùng hiện đã đăng nhập vào thiết bị này không thể bật tính năng gỡ lỗi USB. Để sử dụng tính năng này, hãy chuyển sang người dùng chính."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"Người dùng đang đăng nhập trên thiết bị này không thể bật tính năng gỡ lỗi qua USB. Để sử dụng tính năng này, hãy chuyển sang tài khoản người dùng quản trị."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Bạn có muốn thay đổi ngôn ngữ hệ thống thành <xliff:g id="LANGUAGE">%1$s</xliff:g> không?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Thiết bị khác yêu cầu thay đổi ngôn ngữ hệ thống"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Thay đổi ngôn ngữ"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"Luôn cho phép trên mạng này"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"Cho phép"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Không cho phép gỡ lỗi qua Wi-Fi"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"Người dùng hiện đã đăng nhập vào thiết bị này không thể bật tính năng gỡ lỗi qua Wi-Fi. Để sử dụng tính năng này, hãy chuyển sang người dùng chính."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"Người dùng đang đăng nhập trên thiết bị này không thể bật tính năng gỡ lỗi qua Wi-Fi. Để sử dụng tính năng này, hãy chuyển sang tài khoản người dùng quản trị."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"Đã tắt cổng USB"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"Để bảo vệ thiết bị của bạn khỏi chất lỏng hay mảnh vỡ, cổng USB sẽ tắt và không phát hiện được bất kỳ phụ kiện nào.\n\nBạn sẽ nhận được thông báo khi có thể sử dụng lại cổng USB."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"Đã bật cổng USB để phát hiện bộ sạc và phụ kiện"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Trợ lý thoại"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Ví"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"Trình quét mã QR"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"Mở khóa"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"Đã khóa thiết bị"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Quét tìm khuôn mặt"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Gửi"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"Không nhận ra khuôn mặt"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Hãy dùng vân tay"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Đã kết nối bluetooth."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"Tỷ lệ phần trăm pin không xác định."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"Chế độ trên máy bay."</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN đang bật."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"<xliff:g id="NUMBER">%d</xliff:g> phần trăm pin."</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> phần trăm pin, còn khoảng <xliff:g id="TIME">%2$s</xliff:g> dựa trên mức sử dụng của bạn"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> phần trăm pin, còn khoảng <xliff:g id="TIME">%2$s</xliff:g> dựa trên mức sử dụng của bạn"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Đang sạc pin, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"Xem tất cả thông báo"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"Đã bật TeleTypewriter."</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Chuông rung."</string>
@@ -386,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Khi bạn chia sẻ, ghi hoặc truyền ứng dụng, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> sẽ có quyền truy cập vào mọi nội dung xuất hiện hoặc phát trên ứng dụng đó. Vì vậy, hãy thận trọng để không làm lộ mật khẩu, thông tin thanh toán, tin nhắn hoặc thông tin nhạy cảm khác."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Tiếp tục"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Chia sẻ hoặc ghi ứng dụng"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Cho phép ứng dụng này chia sẻ hoặc ghi?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Khi bạn chia sẻ, ghi hoặc truyền, ứng dụng này sẽ truy cập được vào mọi nội dung xuất hiện trên màn hình hoặc phát trên thiết bị của bạn. Vì vậy, hãy để ý đến mật khẩu, thông tin thanh toán, tin nhắn hoặc thông tin nhạy cảm khác."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Khi bạn chia sẻ, ghi hoặc truyền ứng dụng, ứng dụng này sẽ truy cập được vào mọi nội dung xuất hiện hoặc phát trên ứng dụng đó. Vì vậy, hãy để ý đến mật khẩu, thông tin thanh toán, tin nhắn hoặc thông tin nhạy cảm khác."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Bị quản trị viên CNTT chặn"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"Tính năng chụp ảnh màn hình đã bị tắt theo chính sách thiết bị"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Xóa tất cả"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Quản lý"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Lịch sử"</string>
@@ -511,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Mở khóa để sử dụng"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Đã xảy ra sự cố khi tải thẻ của bạn. Vui lòng thử lại sau"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Cài đặt màn hình khóa"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"Quét mã QR"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Hồ sơ công việc"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Chế độ máy bay"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Bạn sẽ không nghe thấy báo thức tiếp theo lúc <xliff:g id="WHEN">%1$s</xliff:g> của mình"</string>
@@ -794,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Phóng to toàn màn hình"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Phóng to một phần màn hình"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Chuyển"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Cho phép cuộn chéo"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Đổi kích thước"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"Thay đổi kiểu phóng to"</string>
@@ -1024,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"Cho phép <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> truy cập vào mọi nhật ký thiết bị?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"Cho phép truy cập một lần"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Không cho phép"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"Nhật ký thiết bị ghi lại những hoạt động diễn ra trên thiết bị của bạn. Các ứng dụng có thể dùng nhật ký này để tìm và khắc phục vấn đề.\n\nMột số nhật ký có thể chứa thông tin nhạy cảm, vì vậy, bạn chỉ nên cấp quyền truy cập vào mọi nhật ký thiết bị cho những ứng dụng mà mình tin tưởng. \n\nNếu bạn không cho phép ứng dụng này truy cập vào mọi nhật ký thiết bị, thì ứng dụng này vẫn có thể truy cập vào nhật ký của chính nó. Nhà sản xuất thiết bị vẫn có thể truy cập vào một số nhật ký hoặc thông tin trên thiết bị của bạn."</string>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 64357a08e3bd..21c9071c52b4 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"一律允许使用这台计算机进行调试"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"允许"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"不允许使用 USB 调试功能"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"目前已登录此设备的用户无法开启 USB 调试功能。要使用此功能,请切换为主要用户的帐号。"</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"当前已登录此设备的用户无法开启 USB 调试功能。要使用此功能,请切换为管理员用户。"</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"是否要将系统语言更改为<xliff:g id="LANGUAGE">%1$s</xliff:g>?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"另一台设备请求更改系统语言"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"更改语言"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"始终允许通过此网络进行调试"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"允许"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"不允许使用无线调试功能"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"目前已登录此设备的用户无法开启无线调试功能。要使用此功能,请切换为主要用户的帐号。"</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"当前已登录此设备的用户无法开启无线调试功能。要使用此功能,请切换为管理员用户。"</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"USB 端口已停用"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"为避免液体或碎屑导致您的设备受损,系统已停用 USB 端口,因此目前无法检测任何配件。\n\n系统会在重新允许使用 USB 端口时通知您。"</string>
<string name="usb_port_enabled" msgid="531823867664717018">"USB 端口已启用,可检测充电器和配件"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"语音助理"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"钱包"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"二维码扫描器"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"解锁"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"设备已锁定"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"正在扫描面孔"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"发送"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"人脸识别失败"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"改用指纹"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"蓝牙已连接。"</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"电池电量百分比未知。"</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"飞行模式。"</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN 已开启。"</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"电池电量为百分之 <xliff:g id="NUMBER">%d</xliff:g>。"</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"电池电量为 <xliff:g id="PERCENTAGE">%1$s</xliff:g>,根据您的使用情况,大约还可使用<xliff:g id="TIME">%2$s</xliff:g>"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"电池电量为 <xliff:g id="PERCENTAGE">%1$d</xliff:g>,根据您的使用情况,大约还可使用<xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"正在充电,已完成 <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%。"</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"查看所有通知"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"电传打字机已启用。"</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"振铃器振动。"</string>
@@ -386,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"在您进行分享、录制或投射时,<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> 可以访问通过此应用显示或播放的所有内容。因此,请注意保护密码、付款信息、消息或其他敏感信息。"</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"继续"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"分享或录制应用"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"是否允许此应用进行分享或录制?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"在您进行分享、录制或投屏时,此应用可以访问您的屏幕显示或设备播放的所有内容。因此,请注意保护密码、付款信息、消息或其他敏感信息。"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"在您进行分享、录制或投屏时,此应用可以访问通过此应用显示或播放的所有内容。因此,请注意保护密码、付款信息、消息或其他敏感信息。"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"已被 IT 管理员禁止"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"设备政策已停用屏幕截图功能"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"全部清除"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"管理"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"历史记录"</string>
@@ -510,8 +510,9 @@
<string name="wallet_secondary_label_updating" msgid="5726130686114928551">"正在更新"</string>
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"解锁设备即可使用"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"获取您的卡片时出现问题,请稍后重试"</string>
- <string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"锁定屏幕设置"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"扫描二维码"</string>
+ <string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"锁屏设置"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"工作资料"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"飞行模式"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"您在<xliff:g id="WHEN">%1$s</xliff:g>将不会听到下次闹钟响铃"</string>
@@ -794,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"放大整个屏幕"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"放大部分屏幕"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"切换"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"允许沿对角线滚动"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"调整大小"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"更改放大类型"</string>
@@ -1024,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"允许“<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g>”访问所有设备日志吗?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"允许访问一次"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"不允许"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"设备日志会记录设备上发生的活动。应用可以使用这些日志查找和修复问题。\n\n部分日志可能包含敏感信息,因此请仅允许您信任的应用访问所有设备日志。\n\n如果您不授予此应用访问所有设备日志的权限,它仍然可以访问自己的日志。您的设备制造商可能仍然能够访问设备上的部分日志或信息。"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index ec9112cf44a0..eda59b5d9936 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"一律允許透過這部電腦進行"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"允許"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"不允許 USB 偵錯"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"目前登入此裝置的使用者無法啟用 USB 偵錯功能。如要使用此功能,請切換至主要使用者。"</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"目前登入這部裝置的使用者無法開啟 USB 偵錯功能。如要使用這項功能,請切換為管理員使用者帳戶。"</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"要將系統語言變更為<xliff:g id="LANGUAGE">%1$s</xliff:g>嗎?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"另一部裝置要求變更系統語言"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"變更語言"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"一律允許在此網絡上執行"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"允許"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"不允許無線偵錯功能"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"目前登入此裝置的使用者無法啟用無線偵錯功能。如要使用此功能,請切換至主要使用者。"</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"目前登入這部裝置的使用者無法開啟無線偵錯功能。如要使用這項功能,請切換為管理員使用者帳戶。"</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"已停用 USB 連接埠"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"為了保護您的裝置免受液體或碎片損害,USB 連接埠已停用,因此不會偵測到任何配件。\n\nUSB 連接埠可安全使用時,您會收到通知。"</string>
<string name="usb_port_enabled" msgid="531823867664717018">"已啟用 USB 連接埠以偵測充電器和配件"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"語音助手"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"錢包"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"QR 碼掃瞄器"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"解鎖"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"裝置已上鎖"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"掃瞄緊面孔"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"傳送"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"無法辨識面孔"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"請改用指紋"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"藍牙連線已建立。"</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"電量百分比不明。"</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"飛航模式。"</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"開咗 VPN。"</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"電池電量為百分之 <xliff:g id="NUMBER">%d</xliff:g>。"</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"電量仲剩番 <xliff:g id="PERCENTAGE">%1$s</xliff:g>。根據你嘅使用情況,仲可以用大約 <xliff:g id="TIME">%2$s</xliff:g>"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"電量仲剩番 <xliff:g id="PERCENTAGE">%1$d</xliff:g>。根據你嘅使用情況,仲可以用大約 <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"正在充電:<xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%。"</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"睇所有通知"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"TeleTypewriter (TTY) 已啟用。"</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"鈴聲震動。"</string>
@@ -386,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"進行分享、錄製或投放時,<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> 可存取顯示在螢幕畫面上或在裝置上播放的所有內容。因此請謹慎處理密碼、付款資料、訊息或其他敏感資料。"</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"繼續"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"分享或錄製應用程式"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"要允許此應用程式分享或錄製內容嗎?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"進行分享、錄製或投放時,此應用程式可存取顯示在螢幕畫面上或在裝置上播放的所有內容。因此請謹慎處理密碼、付款資料、訊息或其他敏感資料。"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"進行分享、錄製或投放時,此應用程式可存取顯示在螢幕畫面上或在該應用程式上播放的所有內容。因此請謹慎處理密碼、付款資料、訊息或其他敏感資料。"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"已被您的 IT 管理員封鎖"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"螢幕截圖功能因裝置政策而停用"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"全部清除"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"管理"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"記錄"</string>
@@ -511,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"解鎖即可使用"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"擷取資訊卡時發生問題,請稍後再試。"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"上鎖畫面設定"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"掃瞄 QR 碼"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"工作設定檔"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"飛行模式"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"您不會<xliff:g id="WHEN">%1$s</xliff:g>聽到鬧鐘"</string>
@@ -794,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"放大成個畫面"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"放大部分螢幕畫面"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"切換"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"允許斜角捲動"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"調整大小"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"變更放大類型"</string>
@@ -1024,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"MMM d EEE"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"要允許「<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g>」存取所有裝置記錄嗎?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"允許一次性存取"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"不允許"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"系統會透過裝置記錄記下裝置上的活動。應用程式可以根據這些記錄找出問題並修正。\n\n某些記錄可能含有機密資訊,因此請勿讓不信任的應用程式存取所有裝置記錄。\n\n即使你不允許這個應用程式存取所有裝置記錄,這個應用程式仍能存取自己的記錄,而且裝置製造商或許仍可存取裝置的某些記錄或資訊。"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 0f8267543726..24e85c7103e9 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"一律允許透過這台電腦進行"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"允許"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"無權使用 USB 偵錯功能"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"目前登入這個裝置的使用者無法啟用 USB 偵錯功能。如要使用這項功能,請切換到主要使用者。"</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"目前登入這部裝置的使用者無法開啟 USB 偵錯功能。如要使用這項功能,請切換為管理員使用者帳戶。"</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"要將系統語言變更為<xliff:g id="LANGUAGE">%1$s</xliff:g>嗎?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"另一部裝置要求變更系統語言"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"變更語言"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"一律允許透過這個網路執行"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"允許"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"不允許使用無線偵錯功能"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"目前登入這部裝置的使用者無法開啟無線偵錯功能。如要使用這項功能,請切換到主要使用者。"</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"目前登入這部裝置的使用者無法開啟無線偵錯功能。如要使用這項功能,請切換為管理員使用者帳戶。"</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"USB 連接埠已停用"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"為了避免液體或灰塵導致你的裝置受損,系統已停用 USB 連接埠,因此目前無法偵測任何配件。\n\n系統會在可繼續使用 USB 連接埠時通知你。"</string>
<string name="usb_port_enabled" msgid="531823867664717018">"USB 連接埠已啟用,可偵測充電器和配件"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"語音小幫手"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"錢包"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"QR code 掃描器"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"解除鎖定"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"裝置已鎖定"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"掃描臉孔"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"傳送"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"無法辨識臉孔"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"請改用指紋"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"藍牙連線已建立。"</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"電池電量不明。"</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"飛行模式。"</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN 已開啟。"</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"電池電量為百分之 <xliff:g id="NUMBER">%d</xliff:g>。"</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"目前的電量為 <xliff:g id="PERCENTAGE">%1$s</xliff:g>。根據你的使用情形,大約還能使用到<xliff:g id="TIME">%2$s</xliff:g>"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"目前的電量為 <xliff:g id="PERCENTAGE">%1$d</xliff:g>。根據你的使用情形,大約還能使用到<xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"充電中,已完成 <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%。"</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"查看所有通知"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"TeleTypewriter (TTY) 已啟用。"</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"鈴聲震動。"</string>
@@ -386,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"進行分享、錄製或投放應用程式時,<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> 可以存取在該應用程式中顯示或播放的所有內容。因此請謹慎處理密碼、付款資料、訊息或其他機密資訊。"</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"繼續"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"分享或錄製應用程式"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"要允許這個應用程式分享或錄製嗎?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"進行分享、錄製或投放時,這個應用程式可以存取螢幕畫面上所顯示或裝置上所播放的所有內容。因此請謹慎處理密碼、付款資料、訊息或其他機密資訊。"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"進行分享、錄製或投放應用程式時,這個應用程式可以存取在其中顯示或播放的所有內容。因此請謹慎處理密碼、付款資料、訊息或其他機密資訊。"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"IT 管理員已封鎖這項操作"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"根據裝置政策規定,螢幕畫面擷取功能已停用"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"全部清除"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"管理"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"記錄"</string>
@@ -511,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"解鎖即可使用"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"擷取卡片時發生問題,請稍後再試"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"螢幕鎖定設定"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"掃描 QR 圖碼"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"工作資料夾"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"飛航模式"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"你不會聽到下一個<xliff:g id="WHEN">%1$s</xliff:g> 的鬧鐘"</string>
@@ -794,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"放大整個螢幕畫面"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"放大局部螢幕畫面"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"切換"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"允許沿對角線捲動"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"調整大小"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"變更放大類型"</string>
@@ -1024,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"MMM d EEE"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"要允許「<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g>」存取所有裝置記錄嗎?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"允許一次性存取"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"不允許"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"系統會透過裝置記錄記下裝置上的活動。應用程式可以根據這些記錄找出問題並修正。\n\n某些記錄可能含有機密資訊,因此請勿讓不信任的應用程式存取所有裝置記錄。\n\n即使你不允許這個應用程式存取所有裝置記錄,這個應用程式仍能存取自己的記錄,而且裝置製造商或許仍可存取裝置的某些記錄或資訊。"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 061592a33848..70b67ea5cbff 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"Hlala uvumela njalo kusuka kule khompyutha"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"Vumela"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"Ukususa iphutha kwe-USB akuvunyelwe"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"Umsebenzisi manje ongene ngemvume kule divayisi entsha akakwazi ukuvula ukulungisa amaphutha ku-USB. Ukuze usebenzise lesi sici, shintshela kumsebenzisi oyinhloko."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"Umsebenzisi ongene ngemvume manje kule divayisi entsha akakwazi ukuvula ukulungisa iphutha le-USB. Ukuze usebenzise lesi sakhi, shintshela kumsebenzisi ongumphathi."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Ingabe ufuna ukushintsha ulimi lwesistimu lube isi-<xliff:g id="LANGUAGE">%1$s</xliff:g>?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Ushintsho lolimi lwesistimu lucelwe enye idivayisi"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Shintsha ulimi"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"Njalo nje vumela le nethiwekhi"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"Vumela"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Ukulungisa amaphutha okungenantambo akuvunyelwe"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"Umsebenzisi manje ongene ngemvume kule divayisi entsha akakwazi ukuvula ukulungisa amaphutha okungenantambo. Ukuze usebenzise lesi sici, shintshela kumsebenzisi oyinhloko."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"Umsebenzisi ongene ngemvume manje kule divayisi entsha akakwazi ukuvula ukususa ibhagi nge-Wifi. Ukuze usebenzise lesi sakhi, shintshela kumsebenzisi oyinhloko."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"Imbobo ye-USB ikhutshaziwe"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"Ukuze kuvikelwe idivayisi yakho kusukela kuketshezi noma ama-debris, imbobo ye-USB iyakhutshazwa futhi ngeke ize ithole noma iziphi izisetshenziswa.\n\nUzokwaziswa uma sekulungile ukusebenzisa imbobo ye-USB futhi."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"Imbobo ye-USB inikwe amandla ukuze ithole amashaja nezisetshenziswa"</string>
@@ -125,7 +125,8 @@
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Isisekeli sezwi"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"I-wallet"</string>
<string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"Iskena sekhodi ye-QR"</string>
- <string name="accessibility_unlock_button" msgid="122785427241471085">"Vula"</string>
+ <!-- no translation found for accessibility_unlock_button (3613812140816244310) -->
+ <skip />
<string name="accessibility_lock_icon" msgid="661492842417875775">"Idivayisi ikhiyiwe"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Ukuskena ubuso"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Thumela"</string>
@@ -168,7 +169,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"Ayikwazi ukubona ubuso"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Kunalokho sebenzisa isigxivizo somunwe"</string>
- <!-- no translation found for keyguard_face_unlock_unavailable (8145547300240405980) -->
+ <!-- no translation found for keyguard_face_unlock_unavailable (1581949044193418736) -->
<skip />
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth ixhunyiwe"</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"Iphesenti lebhethri alaziwa."</string>
@@ -180,8 +181,12 @@
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"Imodi yendiza."</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"I-VPN ivuliwe."</string>
<string name="accessibility_battery_level" msgid="5143715405241138822">"Iphesenti <xliff:g id="NUMBER">%d</xliff:g> lebhethri"</string>
- <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Amaphesenti ebhethri ngu-<xliff:g id="PERCENTAGE">%1$s</xliff:g>, cishe kusele okungu-<xliff:g id="TIME">%2$s</xliff:g> kusukela ekusetshenzisweni kwakho"</string>
+ <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Amaphesenti ebhethri ngu-<xliff:g id="PERCENTAGE">%1$d</xliff:g>, cishe kusele okungu-<xliff:g id="TIME">%2$s</xliff:g> kusukela ekusetshenzisweni kwakho"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Ibhethri liyashaja, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> %%"</string>
+ <!-- no translation found for accessibility_battery_level_charging_paused (1716051308782906917) -->
+ <skip />
+ <!-- no translation found for accessibility_battery_level_charging_paused_with_estimate (4006089349465741762) -->
+ <skip />
<string name="accessibility_overflow_action" msgid="8555835828182509104">"Bona zonke izaziso"</string>
<string name="accessibility_tty_enabled" msgid="1123180388823381118">"i-TeleTypewriter inikwe amandla"</string>
<string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Ukudlidliza kweringa."</string>
@@ -305,28 +310,17 @@
<string name="sensor_privacy_mic_unblocked_toast_content" msgid="306555320557065068">"Imakrofoni iyatholakala"</string>
<string name="sensor_privacy_camera_unblocked_toast_content" msgid="7843105715964332311">"Ikhamera iyatholakala"</string>
<string name="sensor_privacy_mic_camera_unblocked_toast_content" msgid="7339355093282661115">"Imakrofoni nekhamera kuyatholakala"</string>
- <!-- no translation found for sensor_privacy_mic_turned_on_dialog_title (6348853159838376513) -->
- <skip />
- <!-- no translation found for sensor_privacy_mic_turned_off_dialog_title (5760464281790732849) -->
- <skip />
- <!-- no translation found for sensor_privacy_mic_unblocked_dialog_content (4889961886199270224) -->
- <skip />
- <!-- no translation found for sensor_privacy_mic_blocked_no_exception_dialog_content (5864898470772965394) -->
- <skip />
- <!-- no translation found for sensor_privacy_mic_blocked_with_exception_dialog_content (810289713700437896) -->
- <skip />
- <!-- no translation found for sensor_privacy_camera_turned_on_dialog_title (8039095295100075952) -->
- <skip />
- <!-- no translation found for sensor_privacy_camera_turned_off_dialog_title (1936603903120742696) -->
- <skip />
- <!-- no translation found for sensor_privacy_camera_unblocked_dialog_content (7847190103011782278) -->
- <skip />
- <!-- no translation found for sensor_privacy_camera_blocked_dialog_content (3182428709314874616) -->
- <skip />
- <!-- no translation found for sensor_privacy_htt_blocked_dialog_content (3333321592997666441) -->
- <skip />
- <!-- no translation found for sensor_privacy_dialog_open_settings (1503088305279285048) -->
- <skip />
+ <string name="sensor_privacy_mic_turned_on_dialog_title" msgid="6348853159838376513">"Imakrofoni ivuliwe"</string>
+ <string name="sensor_privacy_mic_turned_off_dialog_title" msgid="5760464281790732849">"Imakrofoni ivaliwe"</string>
+ <string name="sensor_privacy_mic_unblocked_dialog_content" msgid="4889961886199270224">"Imakrofoni inikwe amandla kuwo wonke ama-app namasevisi."</string>
+ <string name="sensor_privacy_mic_blocked_no_exception_dialog_content" msgid="5864898470772965394">"Ukufinyelela kumakrofoni kukhutshaziwe kuwo wonke ama-app namasevisi. Unganika amandla ukufinyelela kumakrofoni kokuthi Amasethingi &gt; Ubumfihlo &gt; Imakrofoni."</string>
+ <string name="sensor_privacy_mic_blocked_with_exception_dialog_content" msgid="810289713700437896">"Ukufinyelela kumakrofoni kukhutshaziwe kuwo wonke ama-app namasevisi. Ungashintsha lokhu kokuthi Amasethingi &gt; Ubumfihlo &gt; Imakrofoni."</string>
+ <string name="sensor_privacy_camera_turned_on_dialog_title" msgid="8039095295100075952">"Ikhamera ivuliwe"</string>
+ <string name="sensor_privacy_camera_turned_off_dialog_title" msgid="1936603903120742696">"Ikhamera ivaliwe"</string>
+ <string name="sensor_privacy_camera_unblocked_dialog_content" msgid="7847190103011782278">"Ikhamera inikwe amandla kuwo wonke ama-app namasevisi."</string>
+ <string name="sensor_privacy_camera_blocked_dialog_content" msgid="3182428709314874616">"Ukufinyelela kukhamera kukhutshaziwe kuwo wonke ama-app namasevisi."</string>
+ <string name="sensor_privacy_htt_blocked_dialog_content" msgid="3333321592997666441">"Ukuze usebenzise inkinobho yemakrofoni, nika amandla ukufinyelela kumakrofoni kokuthi Amasethingi."</string>
+ <string name="sensor_privacy_dialog_open_settings" msgid="1503088305279285048">"Vula izilungiselelo."</string>
<string name="media_seamless_other_device" msgid="4654849800789196737">"Enye idivayisi"</string>
<string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Guqula ukubuka konke"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Ngeke uphazanyiswe imisindo nokudlidliza, ngaphandle kusukela kuma-alamu, izikhumbuzi, imicimbi, nabafonayo obacacisayo. Usazozwa noma yini okhetha ukuyidlala okufaka umculo, amavidiyo, namageyimu."</string>
@@ -397,16 +391,11 @@
<string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"Uma wabelana, urekhoda, noma usakaza i-app, i-<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> inokufinyelela kunoma yini eboniswayo noma edlalwayo kuleyo app. Ngakho-ke qaphela amagama ayimfihlo, imininingwane yokukhokha, imiyalezo, noma olunye ulwazi olubucayi."</string>
<string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"Qhubeka"</string>
<string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"Yabelana noma rekhoda i-app"</string>
- <!-- no translation found for media_projection_permission_dialog_system_service_title (6827129613741303726) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_entire_screen (8801616203805837575) -->
- <skip />
- <!-- no translation found for media_projection_permission_dialog_system_service_warning_single_app (543310680568419338) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_title (2113331792064527203) -->
- <skip />
- <!-- no translation found for screen_capturing_disabled_by_policy_dialog_description (6015975736747696431) -->
- <skip />
+ <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"Vumela le-app ukwabelana noma ukurekhoda?"</string>
+ <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"Uma wabelana, urekhoda, noma usakaza, le-app inokufinyelela kunoma yini ebonakalayo kusikrini sakho noma edlalwa kudivayisi yakho. Ngakho-ke qaphela amagama ayimfihlo, imininingwane yokukhokha, imiyalezo, noma olunye ulwazi olubucayi."</string>
+ <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"Uma wabelana, urekhoda, noma usakaza i-app, le-app inokufinyelela kunoma yini eboniswayo noma edlalwayo kuleyo app. Ngakho-ke qaphela amagama ayimfihlo, imininingwane yokukhokha, imiyalezo, noma olunye ulwazi olubucayi."</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Kuvinjelwe ngumlawuli wakho we-IT"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"Ukuthwebula isikrini kukhutshazwe yinqubomgomo yedivayisi"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Sula konke"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Phatha"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Umlando"</string>
@@ -522,7 +511,8 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Vula ukuze usebenzise"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Kube khona inkinga yokuthola amakhadi akho, sicela uzame futhi ngemuva kwesikhathi"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Amasethingi okukhiya isikrini"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"Skena ikhodi ye-QR"</string>
+ <!-- no translation found for qr_code_scanner_title (1938155688725760702) -->
+ <skip />
<string name="status_bar_work" msgid="5238641949837091056">"Iphrofayela yomsebenzi"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Imodi yendiza"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Ngeke uzwe i-alamu yakho elandelayo ngo-<xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -805,6 +795,8 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Khulisa isikrini esigcwele"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Khulisa ingxenye eyesikrini"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Iswishi"</string>
+ <!-- no translation found for magnification_drag_corner_to_resize (1249766311052418130) -->
+ <skip />
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Vumela ukuskrola oku-diagonal"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Shintsha usayizi"</string>
<string name="accessibility_change_magnification_type" msgid="666000085077432421">"Shintsha uhlobo lokukhuliswa"</string>
@@ -1035,4 +1027,8 @@
<string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"Vumela i-<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> ukuba ifinyelele wonke amalogu edivayisi?"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"Vumela ukufinyelela kwesikhathi esisodwa"</string>
+ <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Ungavumeli"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"Amalogu edivayisi arekhoda okwenzekayo kudivayisi yakho. Ama-app angasebenzisa lawa malogu ukuze athole futhi alungise izinkinga.\n\nAmanye amalogu angase aqukathe ulwazi olubucayi, ngakho vumela ama-app owathembayo kuphela ukuthi afinyelele wonke amalogu edivayisi. \n\nUma ungayivumeli le app ukuthi ifinyelele wonke amalogu wedivayisi, isengakwazi ukufinyelela amalogu wayo. Umkhiqizi wedivayisi yakho usengakwazi ukufinyelela amanye amalogu noma ulwazi kudivayisi yakho."</string>
</resources>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 9eafdb959f07..4cf09ab46684 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1377,6 +1377,9 @@
<!-- QR Code Scanner label, title [CHAR LIMIT=32] -->
<string name="qr_code_scanner_title">QR code scanner</string>
+ <!-- QR Code Scanner Secondary label when GMS Core is Updating -->
+ <string name="qr_code_scanner_updating_secondary_label">Updating</string>
+
<!-- Name of the work status bar icon. -->
<string name="status_bar_work">Work profile</string>
@@ -2798,4 +2801,50 @@
<!-- Learn more URL for the log access confirmation dialog. [DO NOT TRANSLATE]-->
<string name="log_access_confirmation_learn_more" translatable="false">&lt;a href="https://support.google.com/android?p=system_logs#topic=7313011"&gt;Learn more&lt;/a&gt;</string>
+
+ <!--
+ Template for an action that opens a specific app. [CHAR LIMIT=16]
+ -->
+ <string name="keyguard_affordance_enablement_dialog_action_template">Open <xliff:g id="appName" example="Wallet">%1$s</xliff:g></string>
+
+ <!--
+ Template for a message shown right before a list of instructions that tell the user what to do
+ in order to enable a shortcut to a specific app. [CHAR LIMIT=NONE]
+ -->
+ <string name="keyguard_affordance_enablement_dialog_message">To add the <xliff:g id="appName" example="Wallet">%1$s</xliff:g> app as a shortcut, make sure</string>
+
+ <!--
+ Requirement for the wallet app to be available for the user to use. This is shown as part of a
+ bulleted list of requirements. When all requirements are met, the app can be accessed through a
+ shortcut button on the lock screen. [CHAR LIMIT=NONE].
+ -->
+ <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1">&#8226; The app is set up</string>
+
+ <!--
+ Requirement for the wallet app to be available for the user to use. This is shown as part of a
+ bulleted list of requirements. When all requirements are met, the app can be accessed through a
+ shortcut button on the lock screen. [CHAR LIMIT=NONE].
+ -->
+ <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2">&#8226; At least one card has been added to Wallet</string>
+
+ <!--
+ Requirement for the QR code scanner functionality to be available for the user to use. This is
+ shown as part of a bulleted list of requirements. When all requirements are met, the piece of
+ functionality can be accessed through a shortcut button on the lock screen. [CHAR LIMIT=NONE].
+ -->
+ <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction">&#8226; Install a camera app</string>
+
+ <!--
+ Requirement for the home app to be available for the user to use. This is shown as part of a
+ bulleted list of requirements. When all requirements are met, the app can be accessed through a
+ shortcut button on the lock screen. [CHAR LIMIT=NONE].
+ -->
+ <string name="keyguard_affordance_enablement_dialog_home_instruction_1">&#8226; The app is set up</string>
+
+ <!--
+ Requirement for the home app to be available for the user to use. This is shown as part of a
+ bulleted list of requirements. When all requirements are met, the app can be accessed through a
+ shortcut button on the lock screen. [CHAR LIMIT=NONE].
+ -->
+ <string name="keyguard_affordance_enablement_dialog_home_instruction_2">&#8226; At least one device is available</string>
</resources>
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/keyguard/data/content/KeyguardQuickAffordanceProviderContract.kt b/packages/SystemUI/shared/src/com/android/systemui/shared/keyguard/data/content/KeyguardQuickAffordanceProviderContract.kt
index 71469a363f74..98d8d3eb9a4a 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/keyguard/data/content/KeyguardQuickAffordanceProviderContract.kt
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/keyguard/data/content/KeyguardQuickAffordanceProviderContract.kt
@@ -67,6 +67,8 @@ object KeyguardQuickAffordanceProviderContract {
object AffordanceTable {
const val TABLE_NAME = "affordances"
val URI: Uri = BASE_URI.buildUpon().path(TABLE_NAME).build()
+ const val ENABLEMENT_INSTRUCTIONS_DELIMITER = "]["
+ const val COMPONENT_NAME_SEPARATOR = "/"
object Columns {
/** String. Unique ID for this affordance. */
@@ -78,6 +80,25 @@ object KeyguardQuickAffordanceProviderContract {
* ID from the system UI package.
*/
const val ICON = "icon"
+ /** Integer. `1` if the affordance is enabled or `0` if it disabled. */
+ const val IS_ENABLED = "is_enabled"
+ /**
+ * String. List of strings, delimited by [ENABLEMENT_INSTRUCTIONS_DELIMITER] to be shown
+ * to the user if the affordance is disabled and the user selects the affordance. The
+ * first one is a title while the rest are the steps needed to re-enable the affordance.
+ */
+ const val ENABLEMENT_INSTRUCTIONS = "enablement_instructions"
+ /**
+ * String. Optional label for a button that, when clicked, opens a destination activity
+ * where the user can re-enable the disabled affordance.
+ */
+ const val ENABLEMENT_ACTION_TEXT = "enablement_action_text"
+ /**
+ * String. Optional package name and activity action string, delimited by
+ * [COMPONENT_NAME_SEPARATOR] to use with an `Intent` to start an activity that opens a
+ * destination where the user can re-enable the disabled affordance.
+ */
+ const val ENABLEMENT_COMPONENT_NAME = "enablement_action_intent"
}
}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/navigationbar/RegionSamplingHelper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/navigationbar/RegionSamplingHelper.java
index cbd0875d2b2c..9999f08ee03c 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/navigationbar/RegionSamplingHelper.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/navigationbar/RegionSamplingHelper.java
@@ -117,7 +117,7 @@ public class RegionSamplingHelper implements View.OnAttachStateChangeListener,
@Override
public void onSampleCollected(float medianLuma) {
if (mSamplingEnabled) {
- updateMediaLuma(medianLuma);
+ updateMedianLuma(medianLuma);
}
}
};
@@ -261,7 +261,7 @@ public class RegionSamplingHelper implements View.OnAttachStateChangeListener,
}
}
- private void updateMediaLuma(float medianLuma) {
+ private void updateMedianLuma(float medianLuma) {
mCurrentMedianLuma = medianLuma;
// If the difference between the new luma and the current luma is larger than threshold
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardConstants.java b/packages/SystemUI/src/com/android/keyguard/KeyguardConstants.java
index b2658c9f9bdb..a5b62b6e7c64 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardConstants.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardConstants.java
@@ -29,5 +29,4 @@ public class KeyguardConstants {
*/
public static final boolean DEBUG = Log.isLoggable("Keyguard", Log.DEBUG);
public static final boolean DEBUG_SIM_STATES = true;
- public static final boolean DEBUG_BIOMETRIC_WAKELOCK = true;
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index ce22a81befb5..39ade347dd9b 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -829,6 +829,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
+ " triggered while waiting for cancellation, removing watchdog");
mHandler.removeCallbacks(mFpCancelNotReceived);
}
+ mLogger.d("handleFingerprintAuthFailed");
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
if (cb != null) {
@@ -958,6 +959,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
stopListeningForFace(FACE_AUTH_STOPPED_FP_LOCKED_OUT);
}
+ mLogger.logFingerprintError(msgId, errString);
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
if (cb != null) {
@@ -3887,6 +3889,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
pw.println(" listening: actual=" + mFaceRunningState
+ " expected=(" + (shouldListenForFace() ? 1 : 0));
pw.println(" strongAuthFlags=" + Integer.toHexString(strongAuthFlags));
+ pw.println(" isNonStrongBiometricAllowedAfterIdleTimeout="
+ + mStrongAuthTracker.isNonStrongBiometricAllowedAfterIdleTimeout(userId));
pw.println(" trustManaged=" + getUserTrustIsManaged(userId));
pw.println(" mFaceLockedOutPermanent=" + mFaceLockedOutPermanent);
pw.println(" enabledByUser=" + mBiometricEnabledForUser.get(userId));
diff --git a/packages/SystemUI/src/com/android/keyguard/logging/BiometricMessageDeferralLogger.kt b/packages/SystemUI/src/com/android/keyguard/logging/BiometricMessageDeferralLogger.kt
index 6264ce7273f1..2bb75aa34c6a 100644
--- a/packages/SystemUI/src/com/android/keyguard/logging/BiometricMessageDeferralLogger.kt
+++ b/packages/SystemUI/src/com/android/keyguard/logging/BiometricMessageDeferralLogger.kt
@@ -17,7 +17,7 @@
package com.android.keyguard.logging
import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.log.dagger.BiometricMessagesLog
+import com.android.systemui.log.dagger.BiometricLog
import com.android.systemui.plugins.log.LogBuffer
import com.android.systemui.plugins.log.LogLevel.DEBUG
import javax.inject.Inject
@@ -26,7 +26,7 @@ import javax.inject.Inject
@SysUISingleton
class FaceMessageDeferralLogger
@Inject
-constructor(@BiometricMessagesLog private val logBuffer: LogBuffer) :
+constructor(@BiometricLog private val logBuffer: LogBuffer) :
BiometricMessageDeferralLogger(logBuffer, "FaceMessageDeferralLogger")
open class BiometricMessageDeferralLogger(
diff --git a/packages/SystemUI/src/com/android/keyguard/logging/BiometricUnlockLogger.kt b/packages/SystemUI/src/com/android/keyguard/logging/BiometricUnlockLogger.kt
new file mode 100644
index 000000000000..bc0bd8c53d26
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/logging/BiometricUnlockLogger.kt
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.keyguard.logging
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.log.dagger.BiometricLog
+import com.android.systemui.plugins.log.LogBuffer
+import com.android.systemui.plugins.log.LogLevel
+import com.android.systemui.plugins.log.LogLevel.DEBUG
+import com.android.systemui.plugins.log.LogLevel.INFO
+import com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_DISMISS_BOUNCER
+import com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_NONE
+import com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_ONLY_WAKE
+import com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_SHOW_BOUNCER
+import com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_UNLOCK_COLLAPSING
+import com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_WAKE_AND_UNLOCK
+import com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_WAKE_AND_UNLOCK_FROM_DREAM
+import com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_WAKE_AND_UNLOCK_PULSING
+import com.google.errorprone.annotations.CompileTimeConstant
+import javax.inject.Inject
+
+private const val TAG = "BiometricUnlockLogger"
+
+/** Helper class for logging for [com.android.systemui.statusbar.phone.BiometricUnlockController] */
+@SysUISingleton
+class BiometricUnlockLogger @Inject constructor(@BiometricLog private val logBuffer: LogBuffer) {
+ fun i(@CompileTimeConstant msg: String) = log(msg, INFO)
+ fun d(@CompileTimeConstant msg: String) = log(msg, DEBUG)
+ fun log(@CompileTimeConstant msg: String, level: LogLevel) = logBuffer.log(TAG, level, msg)
+
+ fun logStartWakeAndUnlock(mode: Int) {
+ logBuffer.log(
+ TAG,
+ DEBUG,
+ { int1 = mode },
+ { "startWakeAndUnlock(${wakeAndUnlockModeToString(int1)})" }
+ )
+ }
+
+ fun logUdfpsAttemptThresholdMet(consecutiveFailedAttempts: Int) {
+ logBuffer.log(
+ TAG,
+ DEBUG,
+ { int1 = consecutiveFailedAttempts },
+ { "udfpsAttemptThresholdMet consecutiveFailedAttempts=$int1" }
+ )
+ }
+
+ fun logCalculateModeForFingerprintUnlockingAllowed(
+ deviceInteractive: Boolean,
+ keyguardShowing: Boolean,
+ deviceDreaming: Boolean
+ ) {
+ logBuffer.log(
+ TAG,
+ DEBUG,
+ {
+ bool1 = deviceInteractive
+ bool2 = keyguardShowing
+ bool3 = deviceDreaming
+ },
+ {
+ "calculateModeForFingerprint unlockingAllowed=true" +
+ " deviceInteractive=$bool1 isKeyguardShowing=$bool2" +
+ " deviceDreaming=$bool3"
+ }
+ )
+ }
+
+ fun logCalculateModeForFingerprintUnlockingNotAllowed(
+ strongBiometric: Boolean,
+ strongAuthFlags: Int,
+ nonStrongBiometricAllowed: Boolean,
+ deviceInteractive: Boolean,
+ keyguardShowing: Boolean
+ ) {
+ logBuffer.log(
+ TAG,
+ DEBUG,
+ {
+ int1 = strongAuthFlags
+ bool1 = strongBiometric
+ bool2 = nonStrongBiometricAllowed
+ bool3 = deviceInteractive
+ bool4 = keyguardShowing
+ },
+ {
+ "calculateModeForFingerprint unlockingAllowed=false" +
+ " strongBiometric=$bool1 strongAuthFlags=$int1" +
+ " nonStrongBiometricAllowed=$bool2" +
+ " deviceInteractive=$bool3 isKeyguardShowing=$bool4"
+ }
+ )
+ }
+
+ fun logCalculateModeForPassiveAuthUnlockingAllowed(
+ deviceInteractive: Boolean,
+ keyguardShowing: Boolean,
+ deviceDreaming: Boolean,
+ bypass: Boolean
+ ) {
+ logBuffer.log(
+ TAG,
+ DEBUG,
+ {
+ bool1 = deviceInteractive
+ bool2 = keyguardShowing
+ bool3 = deviceDreaming
+ bool4 = bypass
+ },
+ {
+ "calculateModeForPassiveAuth unlockingAllowed=true" +
+ " deviceInteractive=$bool1 isKeyguardShowing=$bool2" +
+ " deviceDreaming=$bool3 bypass=$bool4"
+ }
+ )
+ }
+
+ fun logCalculateModeForPassiveAuthUnlockingNotAllowed(
+ strongBiometric: Boolean,
+ strongAuthFlags: Int,
+ nonStrongBiometricAllowed: Boolean,
+ deviceInteractive: Boolean,
+ keyguardShowing: Boolean,
+ bypass: Boolean
+ ) {
+ logBuffer.log(
+ TAG,
+ DEBUG,
+ {
+ int1 = if (strongBiometric) 1 else 0
+ int2 = strongAuthFlags
+ bool1 = nonStrongBiometricAllowed
+ bool2 = deviceInteractive
+ bool3 = keyguardShowing
+ bool4 = bypass
+ },
+ {
+ "calculateModeForPassiveAuth unlockingAllowed=false" +
+ " strongBiometric=${int1 == 1}" +
+ " strongAuthFlags=$int2 nonStrongBiometricAllowed=$bool1" +
+ " deviceInteractive=$bool2 isKeyguardShowing=$bool3 bypass=$bool4"
+ }
+ )
+ }
+}
+
+private fun wakeAndUnlockModeToString(mode: Int): String {
+ return when (mode) {
+ MODE_NONE -> "MODE_NONE"
+ MODE_WAKE_AND_UNLOCK -> "MODE_WAKE_AND_UNLOCK"
+ MODE_WAKE_AND_UNLOCK_PULSING -> "MODE_WAKE_AND_UNLOCK_PULSING"
+ MODE_SHOW_BOUNCER -> "MODE_SHOW_BOUNCER"
+ MODE_ONLY_WAKE -> "MODE_ONLY_WAKE"
+ MODE_UNLOCK_COLLAPSING -> "MODE_UNLOCK_COLLAPSING"
+ MODE_WAKE_AND_UNLOCK_FROM_DREAM -> "MODE_WAKE_AND_UNLOCK_FROM_DREAM"
+ MODE_DISMISS_BOUNCER -> "MODE_DISMISS_BOUNCER"
+ else -> "UNKNOWN{$mode}"
+ }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt b/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt
index 676370093aee..1f6441a47092 100644
--- a/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt
+++ b/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt
@@ -161,6 +161,13 @@ class KeyguardUpdateMonitorLogger @Inject constructor(
}, {"Fingerprint auth successful: userId: $int1, isStrongBiometric: $bool1"})
}
+ fun logFingerprintError(msgId: Int, originalErrMsg: String) {
+ logBuffer.log(TAG, DEBUG, {
+ str1 = originalErrMsg
+ int1 = msgId
+ }, { "Fingerprint error received: $str1 msgId= $int1" })
+ }
+
fun logInvalidSubId(subId: Int) {
logBuffer.log(TAG, INFO,
{ int1 = subId },
diff --git a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsController.kt b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsController.kt
index 31fadb13db08..2f49c3fe863e 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsController.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsController.kt
@@ -24,6 +24,7 @@ import com.android.systemui.controls.ControlStatus
import com.android.systemui.util.UserAwareController
import com.android.systemui.controls.management.ControlsFavoritingActivity
import com.android.systemui.controls.ui.ControlsUiController
+import com.android.systemui.controls.ui.SelectedItem
import java.util.function.Consumer
/**
@@ -184,8 +185,8 @@ interface ControlsController : UserAwareController {
*/
fun countFavoritesForComponent(componentName: ComponentName): Int
- /** See [ControlsUiController.getPreferredStructure]. */
- fun getPreferredStructure(): StructureInfo
+ /** See [ControlsUiController.getPreferredSelectedItem]. */
+ fun getPreferredSelection(): SelectedItem
/**
* Interface for structure to pass data to [ControlsFavoritingActivity].
diff --git a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsControllerImpl.kt
index 9e20b467e661..870649d41b4e 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsControllerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsControllerImpl.kt
@@ -39,6 +39,7 @@ import com.android.systemui.controls.ControlStatus
import com.android.systemui.controls.ControlsServiceInfo
import com.android.systemui.controls.management.ControlsListingController
import com.android.systemui.controls.ui.ControlsUiController
+import com.android.systemui.controls.ui.SelectedItem
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dump.DumpManager
@@ -558,8 +559,8 @@ class ControlsControllerImpl @Inject constructor (
)
}
- override fun getPreferredStructure(): StructureInfo {
- return uiController.getPreferredStructure(getFavorites())
+ override fun getPreferredSelection(): SelectedItem {
+ return uiController.getPreferredSelectedItem(getFavorites())
}
override fun dump(pw: PrintWriter, args: Array<out String>) {
diff --git a/packages/SystemUI/src/com/android/systemui/controls/controller/StructureInfo.kt b/packages/SystemUI/src/com/android/systemui/controls/controller/StructureInfo.kt
index 34bfa135f0c8..c8090bfb60e8 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/controller/StructureInfo.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/controller/StructureInfo.kt
@@ -31,4 +31,9 @@ data class StructureInfo(
val componentName: ComponentName,
val structure: CharSequence,
val controls: List<ControlInfo>
-)
+) {
+ companion object {
+ val EMPTY_COMPONENT = ComponentName("", "")
+ val EMPTY_STRUCTURE = StructureInfo(EMPTY_COMPONENT, "", mutableListOf())
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/AppAdapter.kt b/packages/SystemUI/src/com/android/systemui/controls/management/AppAdapter.kt
index 2389ad134c55..753d5addeb11 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/AppAdapter.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/AppAdapter.kt
@@ -64,7 +64,8 @@ class AppAdapter(
val localeComparator = compareBy<ControlsServiceInfo, CharSequence>(collator) {
it.loadLabel() ?: ""
}
- listOfServices = serviceInfos.sortedWith(localeComparator)
+ listOfServices = serviceInfos.filter { it.panelActivity == null }
+ .sortedWith(localeComparator)
uiExecutor.execute(::notifyDataSetChanged)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsActivity.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsActivity.kt
index d3b5d0edd222..bd704c1ff086 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsActivity.kt
@@ -27,10 +27,13 @@ import android.view.View
import android.view.ViewGroup
import android.view.WindowInsets
import android.view.WindowInsets.Type
+import android.view.WindowManager
import androidx.activity.ComponentActivity
import com.android.systemui.R
import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.controls.management.ControlsAnimations
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
import javax.inject.Inject
/**
@@ -44,6 +47,7 @@ class ControlsActivity @Inject constructor(
private val uiController: ControlsUiController,
private val broadcastDispatcher: BroadcastDispatcher,
private val dreamManager: IDreamManager,
+ private val featureFlags: FeatureFlags
) : ComponentActivity() {
private lateinit var parent: ViewGroup
@@ -52,6 +56,9 @@ class ControlsActivity @Inject constructor(
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
+ if (featureFlags.isEnabled(Flags.USE_APP_PANELS)) {
+ window.addPrivateFlags(WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY)
+ }
setContentView(R.layout.controls_fullscreen)
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiController.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiController.kt
index c1cfbcb0c211..f5c5905779a1 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiController.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiController.kt
@@ -35,7 +35,7 @@ interface ControlsUiController {
/**
* Returns the preferred activity to start, depending on if the user has favorited any
- * controls.
+ * controls or whether there are any app providing panels.
*/
fun resolveActivity(): Class<*>
@@ -53,9 +53,43 @@ interface ControlsUiController {
)
/**
- * Returns the structure that is currently preferred by the user.
+ * Returns the element that is currently preferred by the user.
*
- * This structure will be the one that appears when the user first opens the controls activity.
+ * This element will be the one that appears when the user first opens the controls activity.
*/
- fun getPreferredStructure(structures: List<StructureInfo>): StructureInfo
+ fun getPreferredSelectedItem(structures: List<StructureInfo>): SelectedItem
}
+
+sealed class SelectedItem {
+
+ abstract val name: CharSequence
+ abstract val hasControls: Boolean
+ abstract val componentName: ComponentName
+
+ /**
+ * Represents the currently selected item for a structure.
+ */
+ data class StructureItem(val structure: StructureInfo) : SelectedItem() {
+ override val name: CharSequence = structure.structure
+ override val hasControls: Boolean = structure.controls.isNotEmpty()
+ override val componentName: ComponentName = structure.componentName
+ }
+
+ /**
+ * Represents the currently selected item for a service that provides a panel activity.
+ *
+ * The [componentName] is that of the service, as that is the expected identifier that should
+ * not change (to always provide proper migration).
+ */
+ data class PanelItem(
+ val appName: CharSequence,
+ override val componentName:
+ ComponentName
+ ) : SelectedItem() {
+ override val name: CharSequence = appName
+ override val hasControls: Boolean = true
+ }
+ companion object {
+ val EMPTY_SELECTION: SelectedItem = StructureItem(StructureInfo.EMPTY_STRUCTURE)
+ }
+} \ No newline at end of file
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 6cb0e8b04869..4c8e1ac968f9 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
@@ -21,6 +21,7 @@ import android.animation.AnimatorListenerAdapter
import android.animation.ObjectAnimator
import android.app.Activity
import android.app.ActivityOptions
+import android.app.PendingIntent
import android.content.ComponentName
import android.content.Context
import android.content.Intent
@@ -36,18 +37,22 @@ import android.view.animation.AccelerateInterpolator
import android.view.animation.DecelerateInterpolator
import android.widget.AdapterView
import android.widget.ArrayAdapter
+import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.ListPopupWindow
import android.widget.Space
import android.widget.TextView
+import androidx.annotation.VisibleForTesting
+import com.android.systemui.Dumpable
import com.android.systemui.R
import com.android.systemui.controls.ControlsMetricsLogger
import com.android.systemui.controls.ControlsServiceInfo
import com.android.systemui.controls.CustomIconCache
-import com.android.systemui.controls.controller.ControlInfo
import com.android.systemui.controls.controller.ControlsController
import com.android.systemui.controls.controller.StructureInfo
+import com.android.systemui.controls.controller.StructureInfo.Companion.EMPTY_COMPONENT
+import com.android.systemui.controls.controller.StructureInfo.Companion.EMPTY_STRUCTURE
import com.android.systemui.controls.management.ControlAdapter
import com.android.systemui.controls.management.ControlsEditingActivity
import com.android.systemui.controls.management.ControlsFavoritingActivity
@@ -56,16 +61,21 @@ import com.android.systemui.controls.management.ControlsProviderSelectorActivity
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.dump.DumpManager
import com.android.systemui.globalactions.GlobalActionsPopupMenu
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.settings.UserFileManager
import com.android.systemui.settings.UserTracker
-import com.android.systemui.shade.ShadeController
import com.android.systemui.statusbar.policy.DeviceControlsControllerImpl
import com.android.systemui.statusbar.policy.KeyguardStateController
+import com.android.systemui.util.asIndenting
import com.android.systemui.util.concurrency.DelayableExecutor
+import com.android.systemui.util.indentIfPossible
+import com.android.wm.shell.TaskViewFactory
import dagger.Lazy
+import java.io.PrintWriter
import java.text.Collator
+import java.util.Optional
import java.util.function.Consumer
import javax.inject.Inject
@@ -80,39 +90,34 @@ class ControlsUiControllerImpl @Inject constructor (
val controlsListingController: Lazy<ControlsListingController>,
val controlActionCoordinator: ControlActionCoordinator,
private val activityStarter: ActivityStarter,
- private val shadeController: ShadeController,
private val iconCache: CustomIconCache,
private val controlsMetricsLogger: ControlsMetricsLogger,
private val keyguardStateController: KeyguardStateController,
private val userFileManager: UserFileManager,
private val userTracker: UserTracker,
-) : ControlsUiController {
+ private val taskViewFactory: Optional<TaskViewFactory>,
+ dumpManager: DumpManager
+) : ControlsUiController, Dumpable {
companion object {
private const val PREF_COMPONENT = "controls_component"
- private const val PREF_STRUCTURE = "controls_structure"
+ private const val PREF_STRUCTURE_OR_APP_NAME = "controls_structure"
+ private const val PREF_IS_PANEL = "controls_is_panel"
private const val FADE_IN_MILLIS = 200L
-
- private val EMPTY_COMPONENT = ComponentName("", "")
- private val EMPTY_STRUCTURE = StructureInfo(
- EMPTY_COMPONENT,
- "",
- mutableListOf<ControlInfo>()
- )
}
- private var selectedStructure: StructureInfo = EMPTY_STRUCTURE
+ private var selectedItem: SelectedItem = SelectedItem.EMPTY_SELECTION
private lateinit var allStructures: List<StructureInfo>
private val controlsById = mutableMapOf<ControlKey, ControlWithState>()
private val controlViewsById = mutableMapOf<ControlKey, ControlViewHolder>()
private lateinit var parent: ViewGroup
- private lateinit var lastItems: List<SelectionItem>
private var popup: ListPopupWindow? = null
private var hidden = true
private lateinit var onDismiss: Runnable
private val popupThemedContext = ContextThemeWrapper(context, R.style.Control_ListPopupWindow)
private var retainCache = false
+ private var lastSelections = emptyList<SelectionItem>()
private val sharedPreferences
get() = userFileManager.getSharedPreferences(
fileName = DeviceControlsControllerImpl.PREFS_CONTROLS_FILE,
@@ -120,6 +125,8 @@ class ControlsUiControllerImpl @Inject constructor (
userId = userTracker.userId
)
+ private var taskViewController: PanelTaskViewController? = null
+
private val collator = Collator.getInstance(context.resources.configuration.locales[0])
private val localeComparator = compareBy<SelectionItem, CharSequence>(collator) {
it.getTitle()
@@ -128,10 +135,12 @@ class ControlsUiControllerImpl @Inject constructor (
private val onSeedingComplete = Consumer<Boolean> {
accepted ->
if (accepted) {
- selectedStructure = controlsController.get().getFavorites().maxByOrNull {
+ selectedItem = controlsController.get().getFavorites().maxByOrNull {
it.controls.size
- } ?: EMPTY_STRUCTURE
- updatePreferences(selectedStructure)
+ }?.let {
+ SelectedItem.StructureItem(it)
+ } ?: SelectedItem.EMPTY_SELECTION
+ updatePreferences(selectedItem)
}
reload(parent)
}
@@ -139,6 +148,10 @@ class ControlsUiControllerImpl @Inject constructor (
private lateinit var activityContext: Context
private lateinit var listingCallback: ControlsListingController.ControlsListingCallback
+ init {
+ dumpManager.registerDumpable(javaClass.name, this)
+ }
+
private fun createCallback(
onResult: (List<SelectionItem>) -> Unit
): ControlsListingController.ControlsListingCallback {
@@ -146,7 +159,15 @@ class ControlsUiControllerImpl @Inject constructor (
override fun onServicesUpdated(serviceInfos: List<ControlsServiceInfo>) {
val lastItems = serviceInfos.map {
val uid = it.serviceInfo.applicationInfo.uid
- SelectionItem(it.loadLabel(), "", it.loadIcon(), it.componentName, uid)
+
+ SelectionItem(
+ it.loadLabel(),
+ "",
+ it.loadIcon(),
+ it.componentName,
+ uid,
+ it.panelActivity
+ )
}
uiExecutor.execute {
parent.removeAllViews()
@@ -160,11 +181,13 @@ class ControlsUiControllerImpl @Inject constructor (
override fun resolveActivity(): Class<*> {
val allStructures = controlsController.get().getFavorites()
- val selectedStructure = getPreferredStructure(allStructures)
+ val selected = getPreferredSelectedItem(allStructures)
+ val anyPanels = controlsListingController.get().getCurrentServices()
+ .none { it.panelActivity != null }
return if (controlsController.get().addSeedingFavoritesCallback(onSeedingComplete)) {
ControlsActivity::class.java
- } else if (selectedStructure.controls.isEmpty() && allStructures.size <= 1) {
+ } else if (!selected.hasControls && allStructures.size <= 1 && !anyPanels) {
ControlsProviderSelectorActivity::class.java
} else {
ControlsActivity::class.java
@@ -186,31 +209,49 @@ class ControlsUiControllerImpl @Inject constructor (
controlActionCoordinator.activityContext = activityContext
allStructures = controlsController.get().getFavorites()
- selectedStructure = getPreferredStructure(allStructures)
+ selectedItem = getPreferredSelectedItem(allStructures)
if (controlsController.get().addSeedingFavoritesCallback(onSeedingComplete)) {
listingCallback = createCallback(::showSeedingView)
- } else if (selectedStructure.controls.isEmpty() && allStructures.size <= 1) {
+ } else if (
+ selectedItem !is SelectedItem.PanelItem &&
+ !selectedItem.hasControls &&
+ allStructures.size <= 1
+ ) {
// only show initial view if there are really no favorites across any structure
- listingCallback = createCallback(::showInitialSetupView)
+ listingCallback = createCallback(::initialView)
} else {
- selectedStructure.controls.map {
- ControlWithState(selectedStructure.componentName, it, null)
- }.associateByTo(controlsById) {
- ControlKey(selectedStructure.componentName, it.ci.controlId)
+ val selected = selectedItem
+ if (selected is SelectedItem.StructureItem) {
+ selected.structure.controls.map {
+ ControlWithState(selected.structure.componentName, it, null)
+ }.associateByTo(controlsById) {
+ ControlKey(selected.structure.componentName, it.ci.controlId)
+ }
+ controlsController.get().subscribeToFavorites(selected.structure)
}
listingCallback = createCallback(::showControlsView)
- controlsController.get().subscribeToFavorites(selectedStructure)
}
controlsListingController.get().addCallback(listingCallback)
}
+ private fun initialView(items: List<SelectionItem>) {
+ if (items.any { it.isPanel }) {
+ // We have at least a panel, so we'll end up showing that.
+ showControlsView(items)
+ } else {
+ showInitialSetupView(items)
+ }
+ }
+
private fun reload(parent: ViewGroup) {
if (hidden) return
controlsListingController.get().removeCallback(listingCallback)
controlsController.get().unsubscribe()
+ taskViewController?.dismiss()
+ taskViewController = null
val fadeAnim = ObjectAnimator.ofFloat(parent, "alpha", 1.0f, 0.0f)
fadeAnim.setInterpolator(AccelerateInterpolator(1.0f))
@@ -290,27 +331,90 @@ class ControlsUiControllerImpl @Inject constructor (
private fun showControlsView(items: List<SelectionItem>) {
controlViewsById.clear()
- val itemsByComponent = items.associateBy { it.componentName }
- val itemsWithStructure = mutableListOf<SelectionItem>()
- allStructures.mapNotNullTo(itemsWithStructure) {
+ val (panels, structures) = items.partition { it.isPanel }
+ val panelComponents = panels.map { it.componentName }.toSet()
+
+ val itemsByComponent = structures.associateBy { it.componentName }
+ .filterNot { it.key in panelComponents }
+ val panelsAndStructures = mutableListOf<SelectionItem>()
+ allStructures.mapNotNullTo(panelsAndStructures) {
itemsByComponent.get(it.componentName)?.copy(structure = it.structure)
}
- itemsWithStructure.sortWith(localeComparator)
+ panelsAndStructures.addAll(panels)
- val selectionItem = findSelectionItem(selectedStructure, itemsWithStructure) ?: items[0]
+ panelsAndStructures.sortWith(localeComparator)
+
+ lastSelections = panelsAndStructures
+
+ val selectionItem = findSelectionItem(selectedItem, panelsAndStructures)
+ ?: if (panels.isNotEmpty()) {
+ // If we couldn't find a good selected item, but there's at least one panel,
+ // show a panel.
+ panels[0]
+ } else {
+ items[0]
+ }
- controlsMetricsLogger.refreshBegin(selectionItem.uid, !keyguardStateController.isUnlocked())
+ maybeUpdateSelectedItem(selectionItem)
- createListView(selectionItem)
- createDropDown(itemsWithStructure, selectionItem)
+ createControlsSpaceFrame()
+
+ if (taskViewFactory.isPresent && selectionItem.isPanel) {
+ createPanelView(selectionItem.panelComponentName!!)
+ } else if (!selectionItem.isPanel) {
+ controlsMetricsLogger
+ .refreshBegin(selectionItem.uid, !keyguardStateController.isUnlocked())
+ createListView(selectionItem)
+ } else {
+ Log.w(ControlsUiController.TAG, "Not TaskViewFactory to display panel $selectionItem")
+ }
+
+ createDropDown(panelsAndStructures, selectionItem)
createMenu()
}
- private fun createMenu() {
- val items = arrayOf(
- context.resources.getString(R.string.controls_menu_add),
- context.resources.getString(R.string.controls_menu_edit)
+ private fun createPanelView(componentName: ComponentName) {
+ val pendingIntent = PendingIntent.getActivity(
+ context,
+ 0,
+ Intent().setComponent(componentName),
+ PendingIntent.FLAG_IMMUTABLE
)
+
+ parent.requireViewById<View>(R.id.controls_scroll_view).visibility = View.GONE
+ val container = parent.requireViewById<FrameLayout>(R.id.controls_panel)
+ container.visibility = View.VISIBLE
+ container.post {
+ taskViewFactory.get().create(activityContext, uiExecutor) { taskView ->
+ taskViewController = PanelTaskViewController(
+ activityContext,
+ uiExecutor,
+ pendingIntent,
+ taskView,
+ onDismiss::run
+ ).also {
+ container.addView(taskView)
+ it.launchTaskView()
+ }
+ }
+ }
+ }
+
+ private fun createMenu() {
+ val isPanel = selectedItem is SelectedItem.PanelItem
+ val selectedStructure = (selectedItem as? SelectedItem.StructureItem)?.structure
+ ?: EMPTY_STRUCTURE
+
+ val items = if (isPanel) {
+ arrayOf(
+ context.resources.getString(R.string.controls_menu_add),
+ )
+ } else {
+ arrayOf(
+ context.resources.getString(R.string.controls_menu_add),
+ context.resources.getString(R.string.controls_menu_edit)
+ )
+ }
var adapter = ArrayAdapter<String>(context, R.layout.controls_more_item, items)
val anchor = parent.requireViewById<ImageView>(R.id.controls_more)
@@ -331,7 +435,13 @@ class ControlsUiControllerImpl @Inject constructor (
) {
when (pos) {
// 0: Add Control
- 0 -> startFavoritingActivity(selectedStructure)
+ 0 -> {
+ if (isPanel) {
+ startProviderSelectorActivity()
+ } else {
+ startFavoritingActivity(selectedStructure)
+ }
+ }
// 1: Edit controls
1 -> startEditingActivity(selectedStructure)
}
@@ -353,6 +463,9 @@ class ControlsUiControllerImpl @Inject constructor (
addAll(items)
}
+ val iconSize = context.resources
+ .getDimensionPixelSize(R.dimen.controls_header_app_icon_size)
+
/*
* Default spinner widget does not work with the window type required
* for this dialog. Use a textView with the ListPopupWindow to achieve
@@ -363,14 +476,21 @@ class ControlsUiControllerImpl @Inject constructor (
// override the default color on the dropdown drawable
(getBackground() as LayerDrawable).getDrawable(0)
.setTint(context.resources.getColor(R.color.control_spinner_dropdown, null))
+ selected.icon.setBounds(0, 0, iconSize, iconSize)
+ compoundDrawablePadding = (iconSize / 2.4f).toInt()
+ setCompoundDrawablesRelative(selected.icon, null, null, null)
}
+ val anchor = parent.requireViewById<ViewGroup>(R.id.controls_header)
if (items.size == 1) {
spinner.setBackground(null)
+ anchor.setOnClickListener(null)
return
+ } else {
+ spinner.background = parent.context.resources
+ .getDrawable(R.drawable.control_spinner_background)
}
- val anchor = parent.requireViewById<ViewGroup>(R.id.controls_header)
anchor.setOnClickListener(object : View.OnClickListener {
override fun onClick(v: View) {
popup = GlobalActionsPopupMenu(
@@ -398,14 +518,20 @@ class ControlsUiControllerImpl @Inject constructor (
})
}
- private fun createListView(selected: SelectionItem) {
- val inflater = LayoutInflater.from(context)
+ private fun createControlsSpaceFrame() {
+ val inflater = LayoutInflater.from(activityContext)
inflater.inflate(R.layout.controls_with_favorites, parent, true)
parent.requireViewById<ImageView>(R.id.controls_close).apply {
setOnClickListener { _: View -> onDismiss.run() }
visibility = View.VISIBLE
}
+ }
+
+ private fun createListView(selected: SelectionItem) {
+ if (selectedItem !is SelectedItem.StructureItem) return
+ val selectedStructure = (selectedItem as SelectedItem.StructureItem).structure
+ val inflater = LayoutInflater.from(activityContext)
val maxColumns = ControlAdapter.findMaxColumns(activityContext.resources)
@@ -453,35 +579,51 @@ class ControlsUiControllerImpl @Inject constructor (
}
}
- override fun getPreferredStructure(structures: List<StructureInfo>): StructureInfo {
- if (structures.isEmpty()) return EMPTY_STRUCTURE
+ override fun getPreferredSelectedItem(structures: List<StructureInfo>): SelectedItem {
+ val sp = sharedPreferences
- val component = sharedPreferences.getString(PREF_COMPONENT, null)?.let {
+ val component = sp.getString(PREF_COMPONENT, null)?.let {
ComponentName.unflattenFromString(it)
} ?: EMPTY_COMPONENT
- val structure = sharedPreferences.getString(PREF_STRUCTURE, "")
-
- return structures.firstOrNull {
- component == it.componentName && structure == it.structure
- } ?: structures.get(0)
+ val name = sp.getString(PREF_STRUCTURE_OR_APP_NAME, "")!!
+ val isPanel = sp.getBoolean(PREF_IS_PANEL, false)
+ return if (isPanel) {
+ SelectedItem.PanelItem(name, component)
+ } else {
+ if (structures.isEmpty()) return SelectedItem.EMPTY_SELECTION
+ SelectedItem.StructureItem(structures.firstOrNull {
+ component == it.componentName && name == it.structure
+ } ?: structures.get(0))
+ }
}
- private fun updatePreferences(si: StructureInfo) {
- if (si == EMPTY_STRUCTURE) return
+ private fun updatePreferences(si: SelectedItem) {
sharedPreferences.edit()
- .putString(PREF_COMPONENT, si.componentName.flattenToString())
- .putString(PREF_STRUCTURE, si.structure.toString())
- .commit()
+ .putString(PREF_COMPONENT, si.componentName.flattenToString())
+ .putString(PREF_STRUCTURE_OR_APP_NAME, si.name.toString())
+ .putBoolean(PREF_IS_PANEL, si is SelectedItem.PanelItem)
+ .commit()
}
- private fun switchAppOrStructure(item: SelectionItem) {
- val newSelection = allStructures.first {
- it.structure == item.structure && it.componentName == item.componentName
+ private fun maybeUpdateSelectedItem(item: SelectionItem): Boolean {
+ val newSelection = if (item.isPanel) {
+ SelectedItem.PanelItem(item.appName, item.componentName)
+ } else {
+ SelectedItem.StructureItem(allStructures.firstOrNull {
+ it.structure == item.structure && it.componentName == item.componentName
+ } ?: EMPTY_STRUCTURE)
}
+ return if (newSelection != selectedItem ) {
+ selectedItem = newSelection
+ updatePreferences(selectedItem)
+ true
+ } else {
+ false
+ }
+ }
- if (newSelection != selectedStructure) {
- selectedStructure = newSelection
- updatePreferences(selectedStructure)
+ private fun switchAppOrStructure(item: SelectionItem) {
+ if (maybeUpdateSelectedItem(item)) {
reload(parent)
}
}
@@ -505,6 +647,8 @@ class ControlsUiControllerImpl @Inject constructor (
closeDialogs(true)
controlsController.get().unsubscribe()
+ taskViewController?.dismiss()
+ taskViewController = null
parent.removeAllViews()
controlsById.clear()
@@ -545,20 +689,46 @@ class ControlsUiControllerImpl @Inject constructor (
return row
}
- private fun findSelectionItem(si: StructureInfo, items: List<SelectionItem>): SelectionItem? =
- items.firstOrNull {
- it.componentName == si.componentName && it.structure == si.structure
+ private fun findSelectionItem(si: SelectedItem, items: List<SelectionItem>): SelectionItem? =
+ items.firstOrNull { it.matches(si) }
+
+ override fun dump(pw: PrintWriter, args: Array<out String>) {
+ pw.println("ControlsUiControllerImpl:")
+ pw.asIndenting().indentIfPossible {
+ println("hidden: $hidden")
+ println("selectedItem: $selectedItem")
+ println("lastSelections: $lastSelections")
}
+ }
}
-private data class SelectionItem(
+@VisibleForTesting
+internal data class SelectionItem(
val appName: CharSequence,
val structure: CharSequence,
val icon: Drawable,
val componentName: ComponentName,
- val uid: Int
+ val uid: Int,
+ val panelComponentName: ComponentName?
) {
fun getTitle() = if (structure.isEmpty()) { appName } else { structure }
+
+ val isPanel: Boolean = panelComponentName != null
+
+ fun matches(selectedItem: SelectedItem): Boolean {
+ if (componentName != selectedItem.componentName) {
+ // Not the same component so they are not the same.
+ return false
+ }
+ if (isPanel || selectedItem is SelectedItem.PanelItem) {
+ // As they have the same component, if [this.isPanel] then we may be migrating from
+ // device controls API into panel. Want this to match, even if the selectedItem is not
+ // a panel. We don't want to match on app name because that can change with locale.
+ return true
+ }
+ // Return true if we find a structure with the correct name
+ return structure == (selectedItem as SelectedItem.StructureItem).structure.structure
+ }
}
private class ItemAdapter(
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/PanelTaskViewController.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/PanelTaskViewController.kt
new file mode 100644
index 000000000000..7143be298a9d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/PanelTaskViewController.kt
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.android.systemui.controls.ui
+
+import android.app.ActivityOptions
+import android.app.ActivityTaskManager
+import android.app.ActivityTaskManager.INVALID_TASK_ID
+import android.app.PendingIntent
+import android.content.ComponentName
+import android.content.Context
+import android.content.Intent
+import com.android.systemui.util.boundsOnScreen
+import com.android.wm.shell.TaskView
+import java.util.concurrent.Executor
+
+class PanelTaskViewController(
+ private val activityContext: Context,
+ private val uiExecutor: Executor,
+ private val pendingIntent: PendingIntent,
+ private val taskView: TaskView,
+ private val hide: () -> Unit = {}
+) {
+
+ private var detailTaskId = INVALID_TASK_ID
+
+ private val fillInIntent =
+ Intent().apply {
+ // Apply flags to make behaviour match documentLaunchMode=always.
+ addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+ addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK)
+ }
+
+ private fun removeDetailTask() {
+ if (detailTaskId == INVALID_TASK_ID) return
+ ActivityTaskManager.getInstance().removeTask(detailTaskId)
+ detailTaskId = INVALID_TASK_ID
+ }
+
+ private val stateCallback =
+ object : TaskView.Listener {
+ override fun onInitialized() {
+
+ val options =
+ ActivityOptions.makeCustomAnimation(
+ activityContext,
+ 0 /* enterResId */,
+ 0 /* exitResId */
+ )
+ options.taskAlwaysOnTop = true
+
+ taskView.post {
+ taskView.startActivity(
+ pendingIntent,
+ fillInIntent,
+ options,
+ taskView.boundsOnScreen
+ )
+ }
+ }
+
+ override fun onTaskRemovalStarted(taskId: Int) {
+ detailTaskId = INVALID_TASK_ID
+ dismiss()
+ }
+
+ override fun onTaskCreated(taskId: Int, name: ComponentName?) {
+ detailTaskId = taskId
+ }
+
+ override fun onReleased() {
+ removeDetailTask()
+ }
+
+ override fun onBackPressedOnTaskRoot(taskId: Int) {
+ dismiss()
+ hide()
+ }
+ }
+
+ fun dismiss() {
+ taskView.release()
+ }
+
+ fun launchTaskView() {
+ taskView.setListener(uiExecutor, stateCallback)
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java b/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java
index 0664e9f6ac39..705a110583db 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java
@@ -56,6 +56,7 @@ import android.hardware.display.ColorDisplayManager;
import android.hardware.display.DisplayManager;
import android.hardware.face.FaceManager;
import android.hardware.fingerprint.FingerprintManager;
+import android.hardware.input.InputManager;
import android.media.AudioManager;
import android.media.IAudioService;
import android.media.MediaRouter2Manager;
@@ -291,6 +292,12 @@ public class FrameworkServicesModule {
@Provides
@Singleton
+ static InputManager provideInputManager(Context context) {
+ return context.getSystemService(InputManager.class);
+ }
+
+ @Provides
+ @Singleton
static InputMethodManager provideInputMethodManager(Context context) {
return context.getSystemService(InputMethodManager.class);
}
diff --git a/packages/SystemUI/src/com/android/systemui/dump/DumpHandler.kt b/packages/SystemUI/src/com/android/systemui/dump/DumpHandler.kt
index 609bd76cf210..a2f65ba747ab 100644
--- a/packages/SystemUI/src/com/android/systemui/dump/DumpHandler.kt
+++ b/packages/SystemUI/src/com/android/systemui/dump/DumpHandler.kt
@@ -22,7 +22,6 @@ import android.os.Trace
import com.android.systemui.CoreStartable
import com.android.systemui.R
import com.android.systemui.dump.DumpHandler.Companion.PRIORITY_ARG_CRITICAL
-import com.android.systemui.dump.DumpHandler.Companion.PRIORITY_ARG_HIGH
import com.android.systemui.dump.DumpHandler.Companion.PRIORITY_ARG_NORMAL
import com.android.systemui.dump.nano.SystemUIProtoDump
import com.android.systemui.plugins.log.LogBuffer
@@ -148,12 +147,12 @@ class DumpHandler @Inject constructor(
}
private fun dumpCritical(pw: PrintWriter, args: ParsedArgs) {
- dumpManager.dumpDumpables(pw, args.rawArgs)
+ dumpManager.dumpCritical(pw, args.rawArgs)
dumpConfig(pw)
}
private fun dumpNormal(pw: PrintWriter, args: ParsedArgs) {
- dumpManager.dumpBuffers(pw, args.tailLength)
+ dumpManager.dumpNormal(pw, args.rawArgs, args.tailLength)
logBufferEulogizer.readEulogyIfPresent(pw)
}
@@ -349,14 +348,12 @@ class DumpHandler @Inject constructor(
companion object {
const val PRIORITY_ARG = "--dump-priority"
const val PRIORITY_ARG_CRITICAL = "CRITICAL"
- const val PRIORITY_ARG_HIGH = "HIGH"
const val PRIORITY_ARG_NORMAL = "NORMAL"
const val PROTO = "--proto"
}
}
-private val PRIORITY_OPTIONS =
- arrayOf(PRIORITY_ARG_CRITICAL, PRIORITY_ARG_HIGH, PRIORITY_ARG_NORMAL)
+private val PRIORITY_OPTIONS = arrayOf(PRIORITY_ARG_CRITICAL, PRIORITY_ARG_NORMAL)
private val COMMANDS = arrayOf(
"bugreport-critical",
diff --git a/packages/SystemUI/src/com/android/systemui/dump/DumpManager.kt b/packages/SystemUI/src/com/android/systemui/dump/DumpManager.kt
index ae780896a7e2..c982131be127 100644
--- a/packages/SystemUI/src/com/android/systemui/dump/DumpManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/dump/DumpManager.kt
@@ -40,20 +40,54 @@ open class DumpManager @Inject constructor() {
private val buffers: MutableMap<String, RegisteredDumpable<LogBuffer>> = ArrayMap()
/**
- * Register a dumpable to be called during a bug report. The dumpable will be called during the
- * CRITICAL section of the bug report, so don't dump an excessive amount of stuff here.
+ * Registers a dumpable to be called during the CRITICAL section of the bug report.
+ *
+ * The CRITICAL section gets very high priority during a dump, but also a very limited amount of
+ * time to do the dumping. So, please don't dump an excessive amount of stuff using CRITICAL.
+ *
+ * See [registerDumpable].
+ */
+ fun registerCriticalDumpable(name: String, module: Dumpable) {
+ registerDumpable(name, module, DumpPriority.CRITICAL)
+ }
+
+ /**
+ * Registers a dumpable to be called during the NORMAL section of the bug report.
+ *
+ * The NORMAL section gets a lower priority during a dump, but also more time. This should be
+ * used by [LogBuffer] instances, [ProtoDumpable] instances, and any [Dumpable] instances that
+ * dump a lot of information.
+ */
+ fun registerNormalDumpable(name: String, module: Dumpable) {
+ registerDumpable(name, module, DumpPriority.NORMAL)
+ }
+
+ /**
+ * Register a dumpable to be called during a bug report.
*
* @param name The name to register the dumpable under. This is typically the qualified class
* name of the thing being dumped (getClass().getName()), but can be anything as long as it
* doesn't clash with an existing registration.
+ * @param priority the priority level of this dumpable, which affects at what point in the bug
+ * report this gets dump. By default, the dumpable will be called during the CRITICAL section of
+ * the bug report, so don't dump an excessive amount of stuff here.
+ *
+ * TODO(b/259973758): Replace all calls to this method with calls to [registerCriticalDumpable]
+ * or [registerNormalDumpable] instead.
*/
@Synchronized
- fun registerDumpable(name: String, module: Dumpable) {
+ @JvmOverloads
+ @Deprecated("Use registerCriticalDumpable or registerNormalDumpable instead")
+ fun registerDumpable(
+ name: String,
+ module: Dumpable,
+ priority: DumpPriority = DumpPriority.CRITICAL,
+ ) {
if (!canAssignToNameLocked(name, module)) {
throw IllegalArgumentException("'$name' is already registered")
}
- dumpables[name] = RegisteredDumpable(name, module)
+ dumpables[name] = RegisteredDumpable(name, module, priority)
}
/**
@@ -81,7 +115,10 @@ open class DumpManager @Inject constructor() {
if (!canAssignToNameLocked(name, buffer)) {
throw IllegalArgumentException("'$name' is already registered")
}
- buffers[name] = RegisteredDumpable(name, buffer)
+
+ // All buffers must be priority NORMAL, not CRITICAL, because they often contain a lot of
+ // data.
+ buffers[name] = RegisteredDumpable(name, buffer, DumpPriority.NORMAL)
}
/**
@@ -140,7 +177,35 @@ open class DumpManager @Inject constructor() {
}
/**
- * Dumps all registered dumpables to [pw]
+ * Dumps all registered dumpables with critical priority to [pw]
+ */
+ @Synchronized
+ fun dumpCritical(pw: PrintWriter, args: Array<String>) {
+ for (dumpable in dumpables.values) {
+ if (dumpable.priority == DumpPriority.CRITICAL) {
+ dumpDumpable(dumpable, pw, args)
+ }
+ }
+ }
+
+ /**
+ * To [pw], dumps (1) all registered dumpables with normal priority; and (2) all [LogBuffer]s.
+ */
+ @Synchronized
+ fun dumpNormal(pw: PrintWriter, args: Array<String>, tailLength: Int = 0) {
+ for (dumpable in dumpables.values) {
+ if (dumpable.priority == DumpPriority.NORMAL) {
+ dumpDumpable(dumpable, pw, args)
+ }
+ }
+
+ for (buffer in buffers.values) {
+ dumpBuffer(buffer, pw, tailLength)
+ }
+ }
+
+ /**
+ * Dump all the instances of [Dumpable].
*/
@Synchronized
fun dumpDumpables(pw: PrintWriter, args: Array<String>) {
@@ -232,7 +297,15 @@ open class DumpManager @Inject constructor() {
private data class RegisteredDumpable<T>(
val name: String,
- val dumpable: T
+ val dumpable: T,
+ val priority: DumpPriority,
)
-private const val TAG = "DumpManager"
+/**
+ * The priority level for a given dumpable, which affects at what point in the bug report this gets
+ * dumped.
+ */
+enum class DumpPriority {
+ CRITICAL,
+ NORMAL,
+}
diff --git a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebugStartable.kt b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebugStartable.kt
index 62713348c789..7189f00457a4 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebugStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebugStartable.kt
@@ -35,7 +35,7 @@ constructor(
) : CoreStartable {
init {
- dumpManager.registerDumpable(FeatureFlagsDebug.TAG) { pw, args ->
+ dumpManager.registerCriticalDumpable(FeatureFlagsDebug.TAG) { pw, args ->
featureFlags.dump(pw, args)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsReleaseStartable.kt b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsReleaseStartable.kt
index e7d8cc362c56..d088d7414035 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsReleaseStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsReleaseStartable.kt
@@ -29,7 +29,7 @@ class FeatureFlagsReleaseStartable
constructor(dumpManager: DumpManager, featureFlags: FeatureFlags) : CoreStartable {
init {
- dumpManager.registerDumpable(FeatureFlagsRelease.TAG) { pw, args ->
+ dumpManager.registerCriticalDumpable(FeatureFlagsRelease.TAG) { pw, args ->
featureFlags.dump(pw, args)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
index 5dd583971c3c..e2f86bd76216 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
@@ -205,10 +205,6 @@ object Flags {
@JvmField val QS_SECONDARY_DATA_SUB_INFO = releasedFlag(508, "qs_secondary_data_sub_info")
// 600- status bar
- // TODO(b/254513246): Tracking Bug
- val STATUS_BAR_USER_SWITCHER =
- resourceBooleanFlag(602, R.bool.flag_user_switcher_chip, "status_bar_user_switcher")
-
// TODO(b/254512623): Tracking Bug
@Deprecated("Replaced by mobile and wifi specific flags.")
val NEW_STATUS_BAR_PIPELINE_BACKEND =
@@ -418,6 +414,9 @@ object Flags {
@JvmField val UDFPS_ELLIPSE_DEBUG_UI = unreleasedFlag(2201, "udfps_ellipse_debug")
@JvmField val UDFPS_ELLIPSE_DETECTION = unreleasedFlag(2202, "udfps_ellipse_detection")
+ // 2300 - stylus
+ @JvmField val TRACK_STYLUS_EVER_USED = unreleasedFlag(2300, "track_stylus_ever_used")
+
// TODO(b259590361): Tracking bug
val EXPERIMENTAL_FLAG = unreleasedFlag(2, "exp_flag_release")
}
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/MinHeightScrollView.java b/packages/SystemUI/src/com/android/systemui/globalactions/MinHeightScrollView.java
deleted file mode 100644
index 622fa658f1b0..000000000000
--- a/packages/SystemUI/src/com/android/systemui/globalactions/MinHeightScrollView.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.globalactions;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.View;
-import android.widget.ScrollView;
-
-/**
- * When measured, this view sets the minimum height of its first child to be equal to its own
- * target height.
- *
- * This ensures fall-through click handlers can be placed on this view's child component.
- */
-public class MinHeightScrollView extends ScrollView {
- public MinHeightScrollView(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- @Override
- public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- View firstChild = getChildAt(0);
- if (firstChild != null) {
- firstChild.setMinimumHeight(MeasureSpec.getSize(heightMeasureSpec));
- }
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardQuickAffordanceProvider.kt b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardQuickAffordanceProvider.kt
index bfc60c17225f..29febb6dd0d9 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardQuickAffordanceProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardQuickAffordanceProvider.kt
@@ -31,6 +31,7 @@ import com.android.systemui.SystemUIAppComponentFactoryBase.ContextAvailableCall
import com.android.systemui.keyguard.domain.interactor.KeyguardQuickAffordanceInteractor
import com.android.systemui.shared.keyguard.data.content.KeyguardQuickAffordanceProviderContract as Contract
import javax.inject.Inject
+import kotlinx.coroutines.runBlocking
class KeyguardQuickAffordanceProvider :
ContentProvider(), SystemUIAppComponentFactoryBase.ContextInitializer {
@@ -118,9 +119,9 @@ class KeyguardQuickAffordanceProvider :
sortOrder: String?,
): Cursor? {
return when (uriMatcher.match(uri)) {
- MATCH_CODE_ALL_AFFORDANCES -> queryAffordances()
+ MATCH_CODE_ALL_AFFORDANCES -> runBlocking { queryAffordances() }
MATCH_CODE_ALL_SLOTS -> querySlots()
- MATCH_CODE_ALL_SELECTIONS -> querySelections()
+ MATCH_CODE_ALL_SELECTIONS -> runBlocking { querySelections() }
MATCH_CODE_ALL_FLAGS -> queryFlags()
else -> null
}
@@ -194,7 +195,7 @@ class KeyguardQuickAffordanceProvider :
}
}
- private fun querySelections(): Cursor {
+ private suspend fun querySelections(): Cursor {
return MatrixCursor(
arrayOf(
Contract.SelectionTable.Columns.SLOT_ID,
@@ -219,12 +220,16 @@ class KeyguardQuickAffordanceProvider :
}
}
- private fun queryAffordances(): Cursor {
+ private suspend fun queryAffordances(): Cursor {
return MatrixCursor(
arrayOf(
Contract.AffordanceTable.Columns.ID,
Contract.AffordanceTable.Columns.NAME,
Contract.AffordanceTable.Columns.ICON,
+ Contract.AffordanceTable.Columns.IS_ENABLED,
+ Contract.AffordanceTable.Columns.ENABLEMENT_INSTRUCTIONS,
+ Contract.AffordanceTable.Columns.ENABLEMENT_ACTION_TEXT,
+ Contract.AffordanceTable.Columns.ENABLEMENT_COMPONENT_NAME,
)
)
.apply {
@@ -234,6 +239,12 @@ class KeyguardQuickAffordanceProvider :
representation.id,
representation.name,
representation.iconResourceId,
+ if (representation.isEnabled) 1 else 0,
+ representation.instructions?.joinToString(
+ Contract.AffordanceTable.ENABLEMENT_INSTRUCTIONS_DELIMITER
+ ),
+ representation.actionText,
+ representation.actionComponentName,
)
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfig.kt
index d6f521c6dc87..2558fab216a0 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfig.kt
@@ -20,6 +20,7 @@ package com.android.systemui.keyguard.data.quickaffordance
import android.content.Context
import android.content.Intent
import androidx.annotation.DrawableRes
+import com.android.systemui.R
import com.android.systemui.animation.Expandable
import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
@@ -45,7 +46,7 @@ import kotlinx.coroutines.flow.flowOf
class HomeControlsKeyguardQuickAffordanceConfig
@Inject
constructor(
- @Application context: Context,
+ @Application private val context: Context,
private val component: ControlsComponent,
) : KeyguardQuickAffordanceConfig {
@@ -66,6 +67,36 @@ constructor(
}
}
+ override suspend fun getPickerScreenState(): KeyguardQuickAffordanceConfig.PickerScreenState {
+ if (!component.isEnabled()) {
+ return KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice
+ }
+
+ val currentServices =
+ component.getControlsListingController().getOrNull()?.getCurrentServices()
+ val hasFavorites =
+ component.getControlsController().getOrNull()?.getFavorites()?.isNotEmpty() == true
+ if (currentServices.isNullOrEmpty() || !hasFavorites) {
+ return KeyguardQuickAffordanceConfig.PickerScreenState.Disabled(
+ instructions =
+ listOf(
+ context.getString(
+ R.string.keyguard_affordance_enablement_dialog_message,
+ pickerName,
+ ),
+ context.getString(
+ R.string.keyguard_affordance_enablement_dialog_home_instruction_1
+ ),
+ context.getString(
+ R.string.keyguard_affordance_enablement_dialog_home_instruction_2
+ ),
+ ),
+ )
+ }
+
+ return KeyguardQuickAffordanceConfig.PickerScreenState.Default
+ }
+
override fun onTriggered(
expandable: Expandable?,
): KeyguardQuickAffordanceConfig.OnTriggeredResult {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceConfig.kt
index fd40d1dd1a0e..4477310dca41 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceConfig.kt
@@ -21,6 +21,7 @@ import android.content.Intent
import com.android.systemui.animation.Expandable
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.keyguard.shared.quickaffordance.ActivationState
+import com.android.systemui.shared.keyguard.data.content.KeyguardQuickAffordanceProviderContract as Contract
import kotlinx.coroutines.flow.Flow
/** Defines interface that can act as data source for a single quick affordance model. */
@@ -41,6 +42,12 @@ interface KeyguardQuickAffordanceConfig {
val lockScreenState: Flow<LockScreenState>
/**
+ * Returns the [PickerScreenState] representing the affordance in the settings or selector
+ * experience.
+ */
+ suspend fun getPickerScreenState(): PickerScreenState = PickerScreenState.Default
+
+ /**
* Notifies that the affordance was clicked by the user.
*
* @param expandable An [Expandable] to use when animating dialogs or activities
@@ -49,6 +56,58 @@ interface KeyguardQuickAffordanceConfig {
fun onTriggered(expandable: Expandable?): OnTriggeredResult
/**
+ * Encapsulates the state of a quick affordance within the context of the settings or selector
+ * experience.
+ */
+ sealed class PickerScreenState {
+
+ /** The picker shows the item for selecting this affordance as it normally would. */
+ object Default : PickerScreenState()
+
+ /**
+ * The picker does not show an item for selecting this affordance as it is not supported on
+ * the device at all. For example, missing hardware requirements.
+ */
+ object UnavailableOnDevice : PickerScreenState()
+
+ /**
+ * The picker shows the item for selecting this affordance as disabled. Clicking on it will
+ * show the given instructions to the user. If [actionText] and [actionComponentName] are
+ * provided (optional) a button will be shown to open an activity to help the user complete
+ * the steps described in the instructions.
+ */
+ data class Disabled(
+ /** List of human-readable instructions for setting up the quick affordance. */
+ val instructions: List<String>,
+ /**
+ * Optional text to display on a button that the user can click to start a flow to go
+ * and set up the quick affordance and make it enabled.
+ */
+ val actionText: String? = null,
+ /**
+ * Optional component name to be able to build an `Intent` that opens an `Activity` for
+ * the user to be able to set up the quick affordance and make it enabled.
+ *
+ * This is either just an action for the `Intent` or a package name and action,
+ * separated by [Contract.AffordanceTable.COMPONENT_NAME_SEPARATOR] for convenience, you
+ * can use the [componentName] function.
+ */
+ val actionComponentName: String? = null,
+ ) : PickerScreenState() {
+ init {
+ check(instructions.isNotEmpty()) { "Instructions must not be empty!" }
+ check(
+ (actionText.isNullOrEmpty() && actionComponentName.isNullOrEmpty()) ||
+ (!actionText.isNullOrEmpty() && !actionComponentName.isNullOrEmpty())
+ ) {
+ "actionText and actionComponentName must either both be null/empty or both be" +
+ " non-empty!"
+ }
+ }
+ }
+ }
+
+ /**
* Encapsulates the state of a "quick affordance" in the keyguard bottom area (for example, a
* button on the lock-screen).
*/
@@ -83,4 +142,18 @@ interface KeyguardQuickAffordanceConfig {
val canShowWhileLocked: Boolean,
) : OnTriggeredResult()
}
+
+ companion object {
+ fun componentName(
+ packageName: String? = null,
+ action: String?,
+ ): String? {
+ return when {
+ action.isNullOrEmpty() -> null
+ !packageName.isNullOrEmpty() ->
+ "$packageName${Contract.AffordanceTable.COMPONENT_NAME_SEPARATOR}$action"
+ else -> action
+ }
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfig.kt
index 11f72ffa4757..a96ce77ee15c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfig.kt
@@ -36,7 +36,7 @@ import kotlinx.coroutines.flow.Flow
class QrCodeScannerKeyguardQuickAffordanceConfig
@Inject
constructor(
- @Application context: Context,
+ @Application private val context: Context,
private val controller: QRCodeScannerController,
) : KeyguardQuickAffordanceConfig {
@@ -75,6 +75,28 @@ constructor(
}
}
+ override suspend fun getPickerScreenState(): KeyguardQuickAffordanceConfig.PickerScreenState {
+ return when {
+ !controller.isAvailableOnDevice ->
+ KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice
+ !controller.isAbleToOpenCameraApp ->
+ KeyguardQuickAffordanceConfig.PickerScreenState.Disabled(
+ instructions =
+ listOf(
+ context.getString(
+ R.string.keyguard_affordance_enablement_dialog_message,
+ pickerName,
+ ),
+ context.getString(
+ R.string
+ .keyguard_affordance_enablement_dialog_qr_scanner_instruction
+ ),
+ ),
+ )
+ else -> KeyguardQuickAffordanceConfig.PickerScreenState.Default
+ }
+ }
+
override fun onTriggered(
expandable: Expandable?,
): KeyguardQuickAffordanceConfig.OnTriggeredResult {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfig.kt
index 303e6a1a95cc..beb20ce4540c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfig.kt
@@ -18,10 +18,12 @@
package com.android.systemui.keyguard.data.quickaffordance
import android.content.Context
+import android.content.Intent
import android.graphics.drawable.Drawable
import android.service.quickaccesswallet.GetWalletCardsError
import android.service.quickaccesswallet.GetWalletCardsResponse
import android.service.quickaccesswallet.QuickAccessWalletClient
+import android.service.quickaccesswallet.WalletCard
import android.util.Log
import com.android.systemui.R
import com.android.systemui.animation.Expandable
@@ -31,25 +33,27 @@ import com.android.systemui.common.shared.model.ContentDescription
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceConfig.Companion.componentName
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.wallet.controller.QuickAccessWalletController
import javax.inject.Inject
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.suspendCancellableCoroutine
/** Quick access wallet quick affordance data source. */
@SysUISingleton
class QuickAccessWalletKeyguardQuickAffordanceConfig
@Inject
constructor(
- @Application context: Context,
+ @Application private val context: Context,
private val walletController: QuickAccessWalletController,
private val activityStarter: ActivityStarter,
) : KeyguardQuickAffordanceConfig {
override val key: String = BuiltInKeyguardQuickAffordanceKeys.QUICK_ACCESS_WALLET
- override val pickerName = context.getString(R.string.accessibility_wallet_button)
+ override val pickerName: String = context.getString(R.string.accessibility_wallet_button)
override val pickerIconResourceId = R.drawable.ic_wallet_lockscreen
@@ -58,10 +62,11 @@ constructor(
val callback =
object : QuickAccessWalletClient.OnWalletCardsRetrievedCallback {
override fun onWalletCardsRetrieved(response: GetWalletCardsResponse?) {
+ val hasCards = response?.walletCards?.isNotEmpty() == true
trySendWithFailureLogging(
state(
isFeatureEnabled = walletController.isWalletEnabled,
- hasCard = response?.walletCards?.isNotEmpty() == true,
+ hasCard = hasCards,
tileIcon = walletController.walletClient.tileIcon,
),
TAG,
@@ -93,6 +98,44 @@ constructor(
}
}
+ override suspend fun getPickerScreenState(): KeyguardQuickAffordanceConfig.PickerScreenState {
+ return when {
+ !walletController.isWalletEnabled ->
+ KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice
+ walletController.walletClient.tileIcon == null || queryCards().isEmpty() -> {
+ val componentName =
+ walletController.walletClient.createWalletSettingsIntent().toComponentName()
+ val actionText =
+ if (componentName != null) {
+ context.getString(
+ R.string.keyguard_affordance_enablement_dialog_action_template,
+ pickerName,
+ )
+ } else {
+ null
+ }
+ KeyguardQuickAffordanceConfig.PickerScreenState.Disabled(
+ instructions =
+ listOf(
+ context.getString(
+ R.string.keyguard_affordance_enablement_dialog_message,
+ pickerName,
+ ),
+ context.getString(
+ R.string.keyguard_affordance_enablement_dialog_wallet_instruction_1
+ ),
+ context.getString(
+ R.string.keyguard_affordance_enablement_dialog_wallet_instruction_2
+ ),
+ ),
+ actionText = actionText,
+ actionComponentName = componentName,
+ )
+ }
+ else -> KeyguardQuickAffordanceConfig.PickerScreenState.Default
+ }
+ }
+
override fun onTriggered(
expandable: Expandable?,
): KeyguardQuickAffordanceConfig.OnTriggeredResult {
@@ -104,6 +147,24 @@ constructor(
return KeyguardQuickAffordanceConfig.OnTriggeredResult.Handled
}
+ private suspend fun queryCards(): List<WalletCard> {
+ return suspendCancellableCoroutine { continuation ->
+ val callback =
+ object : QuickAccessWalletClient.OnWalletCardsRetrievedCallback {
+ override fun onWalletCardsRetrieved(response: GetWalletCardsResponse?) {
+ continuation.resumeWith(
+ Result.success(response?.walletCards ?: emptyList())
+ )
+ }
+
+ override fun onWalletCardRetrievalError(error: GetWalletCardsError?) {
+ continuation.resumeWith(Result.success(emptyList()))
+ }
+ }
+ walletController.queryWalletCards(callback)
+ }
+ }
+
private fun state(
isFeatureEnabled: Boolean,
hasCard: Boolean,
@@ -125,6 +186,14 @@ constructor(
}
}
+ private fun Intent?.toComponentName(): String? {
+ if (this == null) {
+ return null
+ }
+
+ return componentName(packageName = `package`, action = action)
+ }
+
companion object {
private const val TAG = "QuickAccessWalletKeyguardQuickAffordanceConfig"
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepository.kt
index 533b3abf4fb6..d95a1a726bf5 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepository.kt
@@ -18,14 +18,17 @@
package com.android.systemui.keyguard.data.repository
import android.content.Context
+import com.android.systemui.Dumpable
import com.android.systemui.R
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dump.DumpManager
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceConfig
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceLegacySettingSyncer
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceSelectionManager
import com.android.systemui.keyguard.shared.model.KeyguardQuickAffordancePickerRepresentation
import com.android.systemui.keyguard.shared.model.KeyguardSlotPickerRepresentation
+import java.io.PrintWriter
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.SharingStarted
@@ -43,6 +46,7 @@ constructor(
private val selectionManager: KeyguardQuickAffordanceSelectionManager,
legacySettingSyncer: KeyguardQuickAffordanceLegacySettingSyncer,
private val configs: Set<@JvmSuppressWildcards KeyguardQuickAffordanceConfig>,
+ dumpManager: DumpManager,
) {
/**
* List of [KeyguardQuickAffordanceConfig] instances of the affordances at the slot with the
@@ -87,6 +91,7 @@ constructor(
init {
legacySettingSyncer.startSyncing()
+ dumpManager.registerDumpable("KeyguardQuickAffordances", Dumpster())
}
/**
@@ -121,18 +126,32 @@ constructor(
}
/**
- * Returns the list of representation objects for all known affordances, regardless of what is
- * selected. This is useful for building experiences like the picker/selector or user settings
- * so the user can see everything that can be selected in a menu.
+ * Returns the list of representation objects for all known, device-available affordances,
+ * regardless of what is selected. This is useful for building experiences like the
+ * picker/selector or user settings so the user can see everything that can be selected in a
+ * menu.
*/
- fun getAffordancePickerRepresentations(): List<KeyguardQuickAffordancePickerRepresentation> {
- return configs.map { config ->
- KeyguardQuickAffordancePickerRepresentation(
- id = config.key,
- name = config.pickerName,
- iconResourceId = config.pickerIconResourceId,
- )
- }
+ suspend fun getAffordancePickerRepresentations():
+ List<KeyguardQuickAffordancePickerRepresentation> {
+ return configs
+ .associateWith { config -> config.getPickerScreenState() }
+ .filterNot { (_, pickerState) ->
+ pickerState is KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice
+ }
+ .map { (config, pickerState) ->
+ val disabledPickerState =
+ pickerState as? KeyguardQuickAffordanceConfig.PickerScreenState.Disabled
+ KeyguardQuickAffordancePickerRepresentation(
+ id = config.key,
+ name = config.pickerName,
+ iconResourceId = config.pickerIconResourceId,
+ isEnabled =
+ pickerState is KeyguardQuickAffordanceConfig.PickerScreenState.Default,
+ instructions = disabledPickerState?.instructions,
+ actionText = disabledPickerState?.actionText,
+ actionComponentName = disabledPickerState?.actionComponentName,
+ )
+ }
}
/**
@@ -144,6 +163,30 @@ constructor(
return _slotPickerRepresentations
}
+ private inner class Dumpster : Dumpable {
+ override fun dump(pw: PrintWriter, args: Array<out String>) {
+ val slotPickerRepresentations = getSlotPickerRepresentations()
+ val selectionsBySlotId = getSelections()
+ pw.println("Slots & selections:")
+ slotPickerRepresentations.forEach { slotPickerRepresentation ->
+ val slotId = slotPickerRepresentation.id
+ val capacity = slotPickerRepresentation.maxSelectedAffordances
+ val affordanceIds = selectionsBySlotId[slotId]
+
+ val selectionText =
+ if (!affordanceIds.isNullOrEmpty()) {
+ ": ${affordanceIds.joinToString(", ")}"
+ } else {
+ " is empty"
+ }
+
+ pw.println(" $slotId$selectionText (capacity = $capacity)")
+ }
+ pw.println("Available affordances on device:")
+ configs.forEach { config -> pw.println(" ${config.key} (\"${config.pickerName}\")") }
+ }
+ }
+
companion object {
private const val SLOT_CONFIG_DELIMITER = ":"
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt
index c8216c5d72d7..2d94d760cb54 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt
@@ -189,7 +189,7 @@ constructor(
}
/** Returns affordance IDs indexed by slot ID, for all known slots. */
- fun getSelections(): Map<String, List<KeyguardQuickAffordancePickerRepresentation>> {
+ suspend fun getSelections(): Map<String, List<KeyguardQuickAffordancePickerRepresentation>> {
check(isUsingRepository)
val slots = repository.get().getSlotPickerRepresentations()
@@ -310,7 +310,8 @@ constructor(
return Pair(splitUp[0], splitUp[1])
}
- fun getAffordancePickerRepresentations(): List<KeyguardQuickAffordancePickerRepresentation> {
+ suspend fun getAffordancePickerRepresentations():
+ List<KeyguardQuickAffordancePickerRepresentation> {
check(isUsingRepository)
return repository.get().getAffordancePickerRepresentations()
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractor.kt
index 3b31dcfc4349..84a80744185e 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractor.kt
@@ -21,6 +21,7 @@ import android.os.Handler
import android.os.Trace
import android.os.UserHandle
import android.os.UserManager
+import android.view.View
import com.android.keyguard.KeyguardSecurityModel
import com.android.keyguard.KeyguardUpdateMonitor
import com.android.systemui.DejankUtils
@@ -84,6 +85,7 @@ constructor(
)
)
repository.setPrimaryShowingSoon(false)
+ primaryBouncerCallbackInteractor.dispatchVisibilityChanged(View.VISIBLE)
}
val keyguardAuthenticated: Flow<Boolean> = repository.keyguardAuthenticated.filterNotNull()
@@ -182,6 +184,7 @@ constructor(
repository.setPrimaryVisible(false)
repository.setPrimaryHide(true)
repository.setPrimaryShow(null)
+ primaryBouncerCallbackInteractor.dispatchVisibilityChanged(View.INVISIBLE)
Trace.endSection()
}
@@ -276,11 +279,6 @@ constructor(
repository.setShowMessage(null)
}
- /** Notify that view visibility has changed. */
- fun notifyBouncerVisibilityHasChanged(visibility: Int) {
- primaryBouncerCallbackInteractor.dispatchVisibilityChanged(visibility)
- }
-
/** Notify that the resources have been updated */
fun notifyUpdatedResources() {
repository.setResourceUpdateRequests(false)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/KeyguardQuickAffordancePickerRepresentation.kt b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/KeyguardQuickAffordancePickerRepresentation.kt
index a56bc900f936..7d133598e105 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/KeyguardQuickAffordancePickerRepresentation.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/KeyguardQuickAffordancePickerRepresentation.kt
@@ -27,4 +27,22 @@ data class KeyguardQuickAffordancePickerRepresentation(
val id: String,
val name: String,
@DrawableRes val iconResourceId: Int,
+
+ /** Whether this quick affordance is enabled. */
+ val isEnabled: Boolean = true,
+
+ /** If not enabled, the list of user-visible steps to re-enable it. */
+ val instructions: List<String>? = null,
+
+ /**
+ * If not enabled, an optional label for a button that takes the user to a destination where
+ * they can re-enable it.
+ */
+ val actionText: String? = null,
+
+ /**
+ * If not enabled, an optional component name (package and action) for a button that takes the
+ * user to a destination where they can re-enable it.
+ */
+ val actionComponentName: String? = null,
)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBouncerViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBouncerViewBinder.kt
index 3c927ee08494..f772b17a7fb6 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBouncerViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBouncerViewBinder.kt
@@ -88,7 +88,7 @@ object KeyguardBouncerViewBinder {
}
}
view.repeatWhenAttached {
- repeatOnLifecycle(Lifecycle.State.STARTED) {
+ repeatOnLifecycle(Lifecycle.State.CREATED) {
try {
viewModel.setBouncerViewDelegate(delegate)
launch {
@@ -152,7 +152,6 @@ object KeyguardBouncerViewBinder {
val visibility = if (isVisible) View.VISIBLE else View.INVISIBLE
view.visibility = visibility
hostViewController.onBouncerVisibilityChanged(visibility)
- viewModel.notifyBouncerVisibilityHasChanged(visibility)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBouncerViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBouncerViewModel.kt
index 503c8ba2ca43..e5d4e4971baa 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBouncerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBouncerViewModel.kt
@@ -72,10 +72,6 @@ constructor(
/** Observe whether screen is turned off. */
val screenTurnedOff: Flow<Unit> = interactor.screenTurnedOff
- /** Notify that view visibility has changed. */
- fun notifyBouncerVisibilityHasChanged(visibility: Int) {
- return interactor.notifyBouncerVisibilityHasChanged(visibility)
- }
/** Observe whether we want to update resources. */
fun notifyUpdateResources() {
interactor.notifyUpdatedResources()
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/BiometricMessagesLog.java b/packages/SystemUI/src/com/android/systemui/log/dagger/BiometricLog.java
index eeadf406060d..4b774d3b2192 100644
--- a/packages/SystemUI/src/com/android/systemui/log/dagger/BiometricMessagesLog.java
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/BiometricLog.java
@@ -29,5 +29,5 @@ import javax.inject.Qualifier;
@Qualifier
@Documented
@Retention(RetentionPolicy.RUNTIME)
-public @interface BiometricMessagesLog {
+public @interface BiometricLog {
}
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 ff291bf39dd2..f5a97ce67098 100644
--- a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
@@ -300,9 +300,9 @@ public class LogModule {
*/
@Provides
@SysUISingleton
- @BiometricMessagesLog
- public static LogBuffer provideBiometricMessagesLogBuffer(LogBufferFactory factory) {
- return factory.create("BiometricMessagesLog", 150);
+ @BiometricLog
+ public static LogBuffer provideBiometricLogBuffer(LogBufferFactory factory) {
+ return factory.create("BiometricLog", 200);
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/qrcodescanner/controller/QRCodeScannerController.java b/packages/SystemUI/src/com/android/systemui/qrcodescanner/controller/QRCodeScannerController.java
index 2c20feb19342..fa3f878ff431 100644
--- a/packages/SystemUI/src/com/android/systemui/qrcodescanner/controller/QRCodeScannerController.java
+++ b/packages/SystemUI/src/com/android/systemui/qrcodescanner/controller/QRCodeScannerController.java
@@ -158,14 +158,18 @@ public class QRCodeScannerController implements
* Returns true if lock screen entry point for QR Code Scanner is to be enabled.
*/
public boolean isEnabledForLockScreenButton() {
- return mQRCodeScannerEnabled && mIntent != null && mConfigEnableLockScreenButton
- && isActivityCallable(mIntent);
+ return mQRCodeScannerEnabled && isAbleToOpenCameraApp() && isAvailableOnDevice();
+ }
+
+ /** Returns whether the feature is available on the device. */
+ public boolean isAvailableOnDevice() {
+ return mConfigEnableLockScreenButton;
}
/**
- * Returns true if quick settings entry point for QR Code Scanner is to be enabled.
+ * Returns true if the feature can open a camera app on the device.
*/
- public boolean isEnabledForQuickSettings() {
+ public boolean isAbleToOpenCameraApp() {
return mIntent != null && isActivityCallable(mIntent);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
index d9be2810d165..c0533bae233f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
@@ -697,10 +697,12 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
if (mQSAnimator != null) {
mQSAnimator.setPosition(expansion);
}
- if (mStatusBarStateController.getState() == StatusBarState.KEYGUARD
+ if (!mInSplitShade
+ || mStatusBarStateController.getState() == StatusBarState.KEYGUARD
|| mStatusBarStateController.getState() == StatusBarState.SHADE_LOCKED) {
// At beginning, state is 0 and will apply wrong squishiness to MediaHost in lockscreen
- // and media player expect no change by squishiness in lock screen shade
+ // and media player expect no change by squishiness in lock screen shade. Don't bother
+ // squishing mQsMediaHost when not in split shade to prevent problems with stale state.
mQsMediaHost.setSquishFraction(1.0F);
} else {
mQsMediaHost.setSquishFraction(mSquishinessFraction);
@@ -757,7 +759,8 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
return ShadeInterpolation.getContentAlpha(progress);
}
- private void updateQsBounds() {
+ @VisibleForTesting
+ void updateQsBounds() {
if (mLastQSExpansion == 1.0f) {
// Fully expanded, let's set the layout bounds as clip bounds. This is necessary because
// it's a scrollview and otherwise wouldn't be clipped. However, we set the horizontal
@@ -773,9 +776,10 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
mQSPanelScrollView.getLocationOnScreen(mLocationTemp);
int left = mLocationTemp[0];
int top = mLocationTemp[1];
- mQsMediaHost.getCurrentClipping().set(left, top, left + getView().getMeasuredWidth(),
+ mQsMediaHost.getCurrentClipping().set(left, top,
+ left + getView().getMeasuredWidth(),
top + mQSPanelScrollView.getMeasuredHeight()
- - mQSPanelScrollView.getPaddingBottom());
+ - mQSPanelController.getPaddingBottom());
}
private boolean headerWillBeAnimating() {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java
index 64962b495c96..1827eaf3fad1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java
@@ -239,5 +239,9 @@ public class QSPanelController extends QSPanelControllerBase<QSPanel> {
public boolean isBouncerInTransit() {
return mStatusBarKeyguardViewManager.isPrimaryBouncerInTransit();
}
+
+ public int getPaddingBottom() {
+ return mView.getPaddingBottom();
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt
index c65bd9b4348e..41d854969e20 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt
@@ -32,6 +32,7 @@ import com.android.systemui.controls.dagger.ControlsComponent
import com.android.systemui.controls.dagger.ControlsComponent.Visibility.AVAILABLE
import com.android.systemui.controls.management.ControlsListingController
import com.android.systemui.controls.ui.ControlsUiController
+import com.android.systemui.controls.ui.SelectedItem
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.plugins.ActivityStarter
@@ -125,14 +126,15 @@ class DeviceControlsTile @Inject constructor(
state.icon = icon
if (controlsComponent.isEnabled() && hasControlsApps.get()) {
if (controlsComponent.getVisibility() == AVAILABLE) {
- val structureInfo = controlsComponent
- .getControlsController().get().getPreferredStructure()
- state.state = if (structureInfo.controls.isEmpty()) {
+ val selection = controlsComponent
+ .getControlsController().get().getPreferredSelection()
+ state.state = if (selection is SelectedItem.StructureItem &&
+ selection.structure.controls.isEmpty()) {
Tile.STATE_INACTIVE
} else {
Tile.STATE_ACTIVE
}
- val label = structureInfo.structure
+ val label = selection.name
state.secondaryLabel = if (label == tileLabel) null else label
} else {
state.state = Tile.STATE_INACTIVE
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/QRCodeScannerTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/QRCodeScannerTile.java
index 376d3d8da8e7..6d50b562cd02 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/QRCodeScannerTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/QRCodeScannerTile.java
@@ -115,8 +115,12 @@ public class QRCodeScannerTile extends QSTileImpl<QSTile.State> {
state.label = mContext.getString(R.string.qr_code_scanner_title);
state.contentDescription = state.label;
state.icon = ResourceIcon.get(R.drawable.ic_qr_code_scanner);
- state.state = mQRCodeScannerController.isEnabledForQuickSettings() ? Tile.STATE_INACTIVE
+ state.state = mQRCodeScannerController.isAbleToOpenCameraApp() ? Tile.STATE_INACTIVE
: Tile.STATE_UNAVAILABLE;
+ // The assumption is that if the OEM has the QR code scanner module enabled then the scanner
+ // would go to "Unavailable" state only when GMS core is updating.
+ state.secondaryLabel = state.state == Tile.STATE_UNAVAILABLE
+ ? mContext.getString(R.string.qr_code_scanner_updating_secondary_label) : null;
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java
index aa6e67841e78..a4ce6b363041 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java
@@ -142,21 +142,28 @@ public class InternetDialogController implements AccessPointController.AccessPoi
private static final int SUBTITLE_TEXT_ALL_CARRIER_NETWORK_UNAVAILABLE =
R.string.all_network_unavailable;
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+ private static final TelephonyDisplayInfo DEFAULT_TELEPHONY_DISPLAY_INFO =
+ new TelephonyDisplayInfo(TelephonyManager.NETWORK_TYPE_UNKNOWN,
+ TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE);
static final int MAX_WIFI_ENTRY_COUNT = 3;
private final FeatureFlags mFeatureFlags;
+ @VisibleForTesting
+ /** Should be accessible only to the main thread. */
+ final Map<Integer, TelephonyDisplayInfo> mSubIdTelephonyDisplayInfoMap = new HashMap<>();
+
private WifiManager mWifiManager;
private Context mContext;
private SubscriptionManager mSubscriptionManager;
+ /** Should be accessible only to the main thread. */
private Map<Integer, TelephonyManager> mSubIdTelephonyManagerMap = new HashMap<>();
+ /** Should be accessible only to the main thread. */
+ private Map<Integer, TelephonyCallback> mSubIdTelephonyCallbackMap = new HashMap<>();
private TelephonyManager mTelephonyManager;
private ConnectivityManager mConnectivityManager;
private CarrierConfigTracker mCarrierConfigTracker;
- private TelephonyDisplayInfo mTelephonyDisplayInfo =
- new TelephonyDisplayInfo(TelephonyManager.NETWORK_TYPE_UNKNOWN,
- TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE);
private Handler mHandler;
private Handler mWorkerHandler;
private MobileMappings.Config mConfig = null;
@@ -190,8 +197,6 @@ public class InternetDialogController implements AccessPointController.AccessPoi
@VisibleForTesting
protected SubscriptionManager.OnSubscriptionsChangedListener mOnSubscriptionsChangedListener;
@VisibleForTesting
- protected InternetTelephonyCallback mInternetTelephonyCallback;
- @VisibleForTesting
protected WifiUtils.InternetIconInjector mWifiIconInjector;
@VisibleForTesting
protected boolean mCanConfigWifi;
@@ -290,8 +295,10 @@ public class InternetDialogController implements AccessPointController.AccessPoi
mConfig = MobileMappings.Config.readConfig(mContext);
mTelephonyManager = mTelephonyManager.createForSubscriptionId(mDefaultDataSubId);
mSubIdTelephonyManagerMap.put(mDefaultDataSubId, mTelephonyManager);
- mInternetTelephonyCallback = new InternetTelephonyCallback();
- mTelephonyManager.registerTelephonyCallback(mExecutor, mInternetTelephonyCallback);
+ InternetTelephonyCallback telephonyCallback =
+ new InternetTelephonyCallback(mDefaultDataSubId);
+ mSubIdTelephonyCallbackMap.put(mDefaultDataSubId, telephonyCallback);
+ mTelephonyManager.registerTelephonyCallback(mExecutor, telephonyCallback);
// Listen the connectivity changes
mConnectivityManager.registerDefaultNetworkCallback(mConnectivityManagerNetworkCallback);
mCanConfigWifi = canConfigWifi;
@@ -304,7 +311,12 @@ public class InternetDialogController implements AccessPointController.AccessPoi
}
mBroadcastDispatcher.unregisterReceiver(mConnectionStateReceiver);
for (TelephonyManager tm : mSubIdTelephonyManagerMap.values()) {
- tm.unregisterTelephonyCallback(mInternetTelephonyCallback);
+ TelephonyCallback callback = mSubIdTelephonyCallbackMap.get(tm.getSubscriptionId());
+ if (callback != null) {
+ tm.unregisterTelephonyCallback(callback);
+ } else if (DEBUG) {
+ Log.e(TAG, "Unexpected null telephony call back for Sub " + tm.getSubscriptionId());
+ }
}
mSubscriptionManager.removeOnSubscriptionsChangedListener(
mOnSubscriptionsChangedListener);
@@ -623,7 +635,9 @@ public class InternetDialogController implements AccessPointController.AccessPoi
int subId = subInfo.getSubscriptionId();
if (mSubIdTelephonyManagerMap.get(subId) == null) {
TelephonyManager secondaryTm = mTelephonyManager.createForSubscriptionId(subId);
- secondaryTm.registerTelephonyCallback(mExecutor, mInternetTelephonyCallback);
+ InternetTelephonyCallback telephonyCallback = new InternetTelephonyCallback(subId);
+ secondaryTm.registerTelephonyCallback(mExecutor, telephonyCallback);
+ mSubIdTelephonyCallbackMap.put(subId, telephonyCallback);
mSubIdTelephonyManagerMap.put(subId, secondaryTm);
}
return subId;
@@ -637,8 +651,7 @@ public class InternetDialogController implements AccessPointController.AccessPoi
}
String getMobileNetworkSummary(int subId) {
- String description = getNetworkTypeDescription(mContext, mConfig,
- mTelephonyDisplayInfo, subId);
+ String description = getNetworkTypeDescription(mContext, mConfig, subId);
return getMobileSummary(mContext, description, subId);
}
@@ -646,7 +659,9 @@ public class InternetDialogController implements AccessPointController.AccessPoi
* Get currently description of mobile network type.
*/
private String getNetworkTypeDescription(Context context, MobileMappings.Config config,
- TelephonyDisplayInfo telephonyDisplayInfo, int subId) {
+ int subId) {
+ TelephonyDisplayInfo telephonyDisplayInfo =
+ mSubIdTelephonyDisplayInfoMap.getOrDefault(subId, DEFAULT_TELEPHONY_DISPLAY_INFO);
String iconKey = getIconKey(telephonyDisplayInfo);
if (mapIconSets(config) == null || mapIconSets(config).get(iconKey) == null) {
@@ -725,11 +740,10 @@ public class InternetDialogController implements AccessPointController.AccessPoi
Intent getSubSettingIntent(int subId) {
final Intent intent = new Intent(Settings.ACTION_NETWORK_OPERATOR_SETTINGS);
-
final Bundle fragmentArgs = new Bundle();
// Special contract for Settings to highlight permission row
fragmentArgs.putString(SETTINGS_EXTRA_FRAGMENT_ARG_KEY, AUTO_DATA_SWITCH_SETTING_R_ID);
- fragmentArgs.putInt(Settings.EXTRA_SUB_ID, subId);
+ intent.putExtra(Settings.EXTRA_SUB_ID, subId);
intent.putExtra(SETTINGS_EXTRA_SHOW_FRAGMENT_ARGUMENTS, fragmentArgs);
return intent;
}
@@ -1082,6 +1096,11 @@ public class InternetDialogController implements AccessPointController.AccessPoi
TelephonyCallback.SignalStrengthsListener,
TelephonyCallback.UserMobileDataStateListener {
+ private final int mSubId;
+ private InternetTelephonyCallback(int subId) {
+ mSubId = subId;
+ }
+
@Override
public void onServiceStateChanged(@NonNull ServiceState serviceState) {
mCallback.onServiceStateChanged(serviceState);
@@ -1099,7 +1118,7 @@ public class InternetDialogController implements AccessPointController.AccessPoi
@Override
public void onDisplayInfoChanged(@NonNull TelephonyDisplayInfo telephonyDisplayInfo) {
- mTelephonyDisplayInfo = telephonyDisplayInfo;
+ mSubIdTelephonyDisplayInfoMap.put(mSubId, telephonyDisplayInfo);
mCallback.onDisplayInfoChanged(telephonyDisplayInfo);
}
@@ -1224,19 +1243,30 @@ public class InternetDialogController implements AccessPointController.AccessPoi
}
return;
}
-
- mDefaultDataSubId = defaultDataSubId;
if (DEBUG) {
- Log.d(TAG, "DDS: defaultDataSubId:" + mDefaultDataSubId);
- }
- if (SubscriptionManager.isUsableSubscriptionId(mDefaultDataSubId)) {
- mTelephonyManager.unregisterTelephonyCallback(mInternetTelephonyCallback);
- mTelephonyManager = mTelephonyManager.createForSubscriptionId(mDefaultDataSubId);
- mSubIdTelephonyManagerMap.put(mDefaultDataSubId, mTelephonyManager);
- mTelephonyManager.registerTelephonyCallback(mHandler::post,
- mInternetTelephonyCallback);
- mCallback.onSubscriptionsChanged(mDefaultDataSubId);
+ Log.d(TAG, "DDS: defaultDataSubId:" + defaultDataSubId);
+ }
+ if (SubscriptionManager.isUsableSubscriptionId(defaultDataSubId)) {
+ // clean up old defaultDataSubId
+ TelephonyCallback oldCallback = mSubIdTelephonyCallbackMap.get(mDefaultDataSubId);
+ if (oldCallback != null) {
+ mTelephonyManager.unregisterTelephonyCallback(oldCallback);
+ } else if (DEBUG) {
+ Log.e(TAG, "Unexpected null telephony call back for Sub " + mDefaultDataSubId);
+ }
+ mSubIdTelephonyCallbackMap.remove(mDefaultDataSubId);
+ mSubIdTelephonyDisplayInfoMap.remove(mDefaultDataSubId);
+ mSubIdTelephonyManagerMap.remove(mDefaultDataSubId);
+
+ // create for new defaultDataSubId
+ mTelephonyManager = mTelephonyManager.createForSubscriptionId(defaultDataSubId);
+ mSubIdTelephonyManagerMap.put(defaultDataSubId, mTelephonyManager);
+ InternetTelephonyCallback newCallback = new InternetTelephonyCallback(defaultDataSubId);
+ mSubIdTelephonyCallbackMap.put(defaultDataSubId, newCallback);
+ mTelephonyManager.registerTelephonyCallback(mHandler::post, newCallback);
+ mCallback.onSubscriptionsChanged(defaultDataSubId);
}
+ mDefaultDataSubId = defaultDataSubId;
}
public WifiUtils.InternetIconInjector getWifiIconInjector() {
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
index d94c8277b82c..8609e4af13f6 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
@@ -739,10 +739,14 @@ public class ScreenshotController {
mLongScreenshotHolder.setLongScreenshot(longScreenshot);
mLongScreenshotHolder.setTransitionDestinationCallback(
- (transitionDestination, onTransitionEnd) ->
+ (transitionDestination, onTransitionEnd) -> {
mScreenshotView.startLongScreenshotTransition(
transitionDestination, onTransitionEnd,
- longScreenshot));
+ longScreenshot);
+ // TODO: Do this via ActionIntentExecutor instead.
+ mContext.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
+ }
+ );
final Intent intent = new Intent(mContext, LongScreenshotActivity.class);
intent.putExtra(LongScreenshotActivity.EXTRA_SCREENSHOT_USER_HANDLE,
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
index 0a4b550882c9..7641554ede3d 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
@@ -898,6 +898,7 @@ public class ScreenshotView extends FrameLayout implements
void startLongScreenshotTransition(Rect destination, Runnable onTransitionEnd,
ScrollCaptureController.LongScreenshot longScreenshot) {
+ mPendingSharedTransition = true;
AnimatorSet animSet = new AnimatorSet();
ValueAnimator scrimAnim = ValueAnimator.ofFloat(0, 1);
diff --git a/packages/SystemUI/src/com/android/systemui/shade/transition/ShadeTransitionController.kt b/packages/SystemUI/src/com/android/systemui/shade/transition/ShadeTransitionController.kt
index 1054aa59db61..07820ecd513e 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/transition/ShadeTransitionController.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/transition/ShadeTransitionController.kt
@@ -78,7 +78,7 @@ constructor(
})
shadeExpansionStateManager.addExpansionListener(this::onPanelExpansionChanged)
shadeExpansionStateManager.addStateListener(this::onPanelStateChanged)
- dumpManager.registerDumpable("ShadeTransitionController") { printWriter, _ ->
+ dumpManager.registerCriticalDumpable("ShadeTransitionController") { printWriter, _ ->
dump(printWriter)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/transition/SplitShadeOverScroller.kt b/packages/SystemUI/src/com/android/systemui/shade/transition/SplitShadeOverScroller.kt
index fde08ee859e0..f95125f5cb6c 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/transition/SplitShadeOverScroller.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/transition/SplitShadeOverScroller.kt
@@ -70,7 +70,7 @@ constructor(
updateResources()
}
})
- dumpManager.registerDumpable("SplitShadeOverScroller") { printWriter, _ ->
+ dumpManager.registerCriticalDumpable("SplitShadeOverScroller") { printWriter, _ ->
dump(printWriter)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index f786ced43963..1dd3a967faaf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -163,6 +163,7 @@ public class CommandQueue extends IStatusBar.Stub implements
private static final int MSG_REGISTER_NEARBY_MEDIA_DEVICE_PROVIDER = 66 << MSG_SHIFT;
private static final int MSG_UNREGISTER_NEARBY_MEDIA_DEVICE_PROVIDER = 67 << MSG_SHIFT;
private static final int MSG_TILE_SERVICE_REQUEST_LISTENING_STATE = 68 << MSG_SHIFT;
+ private static final int MSG_SHOW_REAR_DISPLAY_DIALOG = 69 << MSG_SHIFT;
public static final int FLAG_EXCLUDE_NONE = 0;
public static final int FLAG_EXCLUDE_SEARCH_PANEL = 1 << 0;
@@ -472,6 +473,11 @@ public class CommandQueue extends IStatusBar.Stub implements
*/
default void unregisterNearbyMediaDevicesProvider(
@NonNull INearbyMediaDevicesProvider provider) {}
+
+ /**
+ * @see IStatusBar#showRearDisplayDialog
+ */
+ default void showRearDisplayDialog(int currentBaseState) {}
}
public CommandQueue(Context context) {
@@ -1226,6 +1232,13 @@ public class CommandQueue extends IStatusBar.Stub implements
}
@Override
+ public void showRearDisplayDialog(int currentBaseState) {
+ synchronized (mLock) {
+ mHandler.obtainMessage(MSG_SHOW_REAR_DISPLAY_DIALOG, currentBaseState).sendToTarget();
+ }
+ }
+
+ @Override
public void requestAddTile(
@NonNull ComponentName componentName,
@NonNull CharSequence appName,
@@ -1721,6 +1734,10 @@ public class CommandQueue extends IStatusBar.Stub implements
mCallbacks.get(i).requestTileServiceListeningState(component);
}
break;
+ case MSG_SHOW_REAR_DISPLAY_DIALOG:
+ for (int i = 0; i < mCallbacks.size(); i++) {
+ mCallbacks.get(i).showRearDisplayDialog((Integer) msg.obj);
+ }
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
index b5879ec19d21..8dc78426da7d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
@@ -304,7 +304,7 @@ class NotificationShadeDepthController @Inject constructor(
}
init {
- dumpManager.registerDumpable(javaClass.name, this)
+ dumpManager.registerCriticalDumpable(javaClass.name, this)
if (WAKE_UP_ANIMATION_ENABLED) {
keyguardStateController.addCallback(keyguardStateCallback)
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SplitShadeLockScreenOverScroller.kt b/packages/SystemUI/src/com/android/systemui/statusbar/SplitShadeLockScreenOverScroller.kt
index 13d8adb079de..572c0e0da262 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SplitShadeLockScreenOverScroller.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SplitShadeLockScreenOverScroller.kt
@@ -51,8 +51,8 @@ constructor(
updateResources()
}
})
- dumpManager.registerDumpable("SplitShadeLockscreenOverScroller") { printWriter, _ ->
- dump(printWriter)
+ dumpManager.registerCriticalDumpable("SplitShadeLockscreenOverScroller") { pw, _ ->
+ dump(pw)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java
index 3ae2545e4e10..65a21a4e2190 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java
@@ -1160,12 +1160,21 @@ public class ShadeListBuilder implements Dumpable, PipelineDumpable {
mLogger.logParentChanged(mIterationCount, prev.getParent(), curr.getParent());
}
- if (curr.getSuppressedChanges().getParent() != null) {
- mLogger.logParentChangeSuppressed(
+ GroupEntry currSuppressedParent = curr.getSuppressedChanges().getParent();
+ GroupEntry prevSuppressedParent = prev.getSuppressedChanges().getParent();
+ if (currSuppressedParent != null && (prevSuppressedParent == null
+ || !prevSuppressedParent.getKey().equals(currSuppressedParent.getKey()))) {
+ mLogger.logParentChangeSuppressedStarted(
mIterationCount,
- curr.getSuppressedChanges().getParent(),
+ currSuppressedParent,
curr.getParent());
}
+ if (prevSuppressedParent != null && currSuppressedParent == null) {
+ mLogger.logParentChangeSuppressedStopped(
+ mIterationCount,
+ prevSuppressedParent,
+ prev.getParent());
+ }
if (curr.getSuppressedChanges().getSection() != null) {
mLogger.logSectionChangeSuppressed(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/ShadeListBuilderLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/ShadeListBuilderLogger.kt
index 8e052c7dcc5d..4adc90aec0fb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/ShadeListBuilderLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/ShadeListBuilderLogger.kt
@@ -193,7 +193,7 @@ class ShadeListBuilderLogger @Inject constructor(
})
}
- fun logParentChangeSuppressed(
+ fun logParentChangeSuppressedStarted(
buildId: Int,
suppressedParent: GroupEntry?,
keepingParent: GroupEntry?
@@ -207,6 +207,21 @@ class ShadeListBuilderLogger @Inject constructor(
})
}
+ fun logParentChangeSuppressedStopped(
+ buildId: Int,
+ previouslySuppressedParent: GroupEntry?,
+ previouslyKeptParent: GroupEntry?
+ ) {
+ buffer.log(TAG, INFO, {
+ long1 = buildId.toLong()
+ str1 = previouslySuppressedParent?.logKey
+ str2 = previouslyKeptParent?.logKey
+ }, {
+ "(Build $long1) Change of parent to '$str1' no longer suppressed; " +
+ "replaced parent '$str2'"
+ })
+ }
+
fun logGroupPruningSuppressed(
buildId: Int,
keepingParent: GroupEntry?
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableOutlineView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableOutlineView.java
index 4fde5d06f816..232462714f7d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableOutlineView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableOutlineView.java
@@ -84,7 +84,7 @@ public abstract class ExpandableOutlineView extends ExpandableView {
int right;
int bottom;
int height;
- float topRoundness = mAlwaysRoundBothCorners ? getMaxRadius() : getTopCornerRadius();
+ float topRadius = mAlwaysRoundBothCorners ? getMaxRadius() : getTopCornerRadius();
if (!mCustomOutline) {
// The outline just needs to be shifted if we're translating the contents. Otherwise
// it's already in the right place.
@@ -97,7 +97,7 @@ public abstract class ExpandableOutlineView extends ExpandableView {
// If the top is rounded we want the bottom to be at most at the top roundness, in order
// to avoid the shadow changing when scrolling up.
bottom = Math.max(mMinimumHeightForClipping,
- Math.max(getActualHeight() - mClipBottomAmount, (int) (top + topRoundness)));
+ Math.max(getActualHeight() - mClipBottomAmount, (int) (top + topRadius)));
} else {
left = mOutlineRect.left;
top = mOutlineRect.top;
@@ -108,17 +108,17 @@ public abstract class ExpandableOutlineView extends ExpandableView {
if (height == 0) {
return EMPTY_PATH;
}
- float bottomRoundness = mAlwaysRoundBothCorners ? getMaxRadius() : getBottomCornerRadius();
- if (topRoundness + bottomRoundness > height) {
- float overShoot = topRoundness + bottomRoundness - height;
+ float bottomRadius = mAlwaysRoundBothCorners ? getMaxRadius() : getBottomCornerRadius();
+ if (topRadius + bottomRadius > height) {
+ float overShoot = topRadius + bottomRadius - height;
float currentTopRoundness = getTopRoundness();
float currentBottomRoundness = getBottomRoundness();
- topRoundness -= overShoot * currentTopRoundness
+ topRadius -= overShoot * currentTopRoundness
/ (currentTopRoundness + currentBottomRoundness);
- bottomRoundness -= overShoot * currentBottomRoundness
+ bottomRadius -= overShoot * currentBottomRoundness
/ (currentTopRoundness + currentBottomRoundness);
}
- getRoundedRectPath(left, top, right, bottom, topRoundness, bottomRoundness, mTmpPath);
+ getRoundedRectPath(left, top, right, bottom, topRadius, bottomRadius, mTmpPath);
return mTmpPath;
}
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 2c096f58024a..073bd4bf302b 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
@@ -1553,7 +1553,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
final int pinnedHeight = firstVisibleSection != null
? firstVisibleSection.getFirstVisibleChild().getPinnedHeadsUpHeight()
: 0;
- return mHeadsUpInset + pinnedHeight;
+ return mHeadsUpInset - mAmbientState.getStackTopMargin() + pinnedHeight;
}
return getMinExpansionHeight();
}
@@ -1809,7 +1809,8 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
@Override
@ShadeViewRefactor(RefactorComponent.COORDINATOR)
public WindowInsets onApplyWindowInsets(WindowInsets insets) {
- mBottomInset = insets.getSystemWindowInsetBottom();
+ mBottomInset = insets.getSystemWindowInsetBottom()
+ + insets.getInsets(WindowInsets.Type.ime()).bottom;
mWaterfallTopInset = 0;
final DisplayCutout cutout = insets.getDisplayCutout();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
index cd3f3b0e1dc8..34e62ce321e0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
@@ -29,7 +29,6 @@ import android.os.Handler;
import android.os.PowerManager;
import android.os.SystemClock;
import android.os.Trace;
-import android.util.Log;
import androidx.annotation.Nullable;
@@ -41,10 +40,10 @@ import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.UiEventLoggerImpl;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.util.LatencyTracker;
-import com.android.keyguard.KeyguardConstants;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.keyguard.KeyguardViewController;
+import com.android.keyguard.logging.BiometricUnlockLogger;
import com.android.systemui.Dumpable;
import com.android.systemui.R;
import com.android.systemui.biometrics.AuthController;
@@ -76,9 +75,6 @@ import javax.inject.Inject;
*/
@SysUISingleton
public class BiometricUnlockController extends KeyguardUpdateMonitorCallback implements Dumpable {
-
- private static final String TAG = "BiometricUnlockCtrl";
- private static final boolean DEBUG_BIO_WAKELOCK = KeyguardConstants.DEBUG_BIOMETRIC_WAKELOCK;
private static final long BIOMETRIC_WAKELOCK_TIMEOUT_MS = 15 * 1000;
private static final String BIOMETRIC_WAKE_LOCK_NAME = "wake-and-unlock:wakelock";
private static final UiEventLogger UI_EVENT_LOGGER = new UiEventLoggerImpl();
@@ -172,6 +168,7 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
private final StatusBarStateController mStatusBarStateController;
private final LatencyTracker mLatencyTracker;
private final VibratorHelper mVibratorHelper;
+ private final BiometricUnlockLogger mLogger;
private long mLastFpFailureUptimeMillis;
private int mNumConsecutiveFpFailures;
@@ -257,7 +254,8 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
private final ScreenOffAnimationController mScreenOffAnimationController;
@Inject
- public BiometricUnlockController(DozeScrimController dozeScrimController,
+ public BiometricUnlockController(
+ DozeScrimController dozeScrimController,
KeyguardViewMediator keyguardViewMediator, ScrimController scrimController,
NotificationShadeWindowController notificationShadeWindowController,
KeyguardStateController keyguardStateController, Handler handler,
@@ -266,6 +264,7 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
KeyguardBypassController keyguardBypassController,
MetricsLogger metricsLogger, DumpManager dumpManager,
PowerManager powerManager,
+ BiometricUnlockLogger biometricUnlockLogger,
NotificationMediaManager notificationMediaManager,
WakefulnessLifecycle wakefulnessLifecycle,
ScreenLifecycle screenLifecycle,
@@ -299,6 +298,7 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
mSessionTracker = sessionTracker;
mScreenOffAnimationController = screenOffAnimationController;
mVibratorHelper = vibrator;
+ mLogger = biometricUnlockLogger;
dumpManager.registerDumpable(getClass().getName(), this);
}
@@ -320,9 +320,7 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
private final Runnable mReleaseBiometricWakeLockRunnable = new Runnable() {
@Override
public void run() {
- if (DEBUG_BIO_WAKELOCK) {
- Log.i(TAG, "biometric wakelock: TIMEOUT!!");
- }
+ mLogger.i("biometric wakelock: TIMEOUT!!");
releaseBiometricWakeLock();
}
};
@@ -330,9 +328,7 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
private void releaseBiometricWakeLock() {
if (mWakeLock != null) {
mHandler.removeCallbacks(mReleaseBiometricWakeLockRunnable);
- if (DEBUG_BIO_WAKELOCK) {
- Log.i(TAG, "releasing biometric wakelock");
- }
+ mLogger.i("releasing biometric wakelock");
mWakeLock.release();
mWakeLock = null;
}
@@ -363,9 +359,7 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
Trace.beginSection("acquiring wake-and-unlock");
mWakeLock.acquire();
Trace.endSection();
- if (DEBUG_BIO_WAKELOCK) {
- Log.i(TAG, "biometric acquired, grabbing biometric wakelock");
- }
+ mLogger.i("biometric acquired, grabbing biometric wakelock");
mHandler.postDelayed(mReleaseBiometricWakeLockRunnable,
BIOMETRIC_WAKELOCK_TIMEOUT_MS);
}
@@ -402,7 +396,7 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
mKeyguardViewMediator.userActivity();
startWakeAndUnlock(biometricSourceType, isStrongBiometric);
} else {
- Log.d(TAG, "onBiometricAuthenticated aborted by bypass controller");
+ mLogger.d("onBiometricAuthenticated aborted by bypass controller");
}
}
@@ -418,7 +412,7 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
}
public void startWakeAndUnlock(@WakeAndUnlockMode int mode) {
- Log.v(TAG, "startWakeAndUnlock(" + mode + ")");
+ mLogger.logStartWakeAndUnlock(mode);
boolean wasDeviceInteractive = mUpdateMonitor.isDeviceInteractive();
mMode = mode;
mHasScreenTurnedOnSinceAuthenticating = false;
@@ -433,9 +427,7 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
// brightness changes due to display state transitions.
Runnable wakeUp = ()-> {
if (!wasDeviceInteractive || mUpdateMonitor.isDreaming()) {
- if (DEBUG_BIO_WAKELOCK) {
- Log.i(TAG, "bio wakelock: Authenticated, waking up...");
- }
+ mLogger.i("bio wakelock: Authenticated, waking up...");
mPowerManager.wakeUp(SystemClock.uptimeMillis(), PowerManager.WAKE_REASON_GESTURE,
"android.policy:BIOMETRIC");
}
@@ -519,13 +511,16 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
}
private @WakeAndUnlockMode int calculateModeForFingerprint(boolean isStrongBiometric) {
- boolean unlockingAllowed =
+ final boolean unlockingAllowed =
mUpdateMonitor.isUnlockingWithBiometricAllowed(isStrongBiometric);
- boolean deviceDreaming = mUpdateMonitor.isDreaming();
-
- if (!mUpdateMonitor.isDeviceInteractive()) {
- if (!mKeyguardStateController.isShowing()
- && !mScreenOffAnimationController.isKeyguardShowDelayed()) {
+ final boolean deviceInteractive = mUpdateMonitor.isDeviceInteractive();
+ final boolean keyguardShowing = mKeyguardStateController.isShowing();
+ final boolean deviceDreaming = mUpdateMonitor.isDreaming();
+
+ logCalculateModeForFingerprint(unlockingAllowed, deviceInteractive,
+ keyguardShowing, deviceDreaming, isStrongBiometric);
+ if (!deviceInteractive) {
+ if (!keyguardShowing && !mScreenOffAnimationController.isKeyguardShowDelayed()) {
if (mKeyguardStateController.isUnlocked()) {
return MODE_WAKE_AND_UNLOCK;
}
@@ -541,7 +536,7 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
if (unlockingAllowed && deviceDreaming) {
return MODE_WAKE_AND_UNLOCK_FROM_DREAM;
}
- if (mKeyguardStateController.isShowing()) {
+ if (keyguardShowing) {
if (mKeyguardViewController.primaryBouncerIsOrWillBeShowing() && unlockingAllowed) {
return MODE_DISMISS_BOUNCER;
} else if (unlockingAllowed) {
@@ -553,14 +548,39 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
return MODE_NONE;
}
+ private void logCalculateModeForFingerprint(boolean unlockingAllowed, boolean deviceInteractive,
+ boolean keyguardShowing, boolean deviceDreaming, boolean strongBiometric) {
+ if (unlockingAllowed) {
+ mLogger.logCalculateModeForFingerprintUnlockingAllowed(deviceInteractive,
+ keyguardShowing, deviceDreaming);
+ } else {
+ // if unlocking isn't allowed, log more information about why unlocking may not
+ // have been allowed
+ final int strongAuthFlags = mUpdateMonitor.getStrongAuthTracker().getStrongAuthForUser(
+ KeyguardUpdateMonitor.getCurrentUser());
+ final boolean nonStrongBiometricAllowed =
+ mUpdateMonitor.getStrongAuthTracker()
+ .isNonStrongBiometricAllowedAfterIdleTimeout(
+ KeyguardUpdateMonitor.getCurrentUser());
+
+ mLogger.logCalculateModeForFingerprintUnlockingNotAllowed(strongBiometric,
+ strongAuthFlags, nonStrongBiometricAllowed, deviceInteractive, keyguardShowing);
+ }
+ }
+
private @WakeAndUnlockMode int calculateModeForPassiveAuth(boolean isStrongBiometric) {
- boolean unlockingAllowed =
+ final boolean deviceInteractive = mUpdateMonitor.isDeviceInteractive();
+ final boolean isKeyguardShowing = mKeyguardStateController.isShowing();
+ final boolean unlockingAllowed =
mUpdateMonitor.isUnlockingWithBiometricAllowed(isStrongBiometric);
- boolean deviceDreaming = mUpdateMonitor.isDreaming();
- boolean bypass = mKeyguardBypassController.getBypassEnabled()
+ final boolean deviceDreaming = mUpdateMonitor.isDreaming();
+ final boolean bypass = mKeyguardBypassController.getBypassEnabled()
|| mAuthController.isUdfpsFingerDown();
- if (!mUpdateMonitor.isDeviceInteractive()) {
- if (!mKeyguardStateController.isShowing()) {
+
+ logCalculateModeForPassiveAuth(unlockingAllowed, deviceInteractive, isKeyguardShowing,
+ deviceDreaming, bypass, isStrongBiometric);
+ if (!deviceInteractive) {
+ if (!isKeyguardShowing) {
return bypass ? MODE_WAKE_AND_UNLOCK : MODE_ONLY_WAKE;
} else if (!unlockingAllowed) {
return bypass ? MODE_SHOW_BOUNCER : MODE_NONE;
@@ -584,11 +604,11 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
if (unlockingAllowed && mKeyguardStateController.isOccluded()) {
return MODE_UNLOCK_COLLAPSING;
}
- if (mKeyguardStateController.isShowing()) {
+ if (isKeyguardShowing) {
if ((mKeyguardViewController.primaryBouncerIsOrWillBeShowing()
|| mKeyguardBypassController.getAltBouncerShowing()) && unlockingAllowed) {
return MODE_DISMISS_BOUNCER;
- } else if (unlockingAllowed && (bypass || mAuthController.isUdfpsFingerDown())) {
+ } else if (unlockingAllowed && bypass) {
return MODE_UNLOCK_COLLAPSING;
} else {
return bypass ? MODE_SHOW_BOUNCER : MODE_NONE;
@@ -597,6 +617,28 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
return MODE_NONE;
}
+ private void logCalculateModeForPassiveAuth(boolean unlockingAllowed,
+ boolean deviceInteractive, boolean keyguardShowing, boolean deviceDreaming,
+ boolean bypass, boolean strongBiometric) {
+ if (unlockingAllowed) {
+ mLogger.logCalculateModeForPassiveAuthUnlockingAllowed(
+ deviceInteractive, keyguardShowing, deviceDreaming, bypass);
+ } else {
+ // if unlocking isn't allowed, log more information about why unlocking may not
+ // have been allowed
+ final int strongAuthFlags = mUpdateMonitor.getStrongAuthTracker().getStrongAuthForUser(
+ KeyguardUpdateMonitor.getCurrentUser());
+ final boolean nonStrongBiometricAllowed =
+ mUpdateMonitor.getStrongAuthTracker()
+ .isNonStrongBiometricAllowedAfterIdleTimeout(
+ KeyguardUpdateMonitor.getCurrentUser());
+
+ mLogger.logCalculateModeForPassiveAuthUnlockingNotAllowed(
+ strongBiometric, strongAuthFlags, nonStrongBiometricAllowed,
+ deviceInteractive, keyguardShowing, bypass);
+ }
+ }
+
@Override
public void onBiometricAuthFailed(BiometricSourceType biometricSourceType) {
mMetricsLogger.write(new LogMaker(MetricsEvent.BIOMETRIC_AUTH)
@@ -614,6 +656,7 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
if (!mVibratorHelper.hasVibrator()
&& (!mUpdateMonitor.isDeviceInteractive() || mUpdateMonitor.isDreaming())) {
+ mLogger.d("wakeup device on authentication failure (device doesn't have a vibrator)");
startWakeAndUnlock(MODE_ONLY_WAKE);
} else if (biometricSourceType == BiometricSourceType.FINGERPRINT
&& mUpdateMonitor.isUdfpsSupported()) {
@@ -626,6 +669,7 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
mLastFpFailureUptimeMillis = currUptimeMillis;
if (mNumConsecutiveFpFailures >= UDFPS_ATTEMPTS_BEFORE_SHOW_BOUNCER) {
+ mLogger.logUdfpsAttemptThresholdMet(mNumConsecutiveFpFailures);
startWakeAndUnlock(MODE_SHOW_BOUNCER);
UI_EVENT_LOGGER.log(BiometricUiEvent.BIOMETRIC_BOUNCER_SHOWN, getSessionId());
mNumConsecutiveFpFailures = 0;
@@ -656,6 +700,7 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
&& (msgId == FingerprintManager.FINGERPRINT_ERROR_LOCKOUT
|| msgId == FingerprintManager.FINGERPRINT_ERROR_LOCKOUT_PERMANENT);
if (fingerprintLockout) {
+ mLogger.d("fingerprint locked out");
startWakeAndUnlock(MODE_SHOW_BOUNCER);
UI_EVENT_LOGGER.log(BiometricUiEvent.BIOMETRIC_BOUNCER_SHOWN, getSessionId());
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
index eefceb794607..5efd4603500f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
@@ -241,6 +241,8 @@ import com.android.wm.shell.bubbles.Bubbles;
import com.android.wm.shell.startingsurface.SplashscreenContentDrawer;
import com.android.wm.shell.startingsurface.StartingSurface;
+import dagger.Lazy;
+
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.List;
@@ -251,8 +253,6 @@ import java.util.concurrent.Executor;
import javax.inject.Inject;
import javax.inject.Named;
-import dagger.Lazy;
-
/**
* A class handling initialization and coordination between some of the key central surfaces in
* System UI: The notification shade, the keyguard (lockscreen), and the status bar.
@@ -4204,7 +4204,7 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
Log.wtf(TAG, "WallpaperManager not supported");
return;
}
- WallpaperInfo info = mWallpaperManager.getWallpaperInfo(UserHandle.USER_CURRENT);
+ WallpaperInfo info = mWallpaperManager.getWallpaperInfoForUser(UserHandle.USER_CURRENT);
mWallpaperController.onWallpaperInfoUpdated(info);
final boolean deviceSupportsAodWallpaper = mContext.getResources().getBoolean(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LetterboxAppearanceCalculator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LetterboxAppearanceCalculator.kt
index 4496607a7db2..398985402e76 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LetterboxAppearanceCalculator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LetterboxAppearanceCalculator.kt
@@ -62,7 +62,7 @@ constructor(
private var statusBarBoundsProvider: StatusBarBoundsProvider? = null
override fun start() {
- dumpManager.registerDumpable(javaClass.simpleName) { printWriter, _ -> dump(printWriter) }
+ dumpManager.registerCriticalDumpable(javaClass.simpleName) { pw, _ -> dump(pw) }
}
override fun stop() {
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 d464210750d3..44ad60473925 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -475,7 +475,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
} else {
mPrimaryBouncerInteractor.setPanelExpansion(KeyguardBouncer.EXPANSION_VISIBLE);
}
- } else if (mKeyguardStateController.isShowing() && !hideBouncerOverDream) {
+ } else if (mKeyguardStateController.isShowing() && !hideBouncerOverDream) {
if (!isWakeAndUnlocking()
&& !(mBiometricUnlockController.getMode() == MODE_DISMISS_BOUNCER)
&& !(mBiometricUnlockController.getMode() == MODE_SHOW_BOUNCER)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImpl.kt
index e3266115f777..6c66f0bb1e47 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImpl.kt
@@ -140,6 +140,9 @@ public class DeviceControlsControllerImpl @Inject constructor(
// is out of sync, perhaps through a device restore, and update the
// preference
addPackageToSeededSet(prefs, pkg)
+ } else if (it.panelActivity != null) {
+ // Do not seed for packages with panels
+ addPackageToSeededSet(prefs, pkg)
} else {
componentsToSeed.add(it.componentName)
}
diff --git a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldLightRevealOverlayAnimation.kt b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldLightRevealOverlayAnimation.kt
index d411e34603d9..ae30ca0e6a61 100644
--- a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldLightRevealOverlayAnimation.kt
+++ b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldLightRevealOverlayAnimation.kt
@@ -94,7 +94,7 @@ constructor(
overlayContainer = builder.build()
SurfaceControl.Transaction()
- .setLayer(overlayContainer, Integer.MAX_VALUE)
+ .setLayer(overlayContainer, UNFOLD_OVERLAY_LAYER_Z_INDEX)
.show(overlayContainer)
.apply()
@@ -268,4 +268,12 @@ constructor(
this.isFolded = isFolded
}
)
+
+ private companion object {
+ private const val ROTATION_ANIMATION_OVERLAY_Z_INDEX = Integer.MAX_VALUE
+
+ // Put the unfold overlay below the rotation animation screenshot to hide the moment
+ // when it is rotated but the rotation of the other windows hasn't happen yet
+ private const val UNFOLD_OVERLAY_LAYER_Z_INDEX = ROTATION_ANIMATION_OVERLAY_Z_INDEX - 1
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserInteractor.kt b/packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserInteractor.kt
index 66724695578a..c5b697c90e0c 100644
--- a/packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserInteractor.kt
@@ -156,42 +156,64 @@ constructor(
keyguardInteractor.isKeyguardShowing,
) { _, userInfos, settings, isDeviceLocked ->
buildList {
- val hasGuestUser = userInfos.any { it.isGuest }
- if (!hasGuestUser && canCreateGuestUser(settings)) {
- add(UserActionModel.ENTER_GUEST_MODE)
- }
-
if (!isDeviceLocked || settings.isAddUsersFromLockscreen) {
// The device is locked and our setting to allow actions that add users
- // from the lock-screen is not enabled. The guest action from above is
- // always allowed, even when the device is locked, but the various "add
- // user" actions below are not. We can finish building the list here.
-
- val canCreateUsers =
- UserActionsUtil.canCreateUser(
- manager,
- repository,
- settings.isUserSwitcherEnabled,
- settings.isAddUsersFromLockscreen,
- )
-
- if (canCreateUsers) {
- add(UserActionModel.ADD_USER)
- }
-
- if (
- UserActionsUtil.canCreateSupervisedUser(
- manager,
- repository,
- settings.isUserSwitcherEnabled,
- settings.isAddUsersFromLockscreen,
- supervisedUserPackageName,
- )
- ) {
- add(UserActionModel.ADD_SUPERVISED_USER)
+ // from the lock-screen is not enabled. We can finish building the list
+ // here.
+ val isFullScreen = featureFlags.isEnabled(Flags.FULL_SCREEN_USER_SWITCHER)
+
+ val actionList: List<UserActionModel> =
+ if (isFullScreen) {
+ listOf(
+ UserActionModel.ADD_USER,
+ UserActionModel.ADD_SUPERVISED_USER,
+ UserActionModel.ENTER_GUEST_MODE,
+ )
+ } else {
+ listOf(
+ UserActionModel.ENTER_GUEST_MODE,
+ UserActionModel.ADD_USER,
+ UserActionModel.ADD_SUPERVISED_USER,
+ )
+ }
+ actionList.map {
+ when (it) {
+ UserActionModel.ENTER_GUEST_MODE -> {
+ val hasGuestUser = userInfos.any { it.isGuest }
+ if (!hasGuestUser && canCreateGuestUser(settings)) {
+ add(UserActionModel.ENTER_GUEST_MODE)
+ }
+ }
+ UserActionModel.ADD_USER -> {
+ val canCreateUsers =
+ UserActionsUtil.canCreateUser(
+ manager,
+ repository,
+ settings.isUserSwitcherEnabled,
+ settings.isAddUsersFromLockscreen,
+ )
+
+ if (canCreateUsers) {
+ add(UserActionModel.ADD_USER)
+ }
+ }
+ UserActionModel.ADD_SUPERVISED_USER -> {
+ if (
+ UserActionsUtil.canCreateSupervisedUser(
+ manager,
+ repository,
+ settings.isUserSwitcherEnabled,
+ settings.isAddUsersFromLockscreen,
+ supervisedUserPackageName,
+ )
+ ) {
+ add(UserActionModel.ADD_SUPERVISED_USER)
+ }
+ }
+ else -> Unit
+ }
}
}
-
if (
UserActionsUtil.canManageUsers(
repository,
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index d062fff32db8..833a6a4193c4 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -638,8 +638,7 @@ public class VolumeDialogImpl implements VolumeDialog,
mRingerDrawerNormalIcon = mDialog.findViewById(R.id.volume_drawer_normal_icon);
mRingerDrawerNewSelectionBg = mDialog.findViewById(R.id.volume_drawer_selection_background);
- mRingerDrawerMuteIcon.setImageResource(mVolumeRingerMuteIconDrawableId);
- mRingerDrawerNormalIcon.setImageResource(mVolumeRingerIconDrawableId);
+ updateRingerModeIconSet();
setupRingerDrawer();
@@ -1404,7 +1403,7 @@ public class VolumeDialogImpl implements VolumeDialog,
private void showH(int reason, boolean keyguardLocked, int lockTaskModeState) {
Trace.beginSection("VolumeDialogImpl#showH");
- if (D.BUG) Log.d(TAG, "showH r=" + Events.SHOW_REASONS[reason]);
+ Log.i(TAG, "showH r=" + Events.SHOW_REASONS[reason]);
mHandler.removeMessages(H.SHOW);
mHandler.removeMessages(H.DISMISS);
rescheduleTimeoutH();
@@ -1432,7 +1431,7 @@ public class VolumeDialogImpl implements VolumeDialog,
final int timeout = computeTimeoutH();
mHandler.sendMessageDelayed(mHandler
.obtainMessage(H.DISMISS, Events.DISMISS_REASON_TIMEOUT, 0), timeout);
- if (D.BUG) Log.d(TAG, "rescheduleTimeout " + timeout + " " + Debug.getCaller());
+ Log.i(TAG, "rescheduleTimeout " + timeout + " " + Debug.getCaller());
mController.userActivity();
}
@@ -1459,10 +1458,10 @@ public class VolumeDialogImpl implements VolumeDialog,
protected void dismissH(int reason) {
Trace.beginSection("VolumeDialogImpl#dismissH");
- if (D.BUG) {
- Log.d(TAG, "mDialog.dismiss() reason: " + Events.DISMISS_REASONS[reason]
- + " from: " + Debug.getCaller());
- }
+
+ Log.i(TAG, "mDialog.dismiss() reason: " + Events.DISMISS_REASONS[reason]
+ + " from: " + Debug.getCaller());
+
mHandler.removeMessages(H.DISMISS);
mHandler.removeMessages(H.SHOW);
if (mIsAnimatingDismiss) {
diff --git a/packages/SystemUI/tests/robolectric/config/robolectric.properties b/packages/SystemUI/tests/robolectric/config/robolectric.properties
new file mode 100644
index 000000000000..2a75bd98bfe8
--- /dev/null
+++ b/packages/SystemUI/tests/robolectric/config/robolectric.properties
@@ -0,0 +1,16 @@
+#
+# Copyright (C) 2022 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+sdk=NEWEST_SDK \ No newline at end of file
diff --git a/packages/SystemUI/tests/robolectric/src/com/android/systemui/robotests/SysuiResourceLoadingTest.java b/packages/SystemUI/tests/robolectric/src/com/android/systemui/robotests/SysuiResourceLoadingTest.java
new file mode 100644
index 000000000000..188dff21efa4
--- /dev/null
+++ b/packages/SystemUI/tests/robolectric/src/com/android/systemui/robotests/SysuiResourceLoadingTest.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.robotests;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+import static com.google.common.truth.Truth.assertThat;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class SysuiResourceLoadingTest extends SysuiRoboBase {
+ @Test
+ public void testResources() {
+ assertThat(getContext().getString(com.android.systemui.R.string.app_label))
+ .isEqualTo("System UI");
+ assertThat(getContext().getString(com.android.systemui.tests.R.string.test_content))
+ .isNotEmpty();
+ }
+}
diff --git a/services/permission/java/com/android/server/permission/ModernPermissionManagerServiceImpl.kt b/packages/SystemUI/tests/robolectric/src/com/android/systemui/robotests/SysuiRoboBase.java
index 21ec1593fdeb..d9686bbeb0cd 100644
--- a/services/permission/java/com/android/server/permission/ModernPermissionManagerServiceImpl.kt
+++ b/packages/SystemUI/tests/robolectric/src/com/android/systemui/robotests/SysuiRoboBase.java
@@ -14,13 +14,14 @@
* limitations under the License.
*/
-package com.android.server.permission
+package com.android.systemui.robotests;
-import com.android.internal.annotations.Keep
-import com.android.server.pm.permission.PermissionManagerServiceInterface
+import android.content.Context;
-/**
- * Modern implementation of [PermissionManagerServiceInterface].
- */
-@Keep
-class ModernPermissionManagerServiceImpl
+import androidx.test.InstrumentationRegistry;
+
+public class SysuiRoboBase {
+ public Context getContext() {
+ return InstrumentationRegistry.getContext();
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/management/AppAdapterTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/management/AppAdapterTest.kt
index 1e4a9e42cce1..765c4c0ac0f0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/management/AppAdapterTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/management/AppAdapterTest.kt
@@ -27,6 +27,7 @@ import com.android.systemui.SysuiTestCase
import com.android.systemui.controls.ControlsServiceInfo
import com.android.systemui.util.concurrency.FakeExecutor
import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.mock
import com.android.systemui.util.time.FakeSystemClock
import com.google.common.truth.Truth.assertThat
import org.junit.Before
@@ -34,9 +35,8 @@ import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentCaptor
import org.mockito.Mock
-import org.mockito.Mockito.mock
-import org.mockito.Mockito.verify
import org.mockito.Mockito.`when`
+import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
@SmallTest
@@ -70,7 +70,7 @@ class AppAdapterTest : SysuiTestCase() {
fun testOnServicesUpdated_nullLoadLabel() {
val captor = ArgumentCaptor
.forClass(ControlsListingController.ControlsListingCallback::class.java)
- val controlsServiceInfo = mock(ControlsServiceInfo::class.java)
+ val controlsServiceInfo = mock<ControlsServiceInfo>()
val serviceInfo = listOf(controlsServiceInfo)
`when`(controlsServiceInfo.loadLabel()).thenReturn(null)
verify(controlsListingController).observe(any(Lifecycle::class.java), captor.capture())
@@ -81,4 +81,32 @@ class AppAdapterTest : SysuiTestCase() {
assertThat(adapter.itemCount).isEqualTo(serviceInfo.size)
}
+
+ @Test
+ fun testOnServicesUpdatedDoesntHavePanels() {
+ val captor = ArgumentCaptor
+ .forClass(ControlsListingController.ControlsListingCallback::class.java)
+ val serviceInfo = listOf(
+ ControlsServiceInfo("no panel", null),
+ ControlsServiceInfo("panel", mock())
+ )
+ verify(controlsListingController).observe(any(Lifecycle::class.java), captor.capture())
+
+ captor.value.onServicesUpdated(serviceInfo)
+ backgroundExecutor.runAllReady()
+ uiExecutor.runAllReady()
+
+ assertThat(adapter.itemCount).isEqualTo(1)
+ }
+
+ fun ControlsServiceInfo(
+ label: CharSequence,
+ panelComponentName: ComponentName? = null
+ ): ControlsServiceInfo {
+ return mock {
+ `when`(this.loadLabel()).thenReturn(label)
+ `when`(this.panelActivity).thenReturn(panelComponentName)
+ `when`(this.loadIcon()).thenReturn(mock())
+ }
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsFavoritingActivityTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsFavoritingActivityTest.kt
index 0f06de2a0684..365523233353 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsFavoritingActivityTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsFavoritingActivityTest.kt
@@ -5,6 +5,7 @@ import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import android.window.OnBackInvokedCallback
import android.window.OnBackInvokedDispatcher
+import androidx.test.filters.FlakyTest
import androidx.test.filters.SmallTest
import androidx.test.rule.ActivityTestRule
import androidx.test.runner.intercepting.SingleActivityFactory
@@ -79,6 +80,8 @@ class ControlsFavoritingActivityTest : SysuiTestCase() {
activityRule.launchActivity(intent)
}
+ // b/259549854 to root-cause and fix
+ @FlakyTest
@Test
fun testBackCallbackRegistrationAndUnregistration() {
// 1. ensure that launching the activity results in it registering a callback
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsUiControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsUiControllerImplTest.kt
index 49c7442b9708..e679b1391c77 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsUiControllerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsUiControllerImplTest.kt
@@ -17,8 +17,10 @@
package com.android.systemui.controls.ui
import android.content.ComponentName
+import android.content.Context
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
+import android.widget.FrameLayout
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.controls.ControlsMetricsLogger
@@ -26,6 +28,7 @@ import com.android.systemui.controls.CustomIconCache
import com.android.systemui.controls.controller.ControlsController
import com.android.systemui.controls.controller.StructureInfo
import com.android.systemui.controls.management.ControlsListingController
+import com.android.systemui.dump.DumpManager
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.settings.UserFileManager
import com.android.systemui.settings.UserTracker
@@ -34,9 +37,12 @@ import com.android.systemui.statusbar.policy.DeviceControlsControllerImpl
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.util.FakeSharedPreferences
import com.android.systemui.util.concurrency.FakeExecutor
+import com.android.systemui.util.mockito.any
import com.android.systemui.util.time.FakeSystemClock
+import com.android.wm.shell.TaskViewFactory
import com.google.common.truth.Truth.assertThat
import dagger.Lazy
+import java.util.Optional
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -44,7 +50,7 @@ import org.mockito.Mock
import org.mockito.Mockito.anyInt
import org.mockito.Mockito.anyString
import org.mockito.Mockito.mock
-import org.mockito.Mockito.times
+import org.mockito.Mockito.never
import org.mockito.Mockito.verify
import org.mockito.Mockito.`when`
import org.mockito.MockitoAnnotations
@@ -63,16 +69,22 @@ class ControlsUiControllerImplTest : SysuiTestCase() {
@Mock lateinit var keyguardStateController: KeyguardStateController
@Mock lateinit var userFileManager: UserFileManager
@Mock lateinit var userTracker: UserTracker
+ @Mock lateinit var taskViewFactory: TaskViewFactory
+ @Mock lateinit var activityContext: Context
+ @Mock lateinit var dumpManager: DumpManager
val sharedPreferences = FakeSharedPreferences()
var uiExecutor = FakeExecutor(FakeSystemClock())
var bgExecutor = FakeExecutor(FakeSystemClock())
lateinit var underTest: ControlsUiControllerImpl
+ lateinit var parent: FrameLayout
@Before
fun setup() {
MockitoAnnotations.initMocks(this)
+ parent = FrameLayout(mContext)
+
underTest =
ControlsUiControllerImpl(
Lazy { controlsController },
@@ -82,12 +94,13 @@ class ControlsUiControllerImplTest : SysuiTestCase() {
Lazy { controlsListingController },
controlActionCoordinator,
activityStarter,
- shadeController,
iconCache,
controlsMetricsLogger,
keyguardStateController,
userFileManager,
- userTracker
+ userTracker,
+ Optional.of(taskViewFactory),
+ dumpManager
)
`when`(
userFileManager.getSharedPreferences(
@@ -105,8 +118,8 @@ class ControlsUiControllerImplTest : SysuiTestCase() {
@Test
fun testGetPreferredStructure() {
val structureInfo = mock(StructureInfo::class.java)
- underTest.getPreferredStructure(listOf(structureInfo))
- verify(userFileManager, times(2))
+ underTest.getPreferredSelectedItem(listOf(structureInfo))
+ verify(userFileManager)
.getSharedPreferences(
fileName = DeviceControlsControllerImpl.PREFS_CONTROLS_FILE,
mode = 0,
@@ -116,25 +129,30 @@ class ControlsUiControllerImplTest : SysuiTestCase() {
@Test
fun testGetPreferredStructure_differentUserId() {
- val structureInfo =
+ val selectedItems =
listOf(
- StructureInfo(ComponentName.unflattenFromString("pkg/.cls1"), "a", ArrayList()),
- StructureInfo(ComponentName.unflattenFromString("pkg/.cls2"), "b", ArrayList()),
+ SelectedItem.StructureItem(
+ StructureInfo(ComponentName.unflattenFromString("pkg/.cls1"), "a", ArrayList())
+ ),
+ SelectedItem.StructureItem(
+ StructureInfo(ComponentName.unflattenFromString("pkg/.cls2"), "b", ArrayList())
+ ),
)
+ val structures = selectedItems.map { it.structure }
sharedPreferences
.edit()
- .putString("controls_component", structureInfo[0].componentName.flattenToString())
- .putString("controls_structure", structureInfo[0].structure.toString())
+ .putString("controls_component", selectedItems[0].componentName.flattenToString())
+ .putString("controls_structure", selectedItems[0].name.toString())
.commit()
val differentSharedPreferences = FakeSharedPreferences()
differentSharedPreferences
.edit()
- .putString("controls_component", structureInfo[1].componentName.flattenToString())
- .putString("controls_structure", structureInfo[1].structure.toString())
+ .putString("controls_component", selectedItems[1].componentName.flattenToString())
+ .putString("controls_structure", selectedItems[1].name.toString())
.commit()
- val previousPreferredStructure = underTest.getPreferredStructure(structureInfo)
+ val previousPreferredStructure = underTest.getPreferredSelectedItem(structures)
`when`(
userFileManager.getSharedPreferences(
@@ -146,10 +164,39 @@ class ControlsUiControllerImplTest : SysuiTestCase() {
.thenReturn(differentSharedPreferences)
`when`(userTracker.userId).thenReturn(1)
- val currentPreferredStructure = underTest.getPreferredStructure(structureInfo)
+ val currentPreferredStructure = underTest.getPreferredSelectedItem(structures)
- assertThat(previousPreferredStructure).isEqualTo(structureInfo[0])
- assertThat(currentPreferredStructure).isEqualTo(structureInfo[1])
+ assertThat(previousPreferredStructure).isEqualTo(selectedItems[0])
+ assertThat(currentPreferredStructure).isEqualTo(selectedItems[1])
assertThat(currentPreferredStructure).isNotEqualTo(previousPreferredStructure)
}
+
+ @Test
+ fun testGetPreferredPanel() {
+ val panel = SelectedItem.PanelItem("App name", ComponentName("pkg", "cls"))
+ sharedPreferences
+ .edit()
+ .putString("controls_component", panel.componentName.flattenToString())
+ .putString("controls_structure", panel.appName.toString())
+ .putBoolean("controls_is_panel", true)
+ .commit()
+
+ val selected = underTest.getPreferredSelectedItem(emptyList())
+
+ assertThat(selected).isEqualTo(panel)
+ }
+
+ @Test
+ fun testPanelDoesNotRefreshControls() {
+ val panel = SelectedItem.PanelItem("App name", ComponentName("pkg", "cls"))
+ sharedPreferences
+ .edit()
+ .putString("controls_component", panel.componentName.flattenToString())
+ .putString("controls_structure", panel.appName.toString())
+ .putBoolean("controls_is_panel", true)
+ .commit()
+
+ underTest.show(parent, {}, activityContext)
+ verify(controlsController, never()).refreshStatus(any(), any())
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/PanelTaskViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/PanelTaskViewControllerTest.kt
new file mode 100644
index 000000000000..5cd2ace4604a
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/PanelTaskViewControllerTest.kt
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.android.systemui.controls.ui
+
+import android.app.ActivityOptions
+import android.app.PendingIntent
+import android.content.Context
+import android.content.Intent
+import android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK
+import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
+import android.graphics.Rect
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.util.boundsOnScreen
+import com.android.systemui.util.concurrency.FakeExecutor
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.argumentCaptor
+import com.android.systemui.util.mockito.capture
+import com.android.systemui.util.mockito.eq
+import com.android.systemui.util.mockito.whenever
+import com.android.systemui.util.time.FakeSystemClock
+import com.android.wm.shell.TaskView
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
+import org.mockito.Captor
+import org.mockito.Mock
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper
+class PanelTaskViewControllerTest : SysuiTestCase() {
+
+ companion object {
+ val FAKE_BOUNDS = Rect(10, 20, 30, 40)
+ }
+
+ @Mock private lateinit var activityContext: Context
+ @Mock private lateinit var taskView: TaskView
+ @Mock private lateinit var pendingIntent: PendingIntent
+ @Mock private lateinit var hideRunnable: () -> Unit
+
+ @Captor private lateinit var listenerCaptor: ArgumentCaptor<TaskView.Listener>
+
+ private lateinit var uiExecutor: FakeExecutor
+ private lateinit var underTest: PanelTaskViewController
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+
+ whenever(taskView.boundsOnScreen).thenAnswer { (it.arguments[0] as Rect).set(FAKE_BOUNDS) }
+ whenever(taskView.post(any())).thenAnswer {
+ uiExecutor.execute(it.arguments[0] as Runnable)
+ true
+ }
+
+ uiExecutor = FakeExecutor(FakeSystemClock())
+
+ underTest =
+ PanelTaskViewController(
+ activityContext,
+ uiExecutor,
+ pendingIntent,
+ taskView,
+ hideRunnable
+ )
+ }
+
+ @Test
+ fun testLaunchTaskViewAttachedListener() {
+ underTest.launchTaskView()
+ verify(taskView).setListener(eq(uiExecutor), any())
+ }
+
+ @Test
+ fun testTaskViewOnInitializeStartsActivity() {
+ underTest.launchTaskView()
+ verify(taskView).setListener(any(), capture(listenerCaptor))
+
+ listenerCaptor.value.onInitialized()
+ uiExecutor.runAllReady()
+
+ val intentCaptor = argumentCaptor<Intent>()
+ val optionsCaptor = argumentCaptor<ActivityOptions>()
+
+ verify(taskView)
+ .startActivity(
+ eq(pendingIntent),
+ /* fillInIntent */ capture(intentCaptor),
+ capture(optionsCaptor),
+ eq(FAKE_BOUNDS)
+ )
+
+ assertThat(intentCaptor.value.flags)
+ .isEqualTo(FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_MULTIPLE_TASK)
+ assertThat(optionsCaptor.value.taskAlwaysOnTop).isTrue()
+ }
+
+ @Test
+ fun testHideRunnableCalledWhenBackOnRoot() {
+ underTest.launchTaskView()
+ verify(taskView).setListener(any(), capture(listenerCaptor))
+
+ listenerCaptor.value.onBackPressedOnTaskRoot(0)
+
+ verify(hideRunnable).invoke()
+ }
+
+ @Test
+ fun testTaskViewReleasedOnDismiss() {
+ underTest.dismiss()
+ verify(taskView).release()
+ }
+
+ @Test
+ fun testTaskViewReleasedOnBackOnRoot() {
+ underTest.launchTaskView()
+ verify(taskView).setListener(any(), capture(listenerCaptor))
+
+ listenerCaptor.value.onBackPressedOnTaskRoot(0)
+ verify(taskView).release()
+ }
+
+ @Test
+ fun testOnTaskRemovalStarted() {
+ underTest.launchTaskView()
+ verify(taskView).setListener(any(), capture(listenerCaptor))
+
+ listenerCaptor.value.onTaskRemovalStarted(0)
+ verify(taskView).release()
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/SelectionItemTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/SelectionItemTest.kt
new file mode 100644
index 000000000000..57176f0eabe0
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/SelectionItemTest.kt
@@ -0,0 +1,112 @@
+package com.android.systemui.controls.ui
+
+import android.content.ComponentName
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.controls.controller.StructureInfo
+import com.android.systemui.util.mockito.mock
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class SelectionItemTest : SysuiTestCase() {
+
+ @Test
+ fun testMatchBadComponentName_false() {
+ val selectionItem =
+ SelectionItem(
+ appName = "app",
+ structure = "structure",
+ icon = mock(),
+ componentName = ComponentName("pkg", "cls"),
+ uid = 0,
+ panelComponentName = null
+ )
+
+ assertThat(
+ selectionItem.matches(
+ SelectedItem.StructureItem(
+ StructureInfo(ComponentName("", ""), "s", emptyList())
+ )
+ )
+ )
+ .isFalse()
+ assertThat(selectionItem.matches(SelectedItem.PanelItem("name", ComponentName("", ""))))
+ .isFalse()
+ }
+
+ @Test
+ fun testMatchSameComponentName_panelSelected_true() {
+ val componentName = ComponentName("pkg", "cls")
+
+ val selectionItem =
+ SelectionItem(
+ appName = "app",
+ structure = "structure",
+ icon = mock(),
+ componentName = componentName,
+ uid = 0,
+ panelComponentName = null
+ )
+ assertThat(selectionItem.matches(SelectedItem.PanelItem("name", componentName))).isTrue()
+ }
+
+ @Test
+ fun testMatchSameComponentName_panelSelection_true() {
+ val componentName = ComponentName("pkg", "cls")
+
+ val selectionItem =
+ SelectionItem(
+ appName = "app",
+ structure = "structure",
+ icon = mock(),
+ componentName = componentName,
+ uid = 0,
+ panelComponentName = ComponentName("pkg", "panel")
+ )
+ assertThat(selectionItem.matches(SelectedItem.PanelItem("name", componentName))).isTrue()
+ }
+
+ @Test
+ fun testMatchSameComponentSameStructure_true() {
+ val componentName = ComponentName("pkg", "cls")
+ val structureName = "structure"
+
+ val structureItem =
+ SelectedItem.StructureItem(StructureInfo(componentName, structureName, emptyList()))
+
+ val selectionItem =
+ SelectionItem(
+ appName = "app",
+ structure = structureName,
+ icon = mock(),
+ componentName = componentName,
+ uid = 0,
+ panelComponentName = null
+ )
+ assertThat(selectionItem.matches(structureItem)).isTrue()
+ }
+
+ @Test
+ fun testMatchSameComponentDifferentStructure_false() {
+ val componentName = ComponentName("pkg", "cls")
+ val structureName = "structure"
+
+ val structureItem =
+ SelectedItem.StructureItem(StructureInfo(componentName, structureName, emptyList()))
+
+ val selectionItem =
+ SelectionItem(
+ appName = "app",
+ structure = "other",
+ icon = mock(),
+ componentName = componentName,
+ uid = 0,
+ panelComponentName = null
+ )
+ assertThat(selectionItem.matches(structureItem)).isFalse()
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dump/DumpHandlerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/dump/DumpHandlerTest.kt
index 65ae90b8f7e8..19135d0cc800 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dump/DumpHandlerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/dump/DumpHandlerTest.kt
@@ -103,8 +103,8 @@ class DumpHandlerTest : SysuiTestCase() {
// THEN only the requested ones have their dump() method called
verify(dumpable1).dump(pw, args)
verify(dumpable2, never()).dump(
- any(PrintWriter::class.java),
- any(Array<String>::class.java))
+ any(PrintWriter::class.java),
+ any(Array<String>::class.java))
verify(dumpable3).dump(pw, args)
verify(buffer1, never()).dump(any(PrintWriter::class.java), anyInt())
verify(buffer2).dump(pw, 0)
@@ -126,9 +126,9 @@ class DumpHandlerTest : SysuiTestCase() {
@Test
fun testCriticalDump() {
// GIVEN a variety of registered dumpables and buffers
- dumpManager.registerDumpable("dumpable1", dumpable1)
- dumpManager.registerDumpable("dumpable2", dumpable2)
- dumpManager.registerDumpable("dumpable3", dumpable3)
+ dumpManager.registerCriticalDumpable("dumpable1", dumpable1)
+ dumpManager.registerCriticalDumpable("dumpable2", dumpable2)
+ dumpManager.registerNormalDumpable("dumpable3", dumpable3)
dumpManager.registerBuffer("buffer1", buffer1)
dumpManager.registerBuffer("buffer2", buffer2)
@@ -136,10 +136,12 @@ class DumpHandlerTest : SysuiTestCase() {
val args = arrayOf("--dump-priority", "CRITICAL")
dumpHandler.dump(fd, pw, args)
- // THEN all modules are dumped (but no buffers)
+ // THEN only critical modules are dumped (and no buffers)
verify(dumpable1).dump(pw, args)
verify(dumpable2).dump(pw, args)
- verify(dumpable3).dump(pw, args)
+ verify(dumpable3, never()).dump(
+ any(PrintWriter::class.java),
+ any(Array<String>::class.java))
verify(buffer1, never()).dump(any(PrintWriter::class.java), anyInt())
verify(buffer2, never()).dump(any(PrintWriter::class.java), anyInt())
}
@@ -147,9 +149,9 @@ class DumpHandlerTest : SysuiTestCase() {
@Test
fun testNormalDump() {
// GIVEN a variety of registered dumpables and buffers
- dumpManager.registerDumpable("dumpable1", dumpable1)
- dumpManager.registerDumpable("dumpable2", dumpable2)
- dumpManager.registerDumpable("dumpable3", dumpable3)
+ dumpManager.registerCriticalDumpable("dumpable1", dumpable1)
+ dumpManager.registerCriticalDumpable("dumpable2", dumpable2)
+ dumpManager.registerNormalDumpable("dumpable3", dumpable3)
dumpManager.registerBuffer("buffer1", buffer1)
dumpManager.registerBuffer("buffer2", buffer2)
@@ -157,16 +159,14 @@ class DumpHandlerTest : SysuiTestCase() {
val args = arrayOf("--dump-priority", "NORMAL")
dumpHandler.dump(fd, pw, args)
- // THEN all buffers are dumped (but no modules)
+ // THEN the normal module and all buffers are dumped
verify(dumpable1, never()).dump(
any(PrintWriter::class.java),
any(Array<String>::class.java))
verify(dumpable2, never()).dump(
any(PrintWriter::class.java),
any(Array<String>::class.java))
- verify(dumpable3, never()).dump(
- any(PrintWriter::class.java),
- any(Array<String>::class.java))
+ verify(dumpable3).dump(pw, args)
verify(buffer1).dump(pw, 0)
verify(buffer2).dump(pw, 0)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dump/DumpManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/dump/DumpManagerTest.kt
new file mode 100644
index 000000000000..0c5a74cd39fa
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/dump/DumpManagerTest.kt
@@ -0,0 +1,221 @@
+/*
+ * 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.dump
+
+import androidx.test.filters.SmallTest
+import com.android.systemui.Dumpable
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.plugins.log.LogBuffer
+import com.android.systemui.util.mockito.any
+import java.io.PrintWriter
+import org.junit.Before
+import org.junit.Test
+import org.mockito.Mock
+import org.mockito.Mockito.anyInt
+import org.mockito.Mockito.never
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+class DumpManagerTest : SysuiTestCase() {
+
+ @Mock private lateinit var pw: PrintWriter
+
+ @Mock private lateinit var dumpable1: Dumpable
+ @Mock private lateinit var dumpable2: Dumpable
+ @Mock private lateinit var dumpable3: Dumpable
+
+ @Mock private lateinit var buffer1: LogBuffer
+ @Mock private lateinit var buffer2: LogBuffer
+
+ private val dumpManager = DumpManager()
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+ }
+
+ @Test
+ fun testDumpTarget_dumpable() {
+ // GIVEN a variety of registered dumpables and buffers
+ dumpManager.registerCriticalDumpable("dumpable1", dumpable1)
+ dumpManager.registerCriticalDumpable("dumpable2", dumpable2)
+ dumpManager.registerCriticalDumpable("dumpable3", dumpable3)
+ dumpManager.registerBuffer("buffer1", buffer1)
+ dumpManager.registerBuffer("buffer2", buffer2)
+
+ // WHEN a dumpable is dumped explicitly
+ val args = arrayOf<String>()
+ dumpManager.dumpTarget("dumpable2", pw, arrayOf(), tailLength = 0)
+
+ // THEN only the requested one has their dump() method called
+ verify(dumpable1, never())
+ .dump(any(PrintWriter::class.java), any(Array<String>::class.java))
+ verify(dumpable2).dump(pw, args)
+ verify(dumpable3, never())
+ .dump(any(PrintWriter::class.java), any(Array<String>::class.java))
+ verify(buffer1, never()).dump(any(PrintWriter::class.java), anyInt())
+ verify(buffer2, never()).dump(any(PrintWriter::class.java), anyInt())
+ }
+
+ @Test
+ fun testDumpTarget_buffer() {
+ // GIVEN a variety of registered dumpables and buffers
+ dumpManager.registerCriticalDumpable("dumpable1", dumpable1)
+ dumpManager.registerCriticalDumpable("dumpable2", dumpable2)
+ dumpManager.registerCriticalDumpable("dumpable3", dumpable3)
+ dumpManager.registerBuffer("buffer1", buffer1)
+ dumpManager.registerBuffer("buffer2", buffer2)
+
+ // WHEN a buffer is dumped explicitly
+ dumpManager.dumpTarget("buffer1", pw, arrayOf(), tailLength = 14)
+
+ // THEN only the requested one has their dump() method called
+ verify(dumpable1, never())
+ .dump(any(PrintWriter::class.java), any(Array<String>::class.java))
+ verify(dumpable2, never())
+ .dump(any(PrintWriter::class.java), any(Array<String>::class.java))
+ verify(dumpable2, never())
+ .dump(any(PrintWriter::class.java), any(Array<String>::class.java))
+ verify(buffer1).dump(pw, tailLength = 14)
+ verify(buffer2, never()).dump(any(PrintWriter::class.java), anyInt())
+ }
+
+ @Test
+ fun testDumpableMatchingIsBasedOnEndOfTag() {
+ // GIVEN a dumpable registered to the manager
+ dumpManager.registerCriticalDumpable("com.android.foo.bar.dumpable1", dumpable1)
+
+ // WHEN that module is dumped
+ val args = arrayOf<String>()
+ dumpManager.dumpTarget("dumpable1", pw, arrayOf(), tailLength = 14)
+
+ // THEN its dump() method is called
+ verify(dumpable1).dump(pw, args)
+ }
+
+ @Test
+ fun testDumpDumpables() {
+ // GIVEN a variety of registered dumpables and buffers
+ dumpManager.registerCriticalDumpable("dumpable1", dumpable1)
+ dumpManager.registerCriticalDumpable("dumpable2", dumpable2)
+ dumpManager.registerNormalDumpable("dumpable3", dumpable3)
+ dumpManager.registerBuffer("buffer1", buffer1)
+ dumpManager.registerBuffer("buffer2", buffer2)
+
+ // WHEN a dumpable dump is requested
+ val args = arrayOf<String>()
+ dumpManager.dumpDumpables(pw, args)
+
+ // THEN all dumpables are dumped (both critical and normal) (and no dumpables)
+ verify(dumpable1).dump(pw, args)
+ verify(dumpable2).dump(pw, args)
+ verify(dumpable3).dump(pw, args)
+ verify(buffer1, never()).dump(any(PrintWriter::class.java), anyInt())
+ verify(buffer2, never()).dump(any(PrintWriter::class.java), anyInt())
+ }
+
+ @Test
+ fun testDumpBuffers() {
+ // GIVEN a variety of registered dumpables and buffers
+ dumpManager.registerCriticalDumpable("dumpable1", dumpable1)
+ dumpManager.registerCriticalDumpable("dumpable2", dumpable2)
+ dumpManager.registerNormalDumpable("dumpable3", dumpable3)
+ dumpManager.registerBuffer("buffer1", buffer1)
+ dumpManager.registerBuffer("buffer2", buffer2)
+
+ // WHEN a buffer dump is requested
+ dumpManager.dumpBuffers(pw, tailLength = 1)
+
+ // THEN all buffers are dumped (and no dumpables)
+ verify(dumpable1, never())
+ .dump(any(PrintWriter::class.java), any(Array<String>::class.java))
+ verify(dumpable2, never())
+ .dump(any(PrintWriter::class.java), any(Array<String>::class.java))
+ verify(dumpable3, never())
+ .dump(any(PrintWriter::class.java), any(Array<String>::class.java))
+ verify(buffer1).dump(pw, tailLength = 1)
+ verify(buffer2).dump(pw, tailLength = 1)
+ }
+
+ @Test
+ fun testCriticalDump() {
+ // GIVEN a variety of registered dumpables and buffers
+ dumpManager.registerCriticalDumpable("dumpable1", dumpable1)
+ dumpManager.registerCriticalDumpable("dumpable2", dumpable2)
+ dumpManager.registerNormalDumpable("dumpable3", dumpable3)
+ dumpManager.registerBuffer("buffer1", buffer1)
+ dumpManager.registerBuffer("buffer2", buffer2)
+
+ // WHEN a critical dump is requested
+ val args = arrayOf<String>()
+ dumpManager.dumpCritical(pw, args)
+
+ // THEN only critical modules are dumped (and no buffers)
+ verify(dumpable1).dump(pw, args)
+ verify(dumpable2).dump(pw, args)
+ verify(dumpable3, never())
+ .dump(any(PrintWriter::class.java), any(Array<String>::class.java))
+ verify(buffer1, never()).dump(any(PrintWriter::class.java), anyInt())
+ verify(buffer2, never()).dump(any(PrintWriter::class.java), anyInt())
+ }
+
+ @Test
+ fun testNormalDump() {
+ // GIVEN a variety of registered dumpables and buffers
+ dumpManager.registerCriticalDumpable("dumpable1", dumpable1)
+ dumpManager.registerCriticalDumpable("dumpable2", dumpable2)
+ dumpManager.registerNormalDumpable("dumpable3", dumpable3)
+ dumpManager.registerBuffer("buffer1", buffer1)
+ dumpManager.registerBuffer("buffer2", buffer2)
+
+ // WHEN a normal dump is requested
+ val args = arrayOf<String>()
+ dumpManager.dumpNormal(pw, args, tailLength = 2)
+
+ // THEN the normal module and all buffers are dumped
+ verify(dumpable1, never())
+ .dump(any(PrintWriter::class.java), any(Array<String>::class.java))
+ verify(dumpable2, never())
+ .dump(any(PrintWriter::class.java), any(Array<String>::class.java))
+ verify(dumpable3).dump(pw, args)
+ verify(buffer1).dump(pw, tailLength = 2)
+ verify(buffer2).dump(pw, tailLength = 2)
+ }
+
+ @Test
+ fun testUnregister() {
+ // GIVEN a variety of registered dumpables and buffers
+ dumpManager.registerCriticalDumpable("dumpable1", dumpable1)
+ dumpManager.registerCriticalDumpable("dumpable2", dumpable2)
+ dumpManager.registerNormalDumpable("dumpable3", dumpable3)
+
+ dumpManager.unregisterDumpable("dumpable2")
+ dumpManager.unregisterDumpable("dumpable3")
+
+ // WHEN a dumpables dump is requested
+ val args = arrayOf<String>()
+ dumpManager.dumpDumpables(pw, args)
+
+ // THEN the unregistered dumpables (both normal and critical) are not dumped
+ verify(dumpable1).dump(pw, args)
+ verify(dumpable2, never())
+ .dump(any(PrintWriter::class.java), any(Array<String>::class.java))
+ verify(dumpable3, never())
+ .dump(any(PrintWriter::class.java), any(Array<String>::class.java))
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardQuickAffordanceProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardQuickAffordanceProviderTest.kt
index 5e27a500125b..cedde58746d2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardQuickAffordanceProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardQuickAffordanceProviderTest.kt
@@ -115,6 +115,7 @@ class KeyguardQuickAffordanceProviderTest : SysuiTestCase() {
secureSettings = FakeSettings(),
selectionsManager = selectionManager,
),
+ dumpManager = mock(),
)
underTest.interactor =
KeyguardQuickAffordanceInteractor(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigParameterizedStateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigParameterizedStateTest.kt
index c94cec6e313a..322014a61a73 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigParameterizedStateTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigParameterizedStateTest.kt
@@ -24,8 +24,9 @@ import com.android.systemui.controls.controller.ControlsController
import com.android.systemui.controls.dagger.ControlsComponent
import com.android.systemui.controls.management.ControlsListingController
import com.android.systemui.util.mockito.mock
+import com.android.systemui.util.mockito.whenever
import com.google.common.truth.Truth.assertThat
-import java.util.Optional
+import java.util.*
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
@@ -40,7 +41,6 @@ import org.mockito.ArgumentCaptor
import org.mockito.Captor
import org.mockito.Mock
import org.mockito.Mockito.verify
-import org.mockito.Mockito.`when` as whenever
import org.mockito.MockitoAnnotations
@SmallTest
@@ -93,6 +93,14 @@ class HomeControlsKeyguardQuickAffordanceConfigParameterizedStateTest : SysuiTes
whenever(component.getControlsController()).thenReturn(Optional.of(controlsController))
whenever(component.getControlsListingController())
.thenReturn(Optional.of(controlsListingController))
+ whenever(controlsListingController.getCurrentServices())
+ .thenReturn(
+ if (hasServiceInfos) {
+ listOf(mock(), mock())
+ } else {
+ emptyList()
+ }
+ )
whenever(component.canShowWhileLockedSetting)
.thenReturn(MutableStateFlow(canShowWhileLocked))
whenever(component.getVisibility())
@@ -144,6 +152,17 @@ class HomeControlsKeyguardQuickAffordanceConfigParameterizedStateTest : SysuiTes
KeyguardQuickAffordanceConfig.LockScreenState.Hidden::class.java
}
)
+ assertThat(underTest.getPickerScreenState())
+ .isInstanceOf(
+ when {
+ !isFeatureEnabled ->
+ KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice::class
+ .java
+ hasServiceInfos && hasFavorites ->
+ KeyguardQuickAffordanceConfig.PickerScreenState.Default::class.java
+ else -> KeyguardQuickAffordanceConfig.PickerScreenState.Disabled::class.java
+ }
+ )
job.cancel()
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfigTest.kt
index 2bd8e9aabab3..6255980601ac 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfigTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfigTest.kt
@@ -24,17 +24,18 @@ import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanc
import com.android.systemui.qrcodescanner.controller.QRCodeScannerController
import com.android.systemui.util.mockito.argumentCaptor
import com.android.systemui.util.mockito.mock
+import com.android.systemui.util.mockito.whenever
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.test.runBlockingTest
+import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
import org.mockito.Mock
import org.mockito.Mockito.verify
-import org.mockito.Mockito.`when` as whenever
import org.mockito.MockitoAnnotations
@SmallTest
@@ -134,6 +135,33 @@ class QrCodeScannerKeyguardQuickAffordanceConfigTest : SysuiTestCase() {
)
}
+ @Test
+ fun `getPickerScreenState - enabled if configured on device - can open camera`() = runTest {
+ whenever(controller.isAvailableOnDevice).thenReturn(true)
+ whenever(controller.isAbleToOpenCameraApp).thenReturn(true)
+
+ assertThat(underTest.getPickerScreenState())
+ .isEqualTo(KeyguardQuickAffordanceConfig.PickerScreenState.Default)
+ }
+
+ @Test
+ fun `getPickerScreenState - disabled if configured on device - cannot open camera`() = runTest {
+ whenever(controller.isAvailableOnDevice).thenReturn(true)
+ whenever(controller.isAbleToOpenCameraApp).thenReturn(false)
+
+ assertThat(underTest.getPickerScreenState())
+ .isInstanceOf(KeyguardQuickAffordanceConfig.PickerScreenState.Disabled::class.java)
+ }
+
+ @Test
+ fun `getPickerScreenState - unavailable if not configured on device`() = runTest {
+ whenever(controller.isAvailableOnDevice).thenReturn(false)
+ whenever(controller.isAbleToOpenCameraApp).thenReturn(true)
+
+ assertThat(underTest.getPickerScreenState())
+ .isEqualTo(KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice)
+ }
+
private fun assertVisibleState(latest: KeyguardQuickAffordanceConfig.LockScreenState?) {
assertThat(latest)
.isInstanceOf(KeyguardQuickAffordanceConfig.LockScreenState.Visible::class.java)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfigTest.kt
index 5178154bdeee..d875dd94da3e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfigTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfigTest.kt
@@ -33,9 +33,11 @@ import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.whenever
import com.android.systemui.wallet.controller.QuickAccessWalletController
import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.test.runBlockingTest
+import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -44,6 +46,7 @@ import org.mockito.Mock
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
+@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@RunWith(JUnit4::class)
class QuickAccessWalletKeyguardQuickAffordanceConfigTest : SysuiTestCase() {
@@ -59,7 +62,7 @@ class QuickAccessWalletKeyguardQuickAffordanceConfigTest : SysuiTestCase() {
underTest =
QuickAccessWalletKeyguardQuickAffordanceConfig(
- mock(),
+ context,
walletController,
activityStarter,
)
@@ -151,6 +154,44 @@ class QuickAccessWalletKeyguardQuickAffordanceConfigTest : SysuiTestCase() {
)
}
+ @Test
+ fun `getPickerScreenState - default`() = runTest {
+ setUpState()
+
+ assertThat(underTest.getPickerScreenState())
+ .isEqualTo(KeyguardQuickAffordanceConfig.PickerScreenState.Default)
+ }
+
+ @Test
+ fun `getPickerScreenState - unavailable`() = runTest {
+ setUpState(
+ isWalletEnabled = false,
+ )
+
+ assertThat(underTest.getPickerScreenState())
+ .isEqualTo(KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice)
+ }
+
+ @Test
+ fun `getPickerScreenState - disabled when there is no icon`() = runTest {
+ setUpState(
+ hasWalletIcon = false,
+ )
+
+ assertThat(underTest.getPickerScreenState())
+ .isInstanceOf(KeyguardQuickAffordanceConfig.PickerScreenState.Disabled::class.java)
+ }
+
+ @Test
+ fun `getPickerScreenState - disabled when there is no card`() = runTest {
+ setUpState(
+ hasSelectedCard = false,
+ )
+
+ assertThat(underTest.getPickerScreenState())
+ .isInstanceOf(KeyguardQuickAffordanceConfig.PickerScreenState.Disabled::class.java)
+ }
+
private fun setUpState(
isWalletEnabled: Boolean = true,
isWalletQuerySuccessful: Boolean = true,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt
index d8a360567a07..5c75417c3473 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt
@@ -91,6 +91,7 @@ class KeyguardQuickAffordanceRepositoryTest : SysuiTestCase() {
selectionsManager = selectionManager,
),
configs = setOf(config1, config2),
+ dumpManager = mock(),
)
}
@@ -133,23 +134,24 @@ class KeyguardQuickAffordanceRepositoryTest : SysuiTestCase() {
}
@Test
- fun getAffordancePickerRepresentations() {
- assertThat(underTest.getAffordancePickerRepresentations())
- .isEqualTo(
- listOf(
- KeyguardQuickAffordancePickerRepresentation(
- id = config1.key,
- name = config1.pickerName,
- iconResourceId = config1.pickerIconResourceId,
- ),
- KeyguardQuickAffordancePickerRepresentation(
- id = config2.key,
- name = config2.pickerName,
- iconResourceId = config2.pickerIconResourceId,
- ),
+ fun getAffordancePickerRepresentations() =
+ runBlocking(IMMEDIATE) {
+ assertThat(underTest.getAffordancePickerRepresentations())
+ .isEqualTo(
+ listOf(
+ KeyguardQuickAffordancePickerRepresentation(
+ id = config1.key,
+ name = config1.pickerName,
+ iconResourceId = config1.pickerIconResourceId,
+ ),
+ KeyguardQuickAffordancePickerRepresentation(
+ id = config2.key,
+ name = config2.pickerName,
+ iconResourceId = config2.pickerIconResourceId,
+ ),
+ )
)
- )
- }
+ }
@Test
fun getSlotPickerRepresentations() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorParameterizedTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorParameterizedTest.kt
index 1e1d3f19d83c..c2650ec455d8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorParameterizedTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorParameterizedTest.kt
@@ -266,6 +266,7 @@ class KeyguardQuickAffordanceInteractorParameterizedTest : SysuiTestCase() {
selectionsManager = selectionManager,
),
configs = setOf(homeControls, quickAccessWallet, qrCodeScanner),
+ dumpManager = mock(),
)
underTest =
KeyguardQuickAffordanceInteractor(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt
index 4850ea5ffed2..b79030602368 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt
@@ -127,6 +127,7 @@ class KeyguardQuickAffordanceInteractorTest : SysuiTestCase() {
selectionsManager = selectionManager,
),
configs = setOf(homeControls, quickAccessWallet, qrCodeScanner),
+ dumpManager = mock(),
)
featureFlags =
FakeFeatureFlags().apply {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractorTest.kt
index 559f183717df..a6fc13bcb011 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractorTest.kt
@@ -19,6 +19,7 @@ package com.android.systemui.keyguard.domain.interactor
import android.os.Looper
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper.RunWithLooper
+import android.view.View
import androidx.test.filters.SmallTest
import com.android.keyguard.KeyguardSecurityModel
import com.android.keyguard.KeyguardUpdateMonitor
@@ -106,6 +107,7 @@ class PrimaryBouncerInteractorTest : SysuiTestCase() {
verify(repository).setPrimaryVisible(true)
verify(repository).setPrimaryShow(any(KeyguardBouncerModel::class.java))
verify(repository).setPrimaryShowingSoon(false)
+ verify(mPrimaryBouncerCallbackInteractor).dispatchVisibilityChanged(View.VISIBLE)
}
@Test
@@ -129,6 +131,7 @@ class PrimaryBouncerInteractorTest : SysuiTestCase() {
verify(repository).setPrimaryVisible(false)
verify(repository).setPrimaryHide(true)
verify(repository).setPrimaryShow(null)
+ verify(mPrimaryBouncerCallbackInteractor).dispatchVisibilityChanged(View.INVISIBLE)
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt
index ecc63ecc879d..8b166bd89426 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt
@@ -155,6 +155,7 @@ class KeyguardBottomAreaViewModelTest : SysuiTestCase() {
quickAccessWalletAffordanceConfig,
qrCodeScannerAffordanceConfig,
),
+ dumpManager = mock(),
)
underTest =
KeyguardBottomAreaViewModel(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qrcodescanner/controller/QRCodeScannerControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qrcodescanner/controller/QRCodeScannerControllerTest.java
index 346d1e60fcf9..65210d63e5c5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qrcodescanner/controller/QRCodeScannerControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qrcodescanner/controller/QRCodeScannerControllerTest.java
@@ -31,7 +31,6 @@ import static org.mockito.Mockito.when;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
-import android.content.res.Resources;
import android.os.UserHandle;
import android.provider.DeviceConfig;
import android.provider.Settings;
@@ -133,7 +132,7 @@ public class QRCodeScannerControllerTest extends SysuiTestCase {
/* enableOnLockScreen */ true);
verifyActivityDetails(null);
assertThat(mController.isEnabledForLockScreenButton()).isFalse();
- assertThat(mController.isEnabledForQuickSettings()).isFalse();
+ assertThat(mController.isAbleToOpenCameraApp()).isFalse();
}
@Test
@@ -152,7 +151,7 @@ public class QRCodeScannerControllerTest extends SysuiTestCase {
/* enableOnLockScreen */ true);
verifyActivityDetails("abc/.def");
assertThat(mController.isEnabledForLockScreenButton()).isTrue();
- assertThat(mController.isEnabledForQuickSettings()).isTrue();
+ assertThat(mController.isAbleToOpenCameraApp()).isTrue();
}
@Test
@@ -162,7 +161,7 @@ public class QRCodeScannerControllerTest extends SysuiTestCase {
/* enableOnLockScreen */ true);
verifyActivityDetails("abc/.def");
assertThat(mController.isEnabledForLockScreenButton()).isTrue();
- assertThat(mController.isEnabledForQuickSettings()).isTrue();
+ assertThat(mController.isAbleToOpenCameraApp()).isTrue();
}
@Test
@@ -172,7 +171,7 @@ public class QRCodeScannerControllerTest extends SysuiTestCase {
/* enableOnLockScreen */ true);
verifyActivityDetails("abc/.def");
assertThat(mController.isEnabledForLockScreenButton()).isTrue();
- assertThat(mController.isEnabledForQuickSettings()).isTrue();
+ assertThat(mController.isAbleToOpenCameraApp()).isTrue();
}
@Test
@@ -182,7 +181,7 @@ public class QRCodeScannerControllerTest extends SysuiTestCase {
/* enableOnLockScreen */ true);
verifyActivityDetails("abc/abc.def");
assertThat(mController.isEnabledForLockScreenButton()).isTrue();
- assertThat(mController.isEnabledForQuickSettings()).isTrue();
+ assertThat(mController.isAbleToOpenCameraApp()).isTrue();
}
@Test
@@ -192,7 +191,7 @@ public class QRCodeScannerControllerTest extends SysuiTestCase {
/* enableOnLockScreen */ true);
verifyActivityDetails(null);
assertThat(mController.isEnabledForLockScreenButton()).isFalse();
- assertThat(mController.isEnabledForQuickSettings()).isFalse();
+ assertThat(mController.isAbleToOpenCameraApp()).isFalse();
}
@Test
@@ -202,21 +201,21 @@ public class QRCodeScannerControllerTest extends SysuiTestCase {
/* enableOnLockScreen */ true);
verifyActivityDetails("abc/.def");
assertThat(mController.isEnabledForLockScreenButton()).isTrue();
- assertThat(mController.isEnabledForQuickSettings()).isTrue();
+ assertThat(mController.isAbleToOpenCameraApp()).isTrue();
mProxyFake.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
SystemUiDeviceConfigFlags.DEFAULT_QR_CODE_SCANNER,
"def/.ijk", false);
verifyActivityDetails("def/.ijk");
assertThat(mController.isEnabledForLockScreenButton()).isTrue();
- assertThat(mController.isEnabledForQuickSettings()).isTrue();
+ assertThat(mController.isAbleToOpenCameraApp()).isTrue();
mProxyFake.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
SystemUiDeviceConfigFlags.DEFAULT_QR_CODE_SCANNER,
null, false);
verifyActivityDetails("abc/.def");
assertThat(mController.isEnabledForLockScreenButton()).isTrue();
- assertThat(mController.isEnabledForQuickSettings()).isTrue();
+ assertThat(mController.isAbleToOpenCameraApp()).isTrue();
// Once from setup + twice from this function
verify(mCallback, times(3)).onQRCodeScannerActivityChanged();
@@ -229,7 +228,7 @@ public class QRCodeScannerControllerTest extends SysuiTestCase {
/* enableOnLockScreen */ true);
verifyActivityDetails(null);
assertThat(mController.isEnabledForLockScreenButton()).isFalse();
- assertThat(mController.isEnabledForQuickSettings()).isFalse();
+ assertThat(mController.isAbleToOpenCameraApp()).isFalse();
mProxyFake.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
SystemUiDeviceConfigFlags.DEFAULT_QR_CODE_SCANNER,
@@ -237,14 +236,14 @@ public class QRCodeScannerControllerTest extends SysuiTestCase {
verifyActivityDetails("def/.ijk");
assertThat(mController.isEnabledForLockScreenButton()).isTrue();
- assertThat(mController.isEnabledForQuickSettings()).isTrue();
+ assertThat(mController.isAbleToOpenCameraApp()).isTrue();
mProxyFake.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
SystemUiDeviceConfigFlags.DEFAULT_QR_CODE_SCANNER,
null, false);
verifyActivityDetails(null);
assertThat(mController.isEnabledForLockScreenButton()).isFalse();
- assertThat(mController.isEnabledForQuickSettings()).isFalse();
+ assertThat(mController.isAbleToOpenCameraApp()).isFalse();
verify(mCallback, times(2)).onQRCodeScannerActivityChanged();
}
@@ -296,19 +295,19 @@ public class QRCodeScannerControllerTest extends SysuiTestCase {
/* enableOnLockScreen */ true);
verifyActivityDetails("abc/.def");
assertThat(mController.isEnabledForLockScreenButton()).isTrue();
- assertThat(mController.isEnabledForQuickSettings()).isTrue();
+ assertThat(mController.isAbleToOpenCameraApp()).isTrue();
mSecureSettings.putStringForUser(LOCK_SCREEN_SHOW_QR_CODE_SCANNER, "0",
UserHandle.USER_CURRENT);
verifyActivityDetails("abc/.def");
assertThat(mController.isEnabledForLockScreenButton()).isFalse();
- assertThat(mController.isEnabledForQuickSettings()).isTrue();
+ assertThat(mController.isAbleToOpenCameraApp()).isTrue();
mSecureSettings.putStringForUser(LOCK_SCREEN_SHOW_QR_CODE_SCANNER, "1",
UserHandle.USER_CURRENT);
verifyActivityDetails("abc/.def");
assertThat(mController.isEnabledForLockScreenButton()).isTrue();
- assertThat(mController.isEnabledForQuickSettings()).isTrue();
+ assertThat(mController.isAbleToOpenCameraApp()).isTrue();
// Once from setup + twice from this function
verify(mCallback, times(3)).onQRCodeScannerPreferenceChanged();
}
@@ -320,13 +319,13 @@ public class QRCodeScannerControllerTest extends SysuiTestCase {
/* enableOnLockScreen */ true);
verifyActivityDetails("abc/.def");
assertThat(mController.isEnabledForLockScreenButton()).isTrue();
- assertThat(mController.isEnabledForQuickSettings()).isTrue();
+ assertThat(mController.isAbleToOpenCameraApp()).isTrue();
mController.unregisterQRCodeScannerChangeObservers(DEFAULT_QR_CODE_SCANNER_CHANGE,
QR_CODE_SCANNER_PREFERENCE_CHANGE);
verifyActivityDetails(null);
assertThat(mController.isEnabledForLockScreenButton()).isFalse();
- assertThat(mController.isEnabledForQuickSettings()).isFalse();
+ assertThat(mController.isAbleToOpenCameraApp()).isFalse();
// Unregister once again and make sure it affects the next register event
mController.unregisterQRCodeScannerChangeObservers(DEFAULT_QR_CODE_SCANNER_CHANGE,
@@ -335,7 +334,7 @@ public class QRCodeScannerControllerTest extends SysuiTestCase {
QR_CODE_SCANNER_PREFERENCE_CHANGE);
verifyActivityDetails("abc/.def");
assertThat(mController.isEnabledForLockScreenButton()).isTrue();
- assertThat(mController.isEnabledForQuickSettings()).isTrue();
+ assertThat(mController.isAbleToOpenCameraApp()).isTrue();
}
@Test
@@ -345,7 +344,7 @@ public class QRCodeScannerControllerTest extends SysuiTestCase {
/* enableOnLockScreen */ false);
assertThat(mController.getIntent()).isNotNull();
assertThat(mController.isEnabledForLockScreenButton()).isFalse();
- assertThat(mController.isEnabledForQuickSettings()).isTrue();
+ assertThat(mController.isAbleToOpenCameraApp()).isTrue();
assertThat(getSettingsQRCodeDefaultComponent()).isNull();
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
index 72e022ed7bbb..aedb9354e6db 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
@@ -19,6 +19,7 @@ import static com.android.systemui.statusbar.StatusBarState.SHADE;
import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
@@ -450,6 +451,23 @@ public class QSFragmentTest extends SysuiBaseFragmentTest {
verify(mQSPanelController).setListening(true, true);
}
+ @Test
+ public void testUpdateQSBounds_setMediaClipCorrectly() {
+ QSFragment fragment = resumeAndGetFragment();
+ disableSplitShade();
+
+ Rect mediaHostClip = new Rect();
+ when(mQSPanelController.getPaddingBottom()).thenReturn(50);
+ setLocationOnScreen(mQSPanelScrollView, 25);
+ when(mQSPanelScrollView.getMeasuredHeight()).thenReturn(200);
+ when(mQSMediaHost.getCurrentClipping()).thenReturn(mediaHostClip);
+
+ fragment.updateQsBounds();
+
+ assertEquals(25, mediaHostClip.top);
+ assertEquals(175, mediaHostClip.bottom);
+ }
+
@Override
protected Fragment instantiate(Context context, String className, Bundle arguments) {
MockitoAnnotations.initMocks(this);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt
index f7b9438e6535..e0b3125fd62a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt
@@ -40,6 +40,7 @@ import com.android.systemui.controls.dagger.ControlsComponent
import com.android.systemui.controls.management.ControlsListingController
import com.android.systemui.controls.ui.ControlsActivity
import com.android.systemui.controls.ui.ControlsUiController
+import com.android.systemui.controls.ui.SelectedItem
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.qs.QSHost
@@ -118,8 +119,9 @@ class DeviceControlsTileTest : SysuiTestCase() {
`when`(qsHost.context).thenReturn(spiedContext)
`when`(qsHost.uiEventLogger).thenReturn(uiEventLogger)
`when`(controlsComponent.isEnabled()).thenReturn(true)
- `when`(controlsController.getPreferredStructure())
- .thenReturn(StructureInfo(ComponentName("pkg", "cls"), "structure", listOf()))
+ `when`(controlsController.getPreferredSelection())
+ .thenReturn(SelectedItem.StructureItem(
+ StructureInfo(ComponentName("pkg", "cls"), "structure", listOf())))
secureSettings.putInt(Settings.Secure.LOCKSCREEN_SHOW_CONTROLS, 1)
setupControlsComponent()
@@ -226,12 +228,12 @@ class DeviceControlsTileTest : SysuiTestCase() {
capture(listingCallbackCaptor)
)
`when`(controlsComponent.getVisibility()).thenReturn(ControlsComponent.Visibility.AVAILABLE)
- `when`(controlsController.getPreferredStructure()).thenReturn(
- StructureInfo(
+ `when`(controlsController.getPreferredSelection()).thenReturn(
+ SelectedItem.StructureItem(StructureInfo(
ComponentName("pkg", "cls"),
"structure",
listOf(ControlInfo("id", "title", "subtitle", 1))
- )
+ ))
)
listingCallbackCaptor.value.onServicesUpdated(listOf(serviceInfo))
@@ -247,8 +249,9 @@ class DeviceControlsTileTest : SysuiTestCase() {
capture(listingCallbackCaptor)
)
`when`(controlsComponent.getVisibility()).thenReturn(ControlsComponent.Visibility.AVAILABLE)
- `when`(controlsController.getPreferredStructure())
- .thenReturn(StructureInfo(ComponentName("pkg", "cls"), "structure", listOf()))
+ `when`(controlsController.getPreferredSelection())
+ .thenReturn(SelectedItem.StructureItem(
+ StructureInfo(ComponentName("pkg", "cls"), "structure", listOf())))
listingCallbackCaptor.value.onServicesUpdated(listOf(serviceInfo))
testableLooper.processAllMessages()
@@ -257,6 +260,22 @@ class DeviceControlsTileTest : SysuiTestCase() {
}
@Test
+ fun testStateActiveIfPreferredIsPanel() {
+ verify(controlsListingController).observe(
+ any(LifecycleOwner::class.java),
+ capture(listingCallbackCaptor)
+ )
+ `when`(controlsComponent.getVisibility()).thenReturn(ControlsComponent.Visibility.AVAILABLE)
+ `when`(controlsController.getPreferredSelection())
+ .thenReturn(SelectedItem.PanelItem("appName", ComponentName("pkg", "cls")))
+
+ listingCallbackCaptor.value.onServicesUpdated(listOf(serviceInfo))
+ testableLooper.processAllMessages()
+
+ assertThat(tile.state.state).isEqualTo(Tile.STATE_ACTIVE)
+ }
+
+ @Test
fun testStateInactiveIfLocked() {
verify(controlsListingController).observe(
any(LifecycleOwner::class.java),
@@ -303,12 +322,12 @@ class DeviceControlsTileTest : SysuiTestCase() {
)
`when`(controlsComponent.getVisibility()).thenReturn(ControlsComponent.Visibility.AVAILABLE)
`when`(controlsUiController.resolveActivity()).thenReturn(ControlsActivity::class.java)
- `when`(controlsController.getPreferredStructure()).thenReturn(
- StructureInfo(
- ComponentName("pkg", "cls"),
- "structure",
- listOf(ControlInfo("id", "title", "subtitle", 1))
- )
+ `when`(controlsController.getPreferredSelection()).thenReturn(
+ SelectedItem.StructureItem(StructureInfo(
+ ComponentName("pkg", "cls"),
+ "structure",
+ listOf(ControlInfo("id", "title", "subtitle", 1))
+ ))
)
listingCallbackCaptor.value.onServicesUpdated(listOf(serviceInfo))
@@ -334,12 +353,12 @@ class DeviceControlsTileTest : SysuiTestCase() {
`when`(controlsComponent.getVisibility())
.thenReturn(ControlsComponent.Visibility.AVAILABLE_AFTER_UNLOCK)
`when`(controlsUiController.resolveActivity()).thenReturn(ControlsActivity::class.java)
- `when`(controlsController.getPreferredStructure()).thenReturn(
- StructureInfo(
+ `when`(controlsController.getPreferredSelection()).thenReturn(
+ SelectedItem.StructureItem(StructureInfo(
ComponentName("pkg", "cls"),
"structure",
listOf(ControlInfo("id", "title", "subtitle", 1))
- )
+ ))
)
listingCallbackCaptor.value.onServicesUpdated(listOf(serviceInfo))
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QRCodeScannerTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QRCodeScannerTileTest.java
index cac90a14096e..a1be2f3ac8de 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QRCodeScannerTileTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QRCodeScannerTileTest.java
@@ -18,6 +18,7 @@ package com.android.systemui.qs.tiles;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertNull;
import static org.mockito.Mockito.when;
@@ -108,17 +109,20 @@ public class QRCodeScannerTileTest extends SysuiTestCase {
@Test
public void testQRCodeTileUnavailable() {
- when(mController.isEnabledForQuickSettings()).thenReturn(false);
+ when(mController.isAbleToOpenCameraApp()).thenReturn(false);
QSTile.State state = new QSTile.State();
mTile.handleUpdateState(state, null);
assertEquals(state.state, Tile.STATE_UNAVAILABLE);
+ assertEquals(state.secondaryLabel.toString(),
+ mContext.getString(R.string.qr_code_scanner_updating_secondary_label));
}
@Test
public void testQRCodeTileAvailable() {
- when(mController.isEnabledForQuickSettings()).thenReturn(true);
+ when(mController.isAbleToOpenCameraApp()).thenReturn(true);
QSTile.State state = new QSTile.State();
mTile.handleUpdateState(state, null);
assertEquals(state.state, Tile.STATE_INACTIVE);
+ assertNull(state.secondaryLabel);
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogControllerTest.java
index 48a53bc659b3..62404cbc54b4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogControllerTest.java
@@ -31,6 +31,7 @@ import static org.mockito.Mockito.when;
import android.animation.Animator;
import android.content.Intent;
+import android.content.res.Resources;
import android.graphics.PixelFormat;
import android.graphics.drawable.Drawable;
import android.net.ConnectivityManager;
@@ -42,6 +43,7 @@ import android.telephony.ServiceState;
import android.telephony.SignalStrength;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyDisplayInfo;
import android.telephony.TelephonyManager;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
@@ -87,6 +89,7 @@ import org.mockito.quality.Strictness;
import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
@SmallTest
@RunWith(AndroidTestingRunner.class)
@@ -815,15 +818,34 @@ public class InternetDialogControllerTest extends SysuiTestCase {
@Test
public void getMobileNetworkSummary() {
mFlags.set(Flags.QS_SECONDARY_DATA_SUB_INFO, true);
+ Resources res1 = mock(Resources.class);
+ doReturn("EDGE").when(res1).getString(anyInt());
+ Resources res2 = mock(Resources.class);
+ doReturn("LTE").when(res2).getString(anyInt());
+ when(SubscriptionManager.getResourcesForSubId(any(), eq(SUB_ID))).thenReturn(res1);
+ when(SubscriptionManager.getResourcesForSubId(any(), eq(SUB_ID2))).thenReturn(res2);
+
InternetDialogController spyController = spy(mInternetDialogController);
+ Map<Integer, TelephonyDisplayInfo> mSubIdTelephonyDisplayInfoMap =
+ spyController.mSubIdTelephonyDisplayInfoMap;
+ TelephonyDisplayInfo info1 = new TelephonyDisplayInfo(TelephonyManager.NETWORK_TYPE_EDGE,
+ TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE);
+ TelephonyDisplayInfo info2 = new TelephonyDisplayInfo(TelephonyManager.NETWORK_TYPE_LTE,
+ TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE);
+
+ mSubIdTelephonyDisplayInfoMap.put(SUB_ID, info1);
+ mSubIdTelephonyDisplayInfoMap.put(SUB_ID2, info2);
+
doReturn(SUB_ID2).when(spyController).getActiveAutoSwitchNonDdsSubId();
doReturn(true).when(spyController).isMobileDataEnabled();
doReturn(true).when(spyController).activeNetworkIsCellular();
String dds = spyController.getMobileNetworkSummary(SUB_ID);
String nonDds = spyController.getMobileNetworkSummary(SUB_ID2);
+ String ddsNetworkType = dds.split("/")[1];
+ String nonDdsNetworkType = nonDds.split("/")[1];
assertThat(dds).contains(mContext.getString(R.string.mobile_data_poor_connection));
- assertThat(dds).isNotEqualTo(nonDds);
+ assertThat(ddsNetworkType).isNotEqualTo(nonDdsNetworkType);
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/CombinedShadeHeaderConstraintsTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/CombinedShadeHeaderConstraintsTest.kt
index 2a3d32e07b91..9c36be62e46e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/CombinedShadeHeaderConstraintsTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/CombinedShadeHeaderConstraintsTest.kt
@@ -344,26 +344,6 @@ class CombinedShadeHeaderConstraintsTest : SysuiTestCase() {
}
@Test
- fun testCheckViewsDontChangeSizeBetweenAnimationConstraints() {
- val views = mapOf(
- R.id.clock to "clock",
- R.id.date to "date",
- R.id.statusIcons to "icons",
- R.id.privacy_container to "privacy",
- R.id.carrier_group to "carriers",
- R.id.batteryRemainingIcon to "battery",
- )
- views.forEach { (id, name) ->
- assertWithMessage("$name changes height")
- .that(qqsConstraint.getConstraint(id).layout.mHeight)
- .isEqualTo(qsConstraint.getConstraint(id).layout.mHeight)
- assertWithMessage("$name changes width")
- .that(qqsConstraint.getConstraint(id).layout.mWidth)
- .isEqualTo(qsConstraint.getConstraint(id).layout.mWidth)
- }
- }
-
- @Test
fun testEmptyCutoutDateIconsAreConstrainedWidth() {
CombinedShadeHeadersConstraintManagerImpl.emptyCutoutConstraints()()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java
index 08933fc4e042..e1346ead3e7f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java
@@ -523,4 +523,12 @@ public class CommandQueueTest extends SysuiTestCase {
waitForIdleSync();
verify(mCallbacks).setNavigationBarLumaSamplingEnabled(eq(1), eq(true));
}
+
+ @Test
+ public void testShowRearDisplayDialog() {
+ final int currentBaseState = 1;
+ mCommandQueue.showRearDisplayDialog(currentBaseState);
+ waitForIdleSync();
+ verify(mCallbacks).showRearDisplayDialog(eq(currentBaseState));
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt
index 77b1e3740907..beaf3009125b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt
@@ -131,7 +131,9 @@ class NotificationShadeDepthControllerTest : SysuiTestCase() {
@Test
fun setupListeners() {
- verify(dumpManager).registerDumpable(anyString(), eq(notificationShadeDepthController))
+ verify(dumpManager).registerCriticalDumpable(
+ anyString(), eq(notificationShadeDepthController)
+ )
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java
index 7246116ccc9b..868ae2bec19f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java
@@ -41,6 +41,7 @@ import android.testing.TestableResources;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.util.LatencyTracker;
import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.keyguard.logging.BiometricUnlockLogger;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.biometrics.AuthController;
import com.android.systemui.dump.DumpManager;
@@ -75,6 +76,8 @@ public class BiometricsUnlockControllerTest extends SysuiTestCase {
@Mock
private KeyguardUpdateMonitor mUpdateMonitor;
@Mock
+ private KeyguardUpdateMonitor.StrongAuthTracker mStrongAuthTracker;
+ @Mock
private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
@Mock
private NotificationShadeWindowController mNotificationShadeWindowController;
@@ -112,6 +115,8 @@ public class BiometricsUnlockControllerTest extends SysuiTestCase {
private ScreenOffAnimationController mScreenOffAnimationController;
@Mock
private VibratorHelper mVibratorHelper;
+ @Mock
+ private BiometricUnlockLogger mLogger;
private BiometricUnlockController mBiometricUnlockController;
@Before
@@ -131,12 +136,13 @@ public class BiometricsUnlockControllerTest extends SysuiTestCase {
mKeyguardViewMediator, mScrimController,
mNotificationShadeWindowController, mKeyguardStateController, mHandler,
mUpdateMonitor, res.getResources(), mKeyguardBypassController,
- mMetricsLogger, mDumpManager, mPowerManager,
+ mMetricsLogger, mDumpManager, mPowerManager, mLogger,
mNotificationMediaManager, mWakefulnessLifecycle, mScreenLifecycle,
mAuthController, mStatusBarStateController,
mSessionTracker, mLatencyTracker, mScreenOffAnimationController, mVibratorHelper);
mBiometricUnlockController.setKeyguardViewController(mStatusBarKeyguardViewManager);
mBiometricUnlockController.addBiometricModeListener(mBiometricModeListener);
+ when(mUpdateMonitor.getStrongAuthTracker()).thenReturn(mStrongAuthTracker);
}
@Test
@@ -276,6 +282,7 @@ public class BiometricsUnlockControllerTest extends SysuiTestCase {
@Test
public void onBiometricAuthenticated_whenFace_andBypass_encrypted_showPrimaryBouncer() {
reset(mUpdateMonitor);
+ when(mUpdateMonitor.getStrongAuthTracker()).thenReturn(mStrongAuthTracker);
when(mKeyguardBypassController.getBypassEnabled()).thenReturn(true);
mBiometricUnlockController.setKeyguardViewController(mStatusBarKeyguardViewManager);
@@ -306,6 +313,7 @@ public class BiometricsUnlockControllerTest extends SysuiTestCase {
@Test
public void onBiometricAuthenticated_whenFace_noBypass_encrypted_doNothing() {
reset(mUpdateMonitor);
+ when(mUpdateMonitor.getStrongAuthTracker()).thenReturn(mStrongAuthTracker);
mBiometricUnlockController.setKeyguardViewController(mStatusBarKeyguardViewManager);
when(mUpdateMonitor.isUnlockingWithBiometricAllowed(anyBoolean())).thenReturn(false);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/UserInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/UserInteractorTest.kt
index 47efcd90cb0d..50d239d25607 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/UserInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/UserInteractorTest.kt
@@ -113,6 +113,7 @@ class UserInteractorTest : SysuiTestCase() {
)
featureFlags = FakeFeatureFlags()
+ featureFlags.set(Flags.FULL_SCREEN_USER_SWITCHER, false)
userRepository = FakeUserRepository()
keyguardRepository = FakeKeyguardRepository()
telephonyRepository = FakeTelephonyRepository()
@@ -311,6 +312,32 @@ class UserInteractorTest : SysuiTestCase() {
}
@Test
+ fun `actions - device unlocked - full screen`() =
+ runBlocking(IMMEDIATE) {
+ featureFlags.set(Flags.FULL_SCREEN_USER_SWITCHER, true)
+ val userInfos = createUserInfos(count = 2, includeGuest = false)
+
+ userRepository.setUserInfos(userInfos)
+ userRepository.setSelectedUserInfo(userInfos[0])
+ userRepository.setSettings(UserSwitcherSettingsModel(isUserSwitcherEnabled = true))
+ keyguardRepository.setKeyguardShowing(false)
+ var value: List<UserActionModel>? = null
+ val job = underTest.actions.onEach { value = it }.launchIn(this)
+
+ assertThat(value)
+ .isEqualTo(
+ listOf(
+ UserActionModel.ADD_USER,
+ UserActionModel.ADD_SUPERVISED_USER,
+ UserActionModel.ENTER_GUEST_MODE,
+ UserActionModel.NAVIGATE_TO_USER_MANAGEMENT,
+ )
+ )
+
+ job.cancel()
+ }
+
+ @Test
fun `actions - device unlocked user not primary - empty list`() =
runBlocking(IMMEDIATE) {
val userInfos = createUserInfos(count = 2, includeGuest = false)
@@ -373,21 +400,29 @@ class UserInteractorTest : SysuiTestCase() {
}
@Test
- fun `actions - device locked - only guest action and manage user is shown`() =
+ fun `actions - device locked add from lockscreen set - full list - full screen`() =
runBlocking(IMMEDIATE) {
+ featureFlags.set(Flags.FULL_SCREEN_USER_SWITCHER, true)
val userInfos = createUserInfos(count = 2, includeGuest = false)
userRepository.setUserInfos(userInfos)
userRepository.setSelectedUserInfo(userInfos[0])
- userRepository.setSettings(UserSwitcherSettingsModel(isUserSwitcherEnabled = true))
- keyguardRepository.setKeyguardShowing(true)
+ userRepository.setSettings(
+ UserSwitcherSettingsModel(
+ isUserSwitcherEnabled = true,
+ isAddUsersFromLockscreen = true,
+ )
+ )
+ keyguardRepository.setKeyguardShowing(false)
var value: List<UserActionModel>? = null
val job = underTest.actions.onEach { value = it }.launchIn(this)
assertThat(value)
.isEqualTo(
listOf(
+ UserActionModel.ADD_USER,
+ UserActionModel.ADD_SUPERVISED_USER,
UserActionModel.ENTER_GUEST_MODE,
- UserActionModel.NAVIGATE_TO_USER_MANAGEMENT
+ UserActionModel.NAVIGATE_TO_USER_MANAGEMENT,
)
)
@@ -395,6 +430,22 @@ class UserInteractorTest : SysuiTestCase() {
}
@Test
+ fun `actions - device locked - only manage user is shown`() =
+ runBlocking(IMMEDIATE) {
+ val userInfos = createUserInfos(count = 2, includeGuest = false)
+ userRepository.setUserInfos(userInfos)
+ userRepository.setSelectedUserInfo(userInfos[0])
+ userRepository.setSettings(UserSwitcherSettingsModel(isUserSwitcherEnabled = true))
+ keyguardRepository.setKeyguardShowing(true)
+ var value: List<UserActionModel>? = null
+ val job = underTest.actions.onEach { value = it }.launchIn(this)
+
+ assertThat(value).isEqualTo(listOf(UserActionModel.NAVIGATE_TO_USER_MANAGEMENT))
+
+ job.cancel()
+ }
+
+ @Test
fun `executeAction - add user - dialog shown`() =
runBlocking(IMMEDIATE) {
val userInfos = createUserInfos(count = 2, includeGuest = false)
@@ -665,6 +716,33 @@ class UserInteractorTest : SysuiTestCase() {
}
@Test
+ fun userRecordsFullScreen() =
+ runBlocking(IMMEDIATE) {
+ featureFlags.set(Flags.FULL_SCREEN_USER_SWITCHER, true)
+ val userInfos = createUserInfos(count = 3, includeGuest = false)
+ userRepository.setSettings(UserSwitcherSettingsModel(isUserSwitcherEnabled = true))
+ userRepository.setUserInfos(userInfos)
+ userRepository.setSelectedUserInfo(userInfos[0])
+ keyguardRepository.setKeyguardShowing(false)
+
+ testCoroutineScope.advanceUntilIdle()
+
+ assertRecords(
+ records = underTest.userRecords.value,
+ userIds = listOf(0, 1, 2),
+ selectedUserIndex = 0,
+ includeGuest = false,
+ expectedActions =
+ listOf(
+ UserActionModel.ADD_USER,
+ UserActionModel.ADD_SUPERVISED_USER,
+ UserActionModel.ENTER_GUEST_MODE,
+ UserActionModel.NAVIGATE_TO_USER_MANAGEMENT,
+ ),
+ )
+ }
+
+ @Test
fun selectedUserRecord() =
runBlocking(IMMEDIATE) {
val userInfos = createUserInfos(count = 3, includeGuest = true)
@@ -728,8 +806,6 @@ class UserInteractorTest : SysuiTestCase() {
@Test
fun `show user switcher - full screen disabled - shows dialog switcher`() =
runBlocking(IMMEDIATE) {
- featureFlags.set(Flags.FULL_SCREEN_USER_SWITCHER, false)
-
var dialogRequest: ShowDialogRequestModel? = null
val expandable = mock<Expandable>()
underTest.showUserSwitcher(context, expandable)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/StatusBarUserChipViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/StatusBarUserChipViewModelTest.kt
index 795ff17f92a4..108fa6246e9c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/StatusBarUserChipViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/StatusBarUserChipViewModelTest.kt
@@ -30,6 +30,7 @@ import com.android.systemui.GuestResumeSessionReceiver
import com.android.systemui.SysuiTestCase
import com.android.systemui.common.shared.model.Text
import com.android.systemui.flags.FakeFeatureFlags
+import com.android.systemui.flags.Flags
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.plugins.ActivityStarter
@@ -241,7 +242,8 @@ class StatusBarUserChipViewModelTest : SysuiTestCase() {
KeyguardInteractor(
repository = keyguardRepository,
),
- featureFlags = featureFlags,
+ featureFlags =
+ FakeFeatureFlags().apply { set(Flags.FULL_SCREEN_USER_SWITCHER, false) },
manager = manager,
applicationScope = testScope.backgroundScope,
telephonyInteractor =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModelTest.kt
index 1730b75c20d4..4b6bdac46a3d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModelTest.kt
@@ -28,6 +28,7 @@ import com.android.systemui.GuestResumeSessionReceiver
import com.android.systemui.SysuiTestCase
import com.android.systemui.common.shared.model.Text
import com.android.systemui.flags.FakeFeatureFlags
+import com.android.systemui.flags.Flags
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.plugins.ActivityStarter
@@ -148,7 +149,10 @@ class UserSwitcherViewModelTest : SysuiTestCase() {
KeyguardInteractor(
repository = keyguardRepository,
),
- featureFlags = FakeFeatureFlags(),
+ featureFlags =
+ FakeFeatureFlags().apply {
+ set(Flags.FULL_SCREEN_USER_SWITCHER, false)
+ },
manager = manager,
applicationScope = injectedScope,
telephonyInteractor =
diff --git a/services/backup/java/com/android/server/backup/fullbackup/FullBackupEngine.java b/services/backup/java/com/android/server/backup/fullbackup/FullBackupEngine.java
index 1e1ca95d69db..379ae52018c4 100644
--- a/services/backup/java/com/android/server/backup/fullbackup/FullBackupEngine.java
+++ b/services/backup/java/com/android/server/backup/fullbackup/FullBackupEngine.java
@@ -23,11 +23,13 @@ import static com.android.server.backup.UserBackupManagerService.BACKUP_MANIFEST
import static com.android.server.backup.UserBackupManagerService.BACKUP_METADATA_FILENAME;
import static com.android.server.backup.UserBackupManagerService.SHARED_BACKUP_AGENT_PACKAGE;
+import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.ApplicationThreadConstants;
import android.app.IBackupAgent;
import android.app.backup.BackupTransport;
import android.app.backup.FullBackupDataOutput;
+import android.app.backup.IBackupManagerMonitor;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
@@ -42,6 +44,7 @@ import com.android.server.backup.OperationStorage.OpType;
import com.android.server.backup.UserBackupManagerService;
import com.android.server.backup.remote.RemoteCall;
import com.android.server.backup.utils.BackupEligibilityRules;
+import com.android.server.backup.utils.BackupManagerMonitorUtils;
import com.android.server.backup.utils.FullBackupUtils;
import java.io.File;
@@ -60,12 +63,13 @@ public class FullBackupEngine {
private BackupRestoreTask mTimeoutMonitor;
private IBackupAgent mAgent;
private boolean mIncludeApks;
- private PackageInfo mPkg;
+ private final PackageInfo mPkg;
private final long mQuota;
private final int mOpToken;
private final int mTransportFlags;
private final BackupAgentTimeoutParameters mAgentTimeoutParameters;
private final BackupEligibilityRules mBackupEligibilityRules;
+ @Nullable private final IBackupManagerMonitor mMonitor;
class FullBackupRunner implements Runnable {
private final @UserIdInt int mUserId;
@@ -193,7 +197,8 @@ public class FullBackupEngine {
long quota,
int opToken,
int transportFlags,
- BackupEligibilityRules backupEligibilityRules) {
+ BackupEligibilityRules backupEligibilityRules,
+ IBackupManagerMonitor monitor) {
this.backupManagerService = backupManagerService;
mOutput = output;
mPreflightHook = preflightHook;
@@ -208,6 +213,7 @@ public class FullBackupEngine {
backupManagerService.getAgentTimeoutParameters(),
"Timeout parameters cannot be null");
mBackupEligibilityRules = backupEligibilityRules;
+ mMonitor = monitor;
}
public int preflightCheck() throws RemoteException {
@@ -260,6 +266,8 @@ public class FullBackupEngine {
}
result = BackupTransport.TRANSPORT_OK;
}
+
+ BackupManagerMonitorUtils.monitorAgentLoggingResults(mMonitor, mPkg, mAgent);
} catch (IOException e) {
Slog.e(TAG, "Error backing up " + mPkg.packageName + ": " + e.getMessage());
result = BackupTransport.AGENT_ERROR;
diff --git a/services/backup/java/com/android/server/backup/fullbackup/PerformAdbBackupTask.java b/services/backup/java/com/android/server/backup/fullbackup/PerformAdbBackupTask.java
index ec58e17148b3..cba1e299ff58 100644
--- a/services/backup/java/com/android/server/backup/fullbackup/PerformAdbBackupTask.java
+++ b/services/backup/java/com/android/server/backup/fullbackup/PerformAdbBackupTask.java
@@ -420,7 +420,8 @@ public class PerformAdbBackupTask extends FullBackupTask implements BackupRestor
Long.MAX_VALUE,
mCurrentOpToken,
/*transportFlags=*/ 0,
- mBackupEligibilityRules);
+ mBackupEligibilityRules,
+ /* monitor= */ null);
sendOnBackupPackage(isSharedStorage ? "Shared storage" : pkg.packageName);
// Don't need to check preflight result as there is no preflight hook.
diff --git a/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java b/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java
index f0492a8b58b4..78df304286b4 100644
--- a/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java
+++ b/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java
@@ -882,7 +882,8 @@ public class PerformFullTransportBackupTask extends FullBackupTask implements Ba
mQuota,
mCurrentOpToken,
mTransportFlags,
- mBackupEligibilityRules);
+ mBackupEligibilityRules,
+ mMonitor);
try {
try {
if (!mIsCancelled) {
diff --git a/services/backup/java/com/android/server/backup/keyvalue/KeyValueBackupTask.java b/services/backup/java/com/android/server/backup/keyvalue/KeyValueBackupTask.java
index 16aa4ebb0656..fd9c834540e7 100644
--- a/services/backup/java/com/android/server/backup/keyvalue/KeyValueBackupTask.java
+++ b/services/backup/java/com/android/server/backup/keyvalue/KeyValueBackupTask.java
@@ -68,6 +68,7 @@ import com.android.server.backup.transport.BackupTransportClient;
import com.android.server.backup.transport.TransportConnection;
import com.android.server.backup.transport.TransportNotAvailableException;
import com.android.server.backup.utils.BackupEligibilityRules;
+import com.android.server.backup.utils.BackupManagerMonitorUtils;
import libcore.io.IoUtils;
@@ -697,6 +698,8 @@ public class KeyValueBackupTask implements BackupRestoreTask, Runnable {
try {
extractAgentData(mCurrentPackage);
+ BackupManagerMonitorUtils.monitorAgentLoggingResults(
+ mReporter.getMonitor(), mCurrentPackage, mAgent);
int status = sendDataToTransport(mCurrentPackage);
cleanUpAgentForTransportStatus(status);
} catch (AgentException | TaskException e) {
diff --git a/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
index b48367db17c2..9f89339a9149 100644
--- a/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
+++ b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
@@ -405,6 +405,12 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask {
BackupTransportClient transport =
mTransportConnection.connectOrThrow("PerformUnifiedRestoreTask.startRestore()");
+ // If the requester of the restore has not passed in a monitor, we ask the transport
+ // for one.
+ if (mMonitor == null) {
+ mMonitor = transport.getBackupManagerMonitor();
+ }
+
mStatus = transport.startRestore(mToken, packages);
if (mStatus != BackupTransport.TRANSPORT_OK) {
Slog.e(TAG, "Transport error " + mStatus + "; no restore possible");
@@ -885,6 +891,10 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask {
OpType.RESTORE_WAIT);
mAgent.doRestoreFinished(mEphemeralOpToken,
backupManagerService.getBackupManagerBinder());
+
+ // Ask the agent for logs after doRestoreFinished() to allow it to finalize its logs.
+ BackupManagerMonitorUtils.monitorAgentLoggingResults(mMonitor, mCurrentPackage, mAgent);
+
// If we get this far, the callback or timeout will schedule the
// next restore state, so we're done
} catch (Exception e) {
diff --git a/services/backup/java/com/android/server/backup/utils/BackupManagerMonitorUtils.java b/services/backup/java/com/android/server/backup/utils/BackupManagerMonitorUtils.java
index 6f083760980d..8eda5b9a3219 100644
--- a/services/backup/java/com/android/server/backup/utils/BackupManagerMonitorUtils.java
+++ b/services/backup/java/com/android/server/backup/utils/BackupManagerMonitorUtils.java
@@ -16,24 +16,43 @@
package com.android.server.backup.utils;
+import static android.app.backup.BackupManagerMonitor.EXTRA_LOG_AGENT_LOGGING_RESULTS;
import static android.app.backup.BackupManagerMonitor.EXTRA_LOG_EVENT_PACKAGE_NAME;
+import static android.app.backup.BackupManagerMonitor.LOG_EVENT_CATEGORY_AGENT;
+import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_AGENT_LOGGING_RESULTS;
import static com.android.server.backup.BackupManagerService.DEBUG;
import static com.android.server.backup.BackupManagerService.TAG;
import android.annotation.Nullable;
+import android.app.IBackupAgent;
import android.app.backup.BackupManagerMonitor;
+import android.app.backup.BackupRestoreEventLogger;
import android.app.backup.IBackupManagerMonitor;
import android.content.pm.PackageInfo;
import android.os.Bundle;
import android.os.RemoteException;
import android.util.Slog;
+import com.android.internal.infra.AndroidFuture;
+
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
/**
* Utility methods to communicate with BackupManagerMonitor.
*/
public class BackupManagerMonitorUtils {
/**
+ * Timeout for how long we wait before we give up on getting logs from a {@link IBackupAgent}.
+ * We expect this to be very fast since the agent immediately returns whatever logs have been
+ * accumulated. The timeout adds a bit more security and ensures we don't hang the B&R waiting
+ * for non-essential logs.
+ */
+ private static final int AGENT_LOGGER_RESULTS_TIMEOUT_MILLIS = 500;
+
+ /**
* Notifies monitor about the event.
*
* Calls {@link IBackupManagerMonitor#onEvent(Bundle)} with a bundle representing current event.
@@ -80,6 +99,48 @@ public class BackupManagerMonitorUtils {
}
/**
+ * Extracts logging results from the provided {@code agent} and notifies the {@code monitor}
+ * about them.
+ *
+ * <p>Note that this method does two separate binder calls (one to the agent and one to the
+ * monitor).
+ *
+ * @param monitor - implementation of {@link IBackupManagerMonitor} to notify.
+ * @param pkg - package the {@code agent} belongs to.
+ * @param agent - the {@link IBackupAgent} to retrieve logs from.
+ * @return {@code null} if the monitor is null. {@code monitor} if we fail to retrieve the logs
+ * from the {@code agent}. Otherwise, the result of {@link
+ * #monitorEvent(IBackupManagerMonitor, int, PackageInfo, int, Bundle)}.
+ */
+ public static IBackupManagerMonitor monitorAgentLoggingResults(
+ @Nullable IBackupManagerMonitor monitor, PackageInfo pkg, IBackupAgent agent) {
+ if (monitor == null) {
+ return null;
+ }
+
+ try {
+ AndroidFuture<List<BackupRestoreEventLogger.DataTypeResult>> resultsFuture =
+ new AndroidFuture<>();
+ agent.getLoggerResults(resultsFuture);
+ Bundle loggerResultsBundle = new Bundle();
+ loggerResultsBundle.putParcelableList(
+ EXTRA_LOG_AGENT_LOGGING_RESULTS,
+ resultsFuture.get(AGENT_LOGGER_RESULTS_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS));
+ return BackupManagerMonitorUtils.monitorEvent(
+ monitor,
+ LOG_EVENT_ID_AGENT_LOGGING_RESULTS,
+ pkg,
+ LOG_EVENT_CATEGORY_AGENT,
+ loggerResultsBundle);
+ } catch (TimeoutException e) {
+ Slog.w(TAG, "Timeout while waiting to retrieve logging results from agent", e);
+ } catch (Exception e) {
+ Slog.w(TAG, "Failed to retrieve logging results from agent", e);
+ }
+ return monitor;
+ }
+
+ /**
* Adds given key-value pair in the bundle and returns the bundle. If bundle was null it will
* be created.
*
diff --git a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
index fbde9e0ea5d1..d83c80fcca6a 100644
--- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
+++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
@@ -480,6 +480,13 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
+ "this virtual device");
}
}
+
+ if (screenSize.x <= 0 || screenSize.y <= 0) {
+ throw new IllegalArgumentException(
+ "Cannot create a virtual touchscreen, screen dimensions must be positive. Got: "
+ + screenSize);
+ }
+
final long token = Binder.clearCallingIdentity();
try {
mInputController.createTouchscreen(deviceName, vendorId, productId,
diff --git a/services/core/java/com/android/server/VcnManagementService.java b/services/core/java/com/android/server/VcnManagementService.java
index 76cac934fdfe..61f7f301a838 100644
--- a/services/core/java/com/android/server/VcnManagementService.java
+++ b/services/core/java/com/android/server/VcnManagementService.java
@@ -18,8 +18,11 @@ package com.android.server;
import static android.Manifest.permission.DUMP;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
+import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
import static android.net.NetworkCapabilities.TRANSPORT_TEST;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
+import static android.net.vcn.VcnGatewayConnectionConfig.ALLOWED_CAPABILITIES;
+import static android.net.vcn.VcnManager.VCN_RESTRICTED_TRANSPORTS_INT_ARRAY_KEY;
import static android.net.vcn.VcnManager.VCN_STATUS_CODE_ACTIVE;
import static android.net.vcn.VcnManager.VCN_STATUS_CODE_INACTIVE;
import static android.net.vcn.VcnManager.VCN_STATUS_CODE_NOT_CONFIGURED;
@@ -53,6 +56,7 @@ import android.net.vcn.VcnManager.VcnStatusCode;
import android.net.vcn.VcnUnderlyingNetworkPolicy;
import android.net.wifi.WifiInfo;
import android.os.Binder;
+import android.os.Build;
import android.os.Environment;
import android.os.Handler;
import android.os.HandlerThread;
@@ -68,6 +72,7 @@ import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.util.ArrayMap;
+import android.util.ArraySet;
import android.util.LocalLog;
import android.util.Log;
import android.util.Slog;
@@ -83,6 +88,7 @@ import com.android.server.vcn.Vcn;
import com.android.server.vcn.VcnContext;
import com.android.server.vcn.VcnNetworkProvider;
import com.android.server.vcn.util.PersistableBundleUtils;
+import com.android.server.vcn.util.PersistableBundleUtils.PersistableBundleWrapper;
import java.io.File;
import java.io.FileDescriptor;
@@ -159,6 +165,9 @@ public class VcnManagementService extends IVcnManagementService.Stub {
private static final long DUMP_TIMEOUT_MILLIS = TimeUnit.SECONDS.toMillis(5);
private static final int LOCAL_LOG_LINE_COUNT = 512;
+ private static final Set<Integer> RESTRICTED_TRANSPORTS_DEFAULT =
+ Collections.singleton(TRANSPORT_WIFI);
+
// Public for use in all other VCN classes
@NonNull public static final LocalLog LOCAL_LOG = new LocalLog(LOCAL_LOG_LINE_COUNT);
@@ -361,6 +370,34 @@ public class VcnManagementService extends IVcnManagementService.Stub {
public LocationPermissionChecker newLocationPermissionChecker(@NonNull Context context) {
return new LocationPermissionChecker(context);
}
+
+ /** Gets the transports that need to be marked as restricted by the VCN */
+ public Set<Integer> getRestrictedTransports(
+ ParcelUuid subGrp, TelephonySubscriptionSnapshot lastSnapshot) {
+ if (!Build.IS_ENG && !Build.IS_USERDEBUG) {
+ return RESTRICTED_TRANSPORTS_DEFAULT;
+ }
+
+ final PersistableBundleWrapper carrierConfig =
+ lastSnapshot.getCarrierConfigForSubGrp(subGrp);
+ if (carrierConfig == null) {
+ return RESTRICTED_TRANSPORTS_DEFAULT;
+ }
+
+ final int[] defaultValue =
+ RESTRICTED_TRANSPORTS_DEFAULT.stream().mapToInt(i -> i).toArray();
+ final int[] restrictedTransportsArray =
+ carrierConfig.getIntArray(
+ VCN_RESTRICTED_TRANSPORTS_INT_ARRAY_KEY,
+ defaultValue);
+
+ // Convert to a boxed set
+ final Set<Integer> restrictedTransports = new ArraySet<>();
+ for (int transport : restrictedTransportsArray) {
+ restrictedTransports.add(transport);
+ }
+ return restrictedTransports;
+ }
}
/** Notifies the VcnManagementService that external dependencies can be set up. */
@@ -517,6 +554,7 @@ public class VcnManagementService extends IVcnManagementService.Stub {
}
}
+ boolean needNotifyAllPolicyListeners = false;
// Schedule teardown of any VCN instances that have lost carrier privileges (after a
// delay)
for (Entry<ParcelUuid, Vcn> entry : mVcns.entrySet()) {
@@ -564,6 +602,10 @@ public class VcnManagementService extends IVcnManagementService.Stub {
} else {
// If this VCN's status has not changed, update it with the new snapshot
entry.getValue().updateSubscriptionSnapshot(mLastSnapshot);
+ needNotifyAllPolicyListeners |=
+ !Objects.equals(
+ oldSnapshot.getCarrierConfigForSubGrp(subGrp),
+ mLastSnapshot.getCarrierConfigForSubGrp(subGrp));
}
}
@@ -573,6 +615,10 @@ public class VcnManagementService extends IVcnManagementService.Stub {
getSubGroupToSubIdMappings(mLastSnapshot);
if (!currSubGrpMappings.equals(oldSubGrpMappings)) {
garbageCollectAndWriteVcnConfigsLocked();
+ needNotifyAllPolicyListeners = true;
+ }
+
+ if (needNotifyAllPolicyListeners) {
notifyAllPolicyListenersLocked();
}
}
@@ -917,6 +963,14 @@ public class VcnManagementService extends IVcnManagementService.Stub {
});
}
+ @VisibleForTesting(visibility = Visibility.PRIVATE)
+ void addVcnUnderlyingNetworkPolicyListenerForTest(
+ @NonNull IVcnUnderlyingNetworkPolicyListener listener) {
+ synchronized (mLock) {
+ addVcnUnderlyingNetworkPolicyListener(listener);
+ }
+ }
+
/** Removes the provided listener from receiving VcnUnderlyingNetworkPolicy updates. */
@GuardedBy("mLock")
@Override
@@ -1000,7 +1054,7 @@ public class VcnManagementService extends IVcnManagementService.Stub {
final ParcelUuid subGrp = getSubGroupForNetworkCapabilities(ncCopy);
boolean isVcnManagedNetwork = false;
- boolean isRestrictedCarrierWifi = false;
+ boolean isRestricted = false;
synchronized (mLock) {
final Vcn vcn = mVcns.get(subGrp);
if (vcn != null) {
@@ -1008,9 +1062,19 @@ public class VcnManagementService extends IVcnManagementService.Stub {
isVcnManagedNetwork = true;
}
- if (ncCopy.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
- // Carrier WiFi always restricted if VCN exists (even in safe mode).
- isRestrictedCarrierWifi = true;
+ final Set<Integer> restrictedTransports =
+ mDeps.getRestrictedTransports(subGrp, mLastSnapshot);
+ for (int restrictedTransport : restrictedTransports) {
+ if (ncCopy.hasTransport(restrictedTransport)) {
+ if (restrictedTransport == TRANSPORT_CELLULAR) {
+ // Only make a cell network as restricted when the VCN is in
+ // active mode.
+ isRestricted |= (vcn.getStatus() == VCN_STATUS_CODE_ACTIVE);
+ } else {
+ isRestricted = true;
+ break;
+ }
+ }
}
}
}
@@ -1024,14 +1088,16 @@ public class VcnManagementService extends IVcnManagementService.Stub {
ncBuilder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
}
- if (isRestrictedCarrierWifi) {
+ if (isRestricted) {
ncBuilder.removeCapability(
NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
}
final NetworkCapabilities result = ncBuilder.build();
final VcnUnderlyingNetworkPolicy policy = new VcnUnderlyingNetworkPolicy(
- mTrackingNetworkCallback.requiresRestartForCarrierWifi(result), result);
+ mTrackingNetworkCallback
+ .requiresRestartForImmutableCapabilityChanges(result),
+ result);
logVdbg("getUnderlyingNetworkPolicy() called for caps: " + networkCapabilities
+ "; and lp: " + linkProperties + "; result = " + policy);
@@ -1296,15 +1362,38 @@ public class VcnManagementService extends IVcnManagementService.Stub {
}
}
- private boolean requiresRestartForCarrierWifi(NetworkCapabilities caps) {
- if (!caps.hasTransport(TRANSPORT_WIFI) || caps.getSubscriptionIds() == null) {
+ private Set<Integer> getNonTestTransportTypes(NetworkCapabilities caps) {
+ final Set<Integer> transportTypes = new ArraySet<>();
+ for (int t : caps.getTransportTypes()) {
+ transportTypes.add(t);
+ }
+ return transportTypes;
+ }
+
+ private boolean hasSameTransportsAndCapabilities(
+ NetworkCapabilities caps, NetworkCapabilities capsOther) {
+ if (!Objects.equals(
+ getNonTestTransportTypes(caps), getNonTestTransportTypes(capsOther))) {
+ return false;
+ }
+
+ for (int capability : ALLOWED_CAPABILITIES) {
+ if (caps.hasCapability(capability) != capsOther.hasCapability(capability)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private boolean requiresRestartForImmutableCapabilityChanges(NetworkCapabilities caps) {
+ if (caps.getSubscriptionIds() == null) {
return false;
}
synchronized (mCaps) {
for (NetworkCapabilities existing : mCaps.values()) {
- if (existing.hasTransport(TRANSPORT_WIFI)
- && caps.getSubscriptionIds().equals(existing.getSubscriptionIds())) {
+ if (caps.getSubscriptionIds().equals(existing.getSubscriptionIds())
+ && hasSameTransportsAndCapabilities(caps, existing)) {
// Restart if any immutable capabilities have changed
return existing.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)
!= caps.hasCapability(NET_CAPABILITY_NOT_RESTRICTED);
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index 74763174783c..a2755bec0bc0 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -1649,7 +1649,7 @@ public class AccountManagerService
final long identityToken = clearCallingIdentity();
try {
- return getAuthenticatorTypesInternal(userId);
+ return getAuthenticatorTypesInternal(userId, callingUid);
} finally {
restoreCallingIdentity(identityToken);
@@ -1659,19 +1659,19 @@ public class AccountManagerService
/**
* Should only be called inside of a clearCallingIdentity block.
*/
- private AuthenticatorDescription[] getAuthenticatorTypesInternal(int userId) {
+ private AuthenticatorDescription[] getAuthenticatorTypesInternal(int userId, int callingUid) {
mAuthenticatorCache.updateServices(userId);
Collection<AccountAuthenticatorCache.ServiceInfo<AuthenticatorDescription>>
authenticatorCollection = mAuthenticatorCache.getAllServices(userId);
- AuthenticatorDescription[] types =
- new AuthenticatorDescription[authenticatorCollection.size()];
- int i = 0;
+ final List<AuthenticatorDescription> types =
+ new ArrayList<>(authenticatorCollection.size());
for (AccountAuthenticatorCache.ServiceInfo<AuthenticatorDescription> authenticator
: authenticatorCollection) {
- types[i] = authenticator.type;
- i++;
+ if (canCallerAccessPackage(authenticator.type.packageName, callingUid, userId)) {
+ types.add(authenticator.type);
+ }
}
- return types;
+ return types.toArray(new AuthenticatorDescription[types.size()]);
}
private boolean isCrossUser(int callingUid, int userId) {
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 6bb3306bc894..1534e635f1b2 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -225,7 +225,9 @@ public final class ActiveServices {
private static final boolean DEBUG_DELAYED_SERVICE = DEBUG_SERVICE;
private static final boolean DEBUG_DELAYED_STARTS = DEBUG_DELAYED_SERVICE;
- private static final boolean LOG_SERVICE_START_STOP = false;
+ private static final boolean DEBUG_SHORT_SERVICE = DEBUG_SERVICE;
+
+ private static final boolean LOG_SERVICE_START_STOP = DEBUG_SERVICE;
// How long we wait for a service to finish executing.
static final int SERVICE_TIMEOUT = 20 * 1000 * Build.HW_TIMEOUT_MULTIPLIER;
@@ -729,6 +731,12 @@ public final class ActiveServices {
? res.permission : "private to package");
}
+
+ // TODO(short-service): This is inside startService() / startForegroundService().
+ // Consider if there's anything special we have to do if these are called on an already-
+ // running short-FGS... But given these APIs shouldn't change the FGS type, we likely
+ // don't need to do anything. (If they would change the FGS type, we'd have to stop
+ // the timeout)
ServiceRecord r = res.record;
setFgsRestrictionLocked(callingPackage, callingPid, callingUid, service, r, userId,
allowBackgroundActivityStarts, false /* isBindService */);
@@ -1291,7 +1299,8 @@ public final class ActiveServices {
}
service.callStart = false;
- bringDownServiceIfNeededLocked(service, false, false, enqueueOomAdj);
+ bringDownServiceIfNeededLocked(service, false, false, enqueueOomAdj,
+ "stopService");
} finally {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
@@ -1473,7 +1482,7 @@ public final class ActiveServices {
}
r.callStart = false;
final long origId = Binder.clearCallingIdentity();
- bringDownServiceIfNeededLocked(r, false, false, false);
+ bringDownServiceIfNeededLocked(r, false, false, false, "stopServiceToken");
Binder.restoreCallingIdentity(origId);
return true;
}
@@ -1801,15 +1810,23 @@ public final class ActiveServices {
r.app.getPid(), r.appInfo.uid, "startForeground");
}
+ // TODO(short-service): This part really should be above the if block,
+ // so we'll apply the same check for instant apps too.
int manifestType = r.serviceInfo.getForegroundServiceType();
// If passed in foreground service type is FOREGROUND_SERVICE_TYPE_MANIFEST,
// consider it is the same as manifest foreground service type.
if (foregroundServiceType == FOREGROUND_SERVICE_TYPE_MANIFEST) {
foregroundServiceType = manifestType;
}
+
// Check the passed in foreground service type flags is a subset of manifest
// foreground service type flags.
- if ((foregroundServiceType & manifestType) != foregroundServiceType) {
+ final String prop = "debug.skip_fgs_manifest_type_check";
+ if (((foregroundServiceType & manifestType) != foregroundServiceType)
+ // When building a test app on Studio, the SDK may not have all the
+ // FGS types yet. This debug flag will allow using FGS types that are
+ // not set in the manifest.
+ && !SystemProperties.getBoolean(prop, false)) {
throw new IllegalArgumentException("foregroundServiceType "
+ String.format("0x%08X", foregroundServiceType)
+ " is not a subset of foregroundServiceType attribute "
@@ -1866,6 +1883,16 @@ public final class ActiveServices {
int fgsTypeCheckCode = FGS_TYPE_POLICY_CHECK_UNKNOWN;
if (!ignoreForeground) {
+ // TODO(short-service): There's a known long-standing bug that allows
+ // a abound service to become "foreground" if setForeground() is called
+ // (without actually "starting" it).
+ // Unfortunately we can't just "fix" it because some apps are relying on it,
+ // but this will cause a problem to short-fgs, so we should disallow it if
+ // this happens and the type is SHORT_SERVICE.
+ //
+ // OTOH, if a valid short-service (which has to be "started"), happens to
+ // also be bound, then we still _will_ apply a timeout, because it still has
+ // to be stopped.
if (r.mStartForegroundCount == 0) {
/*
If the service was started with startService(), not
@@ -1898,6 +1925,28 @@ public final class ActiveServices {
}
}
} else if (r.mStartForegroundCount >= 1) {
+ // We get here if startForeground() is called multiple times
+ // on the same sarvice after it's created, regardless of whether
+ // stopForeground() has been called or not.
+
+ // TODO(short-service): Consider transitions:
+ // A. Short -> other types:
+ // Apply the BG restriction again. Don't just allow it.
+ // i.e. unless the app is in a situation where it's allowed to start
+ // a FGS, this transition shouldn't be allowed.
+ // ... But think about it more, there may be a case this should be
+ // allowed.
+ //
+ // If the transition is allowed, stop the timeout.
+ // If the transition is _not_ allowed... keep the timeout?
+ //
+ // B. Short -> Short:
+ // This should be the same as case A
+ // If this is allowed, the new timeout should start.
+ // C. Other -> short:
+ // This should always be allowed.
+ // A timeout should start.
+
// The second or later time startForeground() is called after service is
// started. Check for app state again.
setFgsRestrictionLocked(r.serviceInfo.packageName, r.app.getPid(),
@@ -1977,6 +2026,10 @@ public final class ActiveServices {
cancelForegroundNotificationLocked(r);
r.foregroundId = id;
}
+
+ // TODO(short-service): Stop the short service timeout, if the type is changing
+ // from short to non-short. (should we do it earlier?)
+
notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
r.foregroundNoti = notification;
r.foregroundServiceType = foregroundServiceType;
@@ -2048,6 +2101,9 @@ public final class ActiveServices {
getServiceMapLocked(r.userId).ensureNotStartingBackgroundLocked(r);
mAm.notifyPackageUse(r.serviceInfo.packageName,
PackageManager.NOTIFY_PACKAGE_USE_FOREGROUND_SERVICE);
+
+ // TODO(short-service): Start counting a timeout.
+
} else {
if (DEBUG_FOREGROUND_SERVICE) {
Slog.d(TAG, "Suppressing startForeground() for FAS " + r);
@@ -2081,6 +2137,8 @@ public final class ActiveServices {
decActiveForegroundAppLocked(smap, r);
}
+ // TODO(short-service): Stop the timeout. (any better place to do it?)
+
// Adjust notification handling before setting isForeground to false, because
// that state is relevant to the notification policy side.
// Leave the time-to-display as already set: re-entering foreground mode will
@@ -2121,6 +2179,10 @@ public final class ActiveServices {
? (int) (r.mFgsExitTime - r.mFgsEnterTime) : 0,
FGS_STOP_REASON_STOP_FOREGROUND,
FGS_TYPE_POLICY_CHECK_UNKNOWN);
+
+ // foregroundServiceType is used in logFGSStateChangeLocked(), so we can't clear it
+ // earlier.
+ r.foregroundServiceType = 0;
r.mFgsNotificationWasDeferred = false;
signalForegroundServiceObserversLocked(r);
resetFgsRestrictionLocked(r);
@@ -2408,7 +2470,9 @@ public final class ActiveServices {
final int uid = r.appInfo.uid;
// schedule the actual notification post
- long when = now + mAm.mConstants.mFgsNotificationDeferralInterval;
+ long when = now
+ + (r.isShortFgs() ? mAm.mConstants.mFgsNotificationDeferralIntervalForShort
+ : mAm.mConstants.mFgsNotificationDeferralInterval);
// If there are already deferred FGS notifications for this app,
// inherit that deferred-show timestamp
for (int i = 0; i < mPendingFgsNotifications.size(); i++) {
@@ -2427,7 +2491,9 @@ public final class ActiveServices {
}
if (mFgsDeferralRateLimited) {
- final long nextEligible = when + mAm.mConstants.mFgsNotificationDeferralExclusionTime;
+ final long nextEligible = when
+ + (r.isShortFgs() ? mAm.mConstants.mFgsNotificationDeferralExclusionTimeForShort
+ : mAm.mConstants.mFgsNotificationDeferralExclusionTime);
mFgsDeferralEligible.put(uid, nextEligible);
}
r.fgDisplayTime = when;
@@ -2791,14 +2857,19 @@ public final class ActiveServices {
private void updateServiceForegroundLocked(ProcessServiceRecord psr, boolean oomAdj) {
boolean anyForeground = false;
int fgServiceTypes = 0;
+ boolean hasTypeNone = false;
for (int i = psr.numberOfRunningServices() - 1; i >= 0; i--) {
ServiceRecord sr = psr.getRunningServiceAt(i);
if (sr.isForeground || sr.fgRequired) {
anyForeground = true;
fgServiceTypes |= sr.foregroundServiceType;
+ if (sr.foregroundServiceType == ServiceInfo.FOREGROUND_SERVICE_TYPE_NONE) {
+ hasTypeNone = true;
+ }
}
}
- mAm.updateProcessForegroundLocked(psr.mApp, anyForeground, fgServiceTypes, oomAdj);
+ mAm.updateProcessForegroundLocked(psr.mApp, anyForeground,
+ fgServiceTypes, hasTypeNone, oomAdj);
psr.setHasReportedForegroundServices(anyForeground);
}
@@ -4773,10 +4844,18 @@ public final class ActiveServices {
return false;
}
- private final void bringDownServiceIfNeededLocked(ServiceRecord r, boolean knowConn,
- boolean hasConn, boolean enqueueOomAdj) {
- //Slog.i(TAG, "Bring down service:");
- //r.dump(" ");
+ private void bringDownServiceIfNeededLocked(ServiceRecord r, boolean knowConn,
+ boolean hasConn, boolean enqueueOomAdj, String debugReason) {
+ if (DEBUG_SERVICE) {
+ Slog.i(TAG, "Bring down service for " + debugReason + " :" + r.toString());
+ }
+
+ // TODO(short-service): Hmm, when the app stops a short-fgs, we should stop the timeout
+ // here.
+ // However we have a couple if's here and if these conditions are met, we stop here
+ // without bringing down the service.
+ // We need to make sure this can't be used (somehow) to keep having a short-FGS running
+ // while having the timeout stopped.
if (isServiceNeededLocked(r, knowConn, hasConn)) {
return;
@@ -4844,6 +4923,8 @@ public final class ActiveServices {
// Check to see if the service had been started as foreground, but being
// brought down before actually showing a notification. That is not allowed.
+ // TODO(short-service): This is unlikely related to short-FGS, but I'm curious why it's
+ // not allowed. Look into it.
if (r.fgRequired) {
Slog.w(TAG_SERVICE, "Bringing down service while still waiting for start foreground: "
+ r);
@@ -4934,6 +5015,8 @@ public final class ActiveServices {
FGS_STOP_REASON_STOP_SERVICE,
FGS_TYPE_POLICY_CHECK_UNKNOWN);
mAm.updateForegroundServiceUsageStats(r.name, r.userId, false);
+
+ // TODO(short-service): Make sure we stop the timeout by here.
}
r.isForeground = false;
@@ -5161,7 +5244,8 @@ public final class ActiveServices {
}
}
}
- bringDownServiceIfNeededLocked(s, true, hasAutoCreate, enqueueOomAdj);
+ bringDownServiceIfNeededLocked(s, true, hasAutoCreate, enqueueOomAdj,
+ "removeConnection");
}
}
}
@@ -6028,7 +6112,7 @@ public final class ActiveServices {
TimeoutRecord timeoutRecord = TimeoutRecord.forServiceStartWithEndTime(annotation,
SystemClock.uptimeMillis());
- timeoutRecord.mLatencyTracker.waitingOnAMSLockEnded();
+ timeoutRecord.mLatencyTracker.waitingOnAMSLockStarted();
synchronized (mAm) {
timeoutRecord.mLatencyTracker.waitingOnAMSLockEnded();
if (!r.fgRequired || !r.fgWaiting || r.destroying) {
@@ -6988,7 +7072,7 @@ public final class ActiveServices {
final Integer allowedType = mAm.mProcessList.searchEachLruProcessesLOSP(false, app -> {
if (app.uid == callingUid) {
final ProcessStateRecord state = app.mState;
- if (state.isAllowedStartFgs()) {
+ if (state.isAllowedStartFgs()) { // Procstate <= BFGS?
return getReasonCodeFromProcState(state.getCurProcState());
} else {
final ActiveInstrumentation instr = app.getActiveInstrumentation();
diff --git a/services/core/java/com/android/server/am/ActivityManagerConstants.java b/services/core/java/com/android/server/am/ActivityManagerConstants.java
index 8b5b795b8ff5..046403d409af 100644
--- a/services/core/java/com/android/server/am/ActivityManagerConstants.java
+++ b/services/core/java/com/android/server/am/ActivityManagerConstants.java
@@ -958,6 +958,20 @@ final class ActivityManagerConstants extends ContentObserver {
/**
* If a "short service" doesn't finish within this after the timeout (
+ * {@link #KEY_SHORT_FGS_TIMEOUT_DURATION}), then we'll lower the procstate.
+ */
+ private static final String KEY_SHORT_FGS_PROC_STATE_EXTRA_WAIT_DURATION =
+ "short_fgs_proc_state_extra_wait_duration";
+
+ /** @see #KEY_SHORT_FGS_PROC_STATE_EXTRA_WAIT_DURATION */
+ static final long DEFAULT_SHORT_FGS_PROC_STATE_EXTRA_WAIT_DURATION = 5_000;
+
+ /** @see #KEY_SHORT_FGS_PROC_STATE_EXTRA_WAIT_DURATION */
+ public static volatile long mShortFgsProcStateExtraWaitDuration =
+ DEFAULT_SHORT_FGS_PROC_STATE_EXTRA_WAIT_DURATION;
+
+ /**
+ * If a "short service" doesn't finish within this after the timeout (
* {@link #KEY_SHORT_FGS_TIMEOUT_DURATION}), then we'll declare an ANR.
* i.e. if the timeout is 60 seconds, and this ANR extra duration is 5 seconds, then
* the app will be ANR'ed in 65 seconds after a short service starts and it's not stopped.
@@ -966,7 +980,7 @@ final class ActivityManagerConstants extends ContentObserver {
"short_fgs_anr_extra_wait_duration";
/** @see #KEY_SHORT_FGS_ANR_EXTRA_WAIT_DURATION */
- static final long DEFAULT_SHORT_FGS_ANR_EXTRA_WAIT_DURATION = 5_000;
+ static final long DEFAULT_SHORT_FGS_ANR_EXTRA_WAIT_DURATION = 10_000;
/** @see #KEY_SHORT_FGS_ANR_EXTRA_WAIT_DURATION */
public static volatile long mShortFgsAnrExtraWaitDuration =
@@ -1116,6 +1130,9 @@ final class ActivityManagerConstants extends ContentObserver {
case KEY_SHORT_FGS_TIMEOUT_DURATION:
updateShortFgsTimeoutDuration();
break;
+ case KEY_SHORT_FGS_PROC_STATE_EXTRA_WAIT_DURATION:
+ updateShortFgsProcStateExtraWaitDuration();
+ break;
case KEY_SHORT_FGS_ANR_EXTRA_WAIT_DURATION:
updateShortFgsAnrExtraWaitDuration();
break;
@@ -1828,6 +1845,13 @@ final class ActivityManagerConstants extends ContentObserver {
DEFAULT_SHORT_FGS_TIMEOUT_DURATION);
}
+ private void updateShortFgsProcStateExtraWaitDuration() {
+ mShortFgsProcStateExtraWaitDuration = DeviceConfig.getLong(
+ DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+ KEY_SHORT_FGS_PROC_STATE_EXTRA_WAIT_DURATION,
+ DEFAULT_SHORT_FGS_PROC_STATE_EXTRA_WAIT_DURATION);
+ }
+
private void updateShortFgsAnrExtraWaitDuration() {
mShortFgsAnrExtraWaitDuration = DeviceConfig.getLong(
DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
@@ -2009,6 +2033,8 @@ final class ActivityManagerConstants extends ContentObserver {
pw.print(" "); pw.print(KEY_SHORT_FGS_TIMEOUT_DURATION);
pw.print("="); pw.println(mShortFgsTimeoutDuration);
+ pw.print(" "); pw.print(KEY_SHORT_FGS_PROC_STATE_EXTRA_WAIT_DURATION);
+ pw.print("="); pw.println(mShortFgsProcStateExtraWaitDuration);
pw.print(" "); pw.print(KEY_SHORT_FGS_ANR_EXTRA_WAIT_DURATION);
pw.print("="); pw.println(mShortFgsAnrExtraWaitDuration);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 6394d7744645..c779ea9b4916 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -3491,9 +3491,6 @@ public class ActivityManagerService extends IActivityManager.Stub
}
final File tracesDir = new File(ANR_TRACE_DIR);
- // Each set of ANR traces is written to a separate file and dumpstate will process
- // all such files and add them to a captured bug report if they're recent enough.
- maybePruneOldTraces(tracesDir);
// NOTE: We should consider creating the file in native code atomically once we've
// gotten rid of the old scheme of dumping and lot of the code that deals with paths
@@ -3526,6 +3523,9 @@ public class ActivityManagerService extends IActivityManager.Stub
if (firstPidEndOffset != null) {
firstPidEndOffset.set(firstPidEndPos);
}
+ // Each set of ANR traces is written to a separate file and dumpstate will process
+ // all such files and add them to a captured bug report if they're recent enough.
+ maybePruneOldTraces(tracesDir);
return tracesFile;
} finally {
@@ -4945,7 +4945,7 @@ public class ActivityManagerService extends IActivityManager.Stub
app.mState.setVerifiedAdj(ProcessList.INVALID_ADJ);
mOomAdjuster.setAttachingSchedGroupLSP(app);
app.mState.setForcingToImportant(null);
- updateProcessForegroundLocked(app, false, 0, false);
+ clearProcessForegroundLocked(app);
app.mState.setHasShownUi(false);
app.mState.setCached(false);
app.setDebugging(false);
@@ -5805,7 +5805,7 @@ public class ActivityManagerService extends IActivityManager.Stub
return;
}
pr.mState.setForcingToImportant(null);
- updateProcessForegroundLocked(pr, false, 0, false);
+ clearProcessForegroundLocked(pr);
}
updateOomAdjLocked(pr, OomAdjuster.OOM_ADJ_REASON_UI_VISIBILITY);
}
@@ -12706,7 +12706,7 @@ public class ActivityManagerService extends IActivityManager.Stub
for (BroadcastQueue queue : mBroadcastQueues) {
queue.onApplicationCleanupLocked(app);
}
- updateProcessForegroundLocked(app, false, 0, false);
+ clearProcessForegroundLocked(app);
mServices.killServicesLocked(app, allowRestart);
mPhantomProcessList.onAppDied(pid);
@@ -15830,12 +15830,18 @@ public class ActivityManagerService extends IActivityManager.Stub
}
@GuardedBy("this")
+ final void clearProcessForegroundLocked(ProcessRecord proc) {
+ updateProcessForegroundLocked(proc, /* isForeground =*/ false,
+ /* fgsTypes =*/0, /* hasTypeNoneFgs =*/false, /* oomAdj= */ false);
+ }
+
+ @GuardedBy("this")
final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
- int fgServiceTypes, boolean oomAdj) {
+ int fgServiceTypes, boolean hasTypeNoneFgs, boolean oomAdj) {
final ProcessServiceRecord psr = proc.mServices;
final boolean foregroundStateChanged = isForeground != psr.hasForegroundServices();
if (foregroundStateChanged
- || psr.getForegroundServiceTypes() != fgServiceTypes) {
+ || !psr.areForegroundServiceTypesSame(fgServiceTypes, hasTypeNoneFgs)) {
if (foregroundStateChanged) {
// Notify internal listeners.
for (int i = mForegroundServiceStateListeners.size() - 1; i >= 0; i--) {
@@ -15843,7 +15849,7 @@ public class ActivityManagerService extends IActivityManager.Stub
proc.info.packageName, proc.info.uid, proc.getPid(), isForeground);
}
}
- psr.setHasForegroundServices(isForeground, fgServiceTypes);
+ psr.setHasForegroundServices(isForeground, fgServiceTypes, hasTypeNoneFgs);
ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
proc.info.uid);
if (isForeground) {
@@ -17762,7 +17768,7 @@ public class ActivityManagerService extends IActivityManager.Stub
return null;
}
- if ((app.mServices.getForegroundServiceTypes() & foregroundServicetype) != 0) {
+ if ((app.mServices.containsAnyForegroundServiceTypes(foregroundServicetype))) {
return Boolean.TRUE;
}
return null;
diff --git a/services/core/java/com/android/server/am/BroadcastQueueImpl.java b/services/core/java/com/android/server/am/BroadcastQueueImpl.java
index 8ece1807a2ae..1a72fef0683e 100644
--- a/services/core/java/com/android/server/am/BroadcastQueueImpl.java
+++ b/services/core/java/com/android/server/am/BroadcastQueueImpl.java
@@ -735,7 +735,7 @@ public class BroadcastQueueImpl extends BroadcastQueue {
+ " via " + app + ": " + ex;
Slog.w(TAG, msg);
app.killLocked("Can't deliver broadcast", ApplicationExitInfo.REASON_OTHER,
- true);
+ ApplicationExitInfo.SUBREASON_UNDELIVERED_BROADCAST, true);
}
throw ex;
}
@@ -1388,7 +1388,8 @@ public class BroadcastQueueImpl extends BroadcastQueue {
final String msg = "Failed to schedule " + r.intent + " to " + info
+ " via " + app + ": " + e;
Slog.w(TAG, msg);
- app.killLocked("Can't deliver broadcast", ApplicationExitInfo.REASON_OTHER, true);
+ app.killLocked("Can't deliver broadcast", ApplicationExitInfo.REASON_OTHER,
+ ApplicationExitInfo.SUBREASON_UNDELIVERED_BROADCAST, true);
} catch (RuntimeException e) {
Slog.wtf(TAG, "Failed sending broadcast to "
+ r.curComponent + " with " + r.intent, e);
diff --git a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java
index ad5aa87b6a50..5d5dbbbed03f 100644
--- a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java
+++ b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java
@@ -831,7 +831,8 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
final String msg = "Failed to schedule " + r + " to " + receiver
+ " via " + app + ": " + e;
logw(msg);
- app.killLocked("Can't deliver broadcast", ApplicationExitInfo.REASON_OTHER, true);
+ app.killLocked("Can't deliver broadcast", ApplicationExitInfo.REASON_OTHER,
+ ApplicationExitInfo.SUBREASON_UNDELIVERED_BROADCAST, true);
enqueueFinishReceiver(queue, BroadcastRecord.DELIVERY_FAILURE, "remote app");
}
} else {
@@ -858,7 +859,8 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
} catch (RemoteException e) {
final String msg = "Failed to schedule result of " + r + " via " + app + ": " + e;
logw(msg);
- app.killLocked("Can't deliver broadcast", ApplicationExitInfo.REASON_OTHER, true);
+ app.killLocked("Can't deliver broadcast", ApplicationExitInfo.REASON_OTHER,
+ ApplicationExitInfo.SUBREASON_UNDELIVERED_BROADCAST, true);
}
}
// Clear so both local and remote references can be GC'ed
diff --git a/services/core/java/com/android/server/am/BroadcastRecord.java b/services/core/java/com/android/server/am/BroadcastRecord.java
index 84d744270e82..100b2db691de 100644
--- a/services/core/java/com/android/server/am/BroadcastRecord.java
+++ b/services/core/java/com/android/server/am/BroadcastRecord.java
@@ -37,6 +37,7 @@ import android.app.compat.CompatChanges;
import android.content.ComponentName;
import android.content.IIntentReceiver;
import android.content.Intent;
+import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
import android.content.pm.ResolveInfo;
import android.os.Binder;
@@ -870,14 +871,34 @@ final class BroadcastRecord extends Binder {
}
}
- public boolean matchesDeliveryGroup(@NonNull BroadcastRecord other) {
- final String key = (options != null) ? options.getDeliveryGroupKey() : null;
- final String otherKey = (other.options != null)
- ? other.options.getDeliveryGroupKey() : null;
- if (key == null && otherKey == null) {
- return intent.filterEquals(other.intent);
+ boolean matchesDeliveryGroup(@NonNull BroadcastRecord other) {
+ return matchesDeliveryGroup(this, other);
+ }
+
+ private static boolean matchesDeliveryGroup(@NonNull BroadcastRecord newRecord,
+ @NonNull BroadcastRecord oldRecord) {
+ final String newMatchingKey = getDeliveryGroupMatchingKey(newRecord);
+ final String oldMatchingKey = getDeliveryGroupMatchingKey(oldRecord);
+ final IntentFilter newMatchingFilter = getDeliveryGroupMatchingFilter(newRecord);
+ // If neither delivery group key nor matching filter is specified, then use
+ // Intent.filterEquals() to identify the delivery group.
+ if (newMatchingKey == null && oldMatchingKey == null && newMatchingFilter == null) {
+ return newRecord.intent.filterEquals(oldRecord.intent);
+ }
+ if (newMatchingFilter != null && !newMatchingFilter.asPredicate().test(oldRecord.intent)) {
+ return false;
}
- return Objects.equals(key, otherKey);
+ return Objects.equals(newMatchingKey, oldMatchingKey);
+ }
+
+ @Nullable
+ private static String getDeliveryGroupMatchingKey(@NonNull BroadcastRecord record) {
+ return record.options == null ? null : record.options.getDeliveryGroupMatchingKey();
+ }
+
+ @Nullable
+ private static IntentFilter getDeliveryGroupMatchingFilter(@NonNull BroadcastRecord record) {
+ return record.options == null ? null : record.options.getDeliveryGroupMatchingFilter();
}
@Override
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index eb2b7d493251..8082e45b3238 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -73,7 +73,30 @@ import static com.android.server.am.AppProfiler.TAG_PSS;
import static com.android.server.am.PlatformCompatCache.CACHED_COMPAT_CHANGE_CAMERA_MICROPHONE_CAPABILITY;
import static com.android.server.am.PlatformCompatCache.CACHED_COMPAT_CHANGE_PROCESS_CAPABILITY;
import static com.android.server.am.PlatformCompatCache.CACHED_COMPAT_CHANGE_USE_SHORT_FGS_USAGE_INTERACTION_TIME;
+import static com.android.server.am.ProcessList.BACKUP_APP_ADJ;
+import static com.android.server.am.ProcessList.CACHED_APP_IMPORTANCE_LEVELS;
+import static com.android.server.am.ProcessList.CACHED_APP_MAX_ADJ;
+import static com.android.server.am.ProcessList.CACHED_APP_MIN_ADJ;
+import static com.android.server.am.ProcessList.FOREGROUND_APP_ADJ;
+import static com.android.server.am.ProcessList.HEAVY_WEIGHT_APP_ADJ;
+import static com.android.server.am.ProcessList.HOME_APP_ADJ;
+import static com.android.server.am.ProcessList.INVALID_ADJ;
+import static com.android.server.am.ProcessList.PERCEPTIBLE_APP_ADJ;
+import static com.android.server.am.ProcessList.PERCEPTIBLE_LOW_APP_ADJ;
+import static com.android.server.am.ProcessList.PERCEPTIBLE_MEDIUM_APP_ADJ;
+import static com.android.server.am.ProcessList.PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ;
+import static com.android.server.am.ProcessList.PERSISTENT_SERVICE_ADJ;
+import static com.android.server.am.ProcessList.PREVIOUS_APP_ADJ;
+import static com.android.server.am.ProcessList.SCHED_GROUP_BACKGROUND;
+import static com.android.server.am.ProcessList.SCHED_GROUP_DEFAULT;
+import static com.android.server.am.ProcessList.SCHED_GROUP_RESTRICTED;
+import static com.android.server.am.ProcessList.SCHED_GROUP_TOP_APP;
+import static com.android.server.am.ProcessList.SCHED_GROUP_TOP_APP_BOUND;
+import static com.android.server.am.ProcessList.SERVICE_ADJ;
+import static com.android.server.am.ProcessList.SERVICE_B_ADJ;
import static com.android.server.am.ProcessList.TAG_PROCESS_OBSERVERS;
+import static com.android.server.am.ProcessList.UNKNOWN_ADJ;
+import static com.android.server.am.ProcessList.VISIBLE_APP_ADJ;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SWITCH;
import android.annotation.IntDef;
@@ -392,8 +415,8 @@ public class OomAdjuster {
});
mTmpUidRecords = new ActiveUids(service, false);
mTmpQueue = new ArrayDeque<ProcessRecord>(mConstants.CUR_MAX_CACHED_PROCESSES << 1);
- mNumSlots = ((ProcessList.CACHED_APP_MAX_ADJ - ProcessList.CACHED_APP_MIN_ADJ + 1) >> 1)
- / ProcessList.CACHED_APP_IMPORTANCE_LEVELS;
+ mNumSlots = ((CACHED_APP_MAX_ADJ - CACHED_APP_MIN_ADJ + 1) >> 1)
+ / CACHED_APP_IMPORTANCE_LEVELS;
}
void initSettings() {
@@ -579,8 +602,8 @@ public class OomAdjuster {
final ProcessStateRecord state = app.mState;
final boolean wasCached = state.isCached();
final int oldAdj = state.getCurRawAdj();
- final int cachedAdj = oldAdj >= ProcessList.CACHED_APP_MIN_ADJ
- ? oldAdj : ProcessList.UNKNOWN_ADJ;
+ final int cachedAdj = oldAdj >= CACHED_APP_MIN_ADJ
+ ? oldAdj : UNKNOWN_ADJ;
final boolean wasBackground = ActivityManager.isProcStateBackground(
state.getSetProcState());
final int oldCap = state.getSetCapability();
@@ -595,7 +618,7 @@ public class OomAdjuster {
SystemClock.uptimeMillis(), oomAdjReason);
// The 'app' here itself might or might not be in the cycle, for example,
// the case A <=> B vs. A -> B <=> C; anyway, if we spot a cycle here, re-compute them.
- if (!success || (wasCached == state.isCached() && oldAdj != ProcessList.INVALID_ADJ
+ if (!success || (wasCached == state.isCached() && oldAdj != INVALID_ADJ
&& mProcessesInCycle.isEmpty() /* Force re-compute if there is a cycle */
&& oldCap == state.getCurCapability()
&& wasBackground == ActivityManager.isProcStateBackground(
@@ -639,7 +662,7 @@ public class OomAdjuster {
mAdjSeq--;
// Update these reachable processes
updateOomAdjInnerLSP(oomAdjReason, topApp, processes, uids, containsCycle, false);
- } else if (state.getCurRawAdj() == ProcessList.UNKNOWN_ADJ) {
+ } else if (state.getCurRawAdj() == UNKNOWN_ADJ) {
// In case the app goes from non-cached to cached but it doesn't have other reachable
// processes, its adj could be still unknown as of now, assign one.
processes.add(app);
@@ -877,7 +900,7 @@ public class OomAdjuster {
if (state.getAdjSeq() != mAdjSeq) {
state.setContainsCycle(false);
state.setCurRawProcState(PROCESS_STATE_CACHED_EMPTY);
- state.setCurRawAdj(ProcessList.UNKNOWN_ADJ);
+ state.setCurRawAdj(UNKNOWN_ADJ);
state.setSetCapability(PROCESS_CAPABILITY_NONE);
state.resetCachedInfo();
state.setCurBoundByNonBgRestrictedApp(false);
@@ -890,7 +913,7 @@ public class OomAdjuster {
if (!app.isKilledByAm() && app.getThread() != null) {
state.setProcStateChanged(false);
app.mOptRecord.setLastOomAdjChangeReason(oomAdjReason);
- computeOomAdjLSP(app, ProcessList.UNKNOWN_ADJ, topApp, fullUpdate, now, false,
+ computeOomAdjLSP(app, UNKNOWN_ADJ, topApp, fullUpdate, now, false,
computeClients); // It won't enter cycle if not computing clients.
// if any app encountered a cycle, we need to perform an additional loop later
retryCycles |= state.containsCycle();
@@ -990,11 +1013,11 @@ public class OomAdjuster {
// First update the OOM adjustment for each of the
// application processes based on their current state.
- int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
- int nextCachedAdj = curCachedAdj + (ProcessList.CACHED_APP_IMPORTANCE_LEVELS * 2);
+ int curCachedAdj = CACHED_APP_MIN_ADJ;
+ int nextCachedAdj = curCachedAdj + (CACHED_APP_IMPORTANCE_LEVELS * 2);
int curCachedImpAdj = 0;
- int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ + ProcessList.CACHED_APP_IMPORTANCE_LEVELS;
- int nextEmptyAdj = curEmptyAdj + (ProcessList.CACHED_APP_IMPORTANCE_LEVELS * 2);
+ int curEmptyAdj = CACHED_APP_MIN_ADJ + CACHED_APP_IMPORTANCE_LEVELS;
+ int nextEmptyAdj = curEmptyAdj + (CACHED_APP_IMPORTANCE_LEVELS * 2);
final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES;
final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES
@@ -1032,7 +1055,7 @@ public class OomAdjuster {
// If we haven't yet assigned the final cached adj
// to the process, do that now.
if (!app.isKilledByAm() && app.getThread() != null && state.getCurAdj()
- >= ProcessList.UNKNOWN_ADJ) {
+ >= UNKNOWN_ADJ) {
final ProcessServiceRecord psr = app.mServices;
switch (state.getCurProcState()) {
case PROCESS_STATE_CACHED_ACTIVITY:
@@ -1050,7 +1073,7 @@ public class OomAdjuster {
if (connectionImportance > lastCachedGroupImportance) {
lastCachedGroupImportance = connectionImportance;
if (curCachedAdj < nextCachedAdj
- && curCachedAdj < ProcessList.CACHED_APP_MAX_ADJ) {
+ && curCachedAdj < CACHED_APP_MAX_ADJ) {
curCachedImpAdj++;
}
}
@@ -1067,9 +1090,9 @@ public class OomAdjuster {
if (stepCached >= cachedFactor) {
stepCached = 0;
curCachedAdj = nextCachedAdj;
- nextCachedAdj += ProcessList.CACHED_APP_IMPORTANCE_LEVELS * 2;
- if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
- nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
+ nextCachedAdj += CACHED_APP_IMPORTANCE_LEVELS * 2;
+ if (nextCachedAdj > CACHED_APP_MAX_ADJ) {
+ nextCachedAdj = CACHED_APP_MAX_ADJ;
}
}
}
@@ -1092,9 +1115,9 @@ public class OomAdjuster {
if (stepEmpty >= emptyFactor) {
stepEmpty = 0;
curEmptyAdj = nextEmptyAdj;
- nextEmptyAdj += ProcessList.CACHED_APP_IMPORTANCE_LEVELS * 2;
- if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
- nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
+ nextEmptyAdj += CACHED_APP_IMPORTANCE_LEVELS * 2;
+ if (nextEmptyAdj > CACHED_APP_MAX_ADJ) {
+ nextEmptyAdj = CACHED_APP_MAX_ADJ;
}
}
}
@@ -1461,8 +1484,8 @@ public class OomAdjuster {
@Override
public void onVisibleActivity() {
// App has a visible activity; only upgrade adjustment.
- if (adj > ProcessList.VISIBLE_APP_ADJ) {
- adj = ProcessList.VISIBLE_APP_ADJ;
+ if (adj > VISIBLE_APP_ADJ) {
+ adj = VISIBLE_APP_ADJ;
mState.setAdjType("vis-activity");
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise adj to vis-activity: " + app);
@@ -1476,8 +1499,8 @@ public class OomAdjuster {
"Raise procstate to vis-activity (top): " + app);
}
}
- if (schedGroup < ProcessList.SCHED_GROUP_DEFAULT) {
- schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
+ if (schedGroup < SCHED_GROUP_DEFAULT) {
+ schedGroup = SCHED_GROUP_DEFAULT;
}
mState.setCached(false);
mState.setEmpty(false);
@@ -1487,8 +1510,8 @@ public class OomAdjuster {
@Override
public void onPausedActivity() {
- if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
- adj = ProcessList.PERCEPTIBLE_APP_ADJ;
+ if (adj > PERCEPTIBLE_APP_ADJ) {
+ adj = PERCEPTIBLE_APP_ADJ;
mState.setAdjType("pause-activity");
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise adj to pause-activity: " + app);
@@ -1502,8 +1525,8 @@ public class OomAdjuster {
"Raise procstate to pause-activity (top): " + app);
}
}
- if (schedGroup < ProcessList.SCHED_GROUP_DEFAULT) {
- schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
+ if (schedGroup < SCHED_GROUP_DEFAULT) {
+ schedGroup = SCHED_GROUP_DEFAULT;
}
mState.setCached(false);
mState.setEmpty(false);
@@ -1513,8 +1536,8 @@ public class OomAdjuster {
@Override
public void onStoppingActivity(boolean finishing) {
- if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
- adj = ProcessList.PERCEPTIBLE_APP_ADJ;
+ if (adj > PERCEPTIBLE_APP_ADJ) {
+ adj = PERCEPTIBLE_APP_ADJ;
mState.setAdjType("stop-activity");
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
reportOomAdjMessageLocked(TAG_OOM_ADJ,
@@ -1579,10 +1602,10 @@ public class OomAdjuster {
if (app.getThread() == null) {
state.setAdjSeq(mAdjSeq);
- state.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_BACKGROUND);
+ state.setCurrentSchedulingGroup(SCHED_GROUP_BACKGROUND);
state.setCurProcState(PROCESS_STATE_CACHED_EMPTY);
- state.setCurAdj(ProcessList.CACHED_APP_MAX_ADJ);
- state.setCurRawAdj(ProcessList.CACHED_APP_MAX_ADJ);
+ state.setCurAdj(CACHED_APP_MAX_ADJ);
+ state.setCurRawAdj(CACHED_APP_MAX_ADJ);
state.setCompletedAdjSeq(state.getAdjSeq());
state.setCurCapability(PROCESS_CAPABILITY_NONE);
return false;
@@ -1609,7 +1632,7 @@ public class OomAdjuster {
int prevCapability = state.getCurCapability();
final ProcessServiceRecord psr = app.mServices;
- if (state.getMaxAdj() <= ProcessList.FOREGROUND_APP_ADJ) {
+ if (state.getMaxAdj() <= FOREGROUND_APP_ADJ) {
// The max adjustment doesn't allow this app to be anything
// below foreground, so it is not worth doing work for it.
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
@@ -1619,7 +1642,7 @@ public class OomAdjuster {
state.setAdjSeq(mAdjSeq);
state.setCurRawAdj(state.getMaxAdj());
state.setHasForegroundActivities(false);
- state.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_DEFAULT);
+ state.setCurrentSchedulingGroup(SCHED_GROUP_DEFAULT);
state.setCurCapability(PROCESS_CAPABILITY_ALL);
state.setCurProcState(ActivityManager.PROCESS_STATE_PERSISTENT);
// System processes can do UI, and when they do we want to have
@@ -1629,7 +1652,7 @@ public class OomAdjuster {
state.setSystemNoUi(true);
if (app == topApp) {
state.setSystemNoUi(false);
- state.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_TOP_APP);
+ state.setCurrentSchedulingGroup(SCHED_GROUP_TOP_APP);
state.setAdjType("pers-top-activity");
} else if (state.hasTopUi()) {
// sched group/proc state adjustment is below
@@ -1643,11 +1666,11 @@ public class OomAdjuster {
|| state.isRunningRemoteAnimation()) {
// screen on or animating, promote UI
state.setCurProcState(ActivityManager.PROCESS_STATE_PERSISTENT_UI);
- state.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_TOP_APP);
+ state.setCurrentSchedulingGroup(SCHED_GROUP_TOP_APP);
} else {
// screen off, restrict UI scheduling
state.setCurProcState(PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
- state.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_RESTRICTED);
+ state.setCurrentSchedulingGroup(SCHED_GROUP_RESTRICTED);
}
}
state.setCurRawProcState(state.getCurProcState());
@@ -1672,14 +1695,14 @@ public class OomAdjuster {
boolean hasVisibleActivities = false;
if (app == topApp && PROCESS_STATE_CUR_TOP == PROCESS_STATE_TOP) {
// The last app on the list is the foreground app.
- adj = ProcessList.FOREGROUND_APP_ADJ;
+ adj = FOREGROUND_APP_ADJ;
if (mService.mAtmInternal.useTopSchedGroupForTopProcess()) {
- schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
+ schedGroup = SCHED_GROUP_TOP_APP;
state.setAdjType("top-activity");
} else {
// Demote the scheduling group to avoid CPU contention if there is another more
// important process which also uses top-app, such as if SystemUI is animating.
- schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
+ schedGroup = SCHED_GROUP_DEFAULT;
state.setAdjType("intermediate-top-activity");
}
foregroundActivities = true;
@@ -1689,8 +1712,8 @@ public class OomAdjuster {
reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making top: " + app);
}
} else if (state.isRunningRemoteAnimation()) {
- adj = ProcessList.VISIBLE_APP_ADJ;
- schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
+ adj = VISIBLE_APP_ADJ;
+ schedGroup = SCHED_GROUP_TOP_APP;
state.setAdjType("running-remote-anim");
procState = PROCESS_STATE_CUR_TOP;
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
@@ -1698,8 +1721,8 @@ public class OomAdjuster {
}
} else if (app.getActiveInstrumentation() != null) {
// Don't want to kill running instrumentation.
- adj = ProcessList.FOREGROUND_APP_ADJ;
- schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
+ adj = FOREGROUND_APP_ADJ;
+ schedGroup = SCHED_GROUP_DEFAULT;
state.setAdjType("instrumentation");
procState = PROCESS_STATE_FOREGROUND_SERVICE;
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
@@ -1710,7 +1733,7 @@ public class OomAdjuster {
// counts as being in the foreground for OOM killer purposes.
// It's placed in a sched group based on the nature of the
// broadcast as reflected by which queue it's active in.
- adj = ProcessList.FOREGROUND_APP_ADJ;
+ adj = FOREGROUND_APP_ADJ;
schedGroup = mTmpSchedGroup[0];
state.setAdjType("broadcast");
procState = ActivityManager.PROCESS_STATE_RECEIVER;
@@ -1720,17 +1743,17 @@ public class OomAdjuster {
} else if (psr.numberOfExecutingServices() > 0) {
// An app that is currently executing a service callback also
// counts as being in the foreground.
- adj = ProcessList.FOREGROUND_APP_ADJ;
+ adj = FOREGROUND_APP_ADJ;
schedGroup = psr.shouldExecServicesFg()
- ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
+ ? SCHED_GROUP_DEFAULT : SCHED_GROUP_BACKGROUND;
state.setAdjType("exec-service");
procState = PROCESS_STATE_SERVICE;
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making exec-service: " + app);
}
} else if (app == topApp) {
- adj = ProcessList.FOREGROUND_APP_ADJ;
- schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
+ adj = FOREGROUND_APP_ADJ;
+ schedGroup = SCHED_GROUP_BACKGROUND;
state.setAdjType("top-sleeping");
foregroundActivities = true;
procState = PROCESS_STATE_CUR_TOP;
@@ -1739,7 +1762,7 @@ public class OomAdjuster {
}
} else {
// As far as we know the process is empty. We may change our mind later.
- schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
+ schedGroup = SCHED_GROUP_BACKGROUND;
// At this point we don't actually know the adjustment. Use the cached adj
// value that the caller wants us to.
adj = cachedAdj;
@@ -1775,28 +1798,53 @@ public class OomAdjuster {
}
}
- if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
+ int capabilityFromFGS = 0; // capability from foreground service.
+
+ // Adjust for FGS or "has-overlay-ui".
+ if (adj > PERCEPTIBLE_APP_ADJ
|| procState > PROCESS_STATE_FOREGROUND_SERVICE) {
- if (psr.hasForegroundServices()) {
- // The user is aware of this app, so make it visible.
- adj = ProcessList.PERCEPTIBLE_APP_ADJ;
- procState = PROCESS_STATE_FOREGROUND_SERVICE;
- state.setAdjType("fg-service");
- state.setCached(false);
- schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
- if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
- reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to " + state.getAdjType() + ": "
- + app + " ");
- }
+ String adjType = null;
+ int newAdj = 0;
+ int newProcState = 0;
+
+ if (psr.hasForegroundServices() && psr.hasNonShortForegroundServices()) {
+ // For regular (non-short) FGS.
+ adjType = "fg-service";
+ newAdj = PERCEPTIBLE_APP_ADJ;
+ newProcState = PROCESS_STATE_FOREGROUND_SERVICE;
+
} else if (state.hasOverlayUi()) {
- // The process is display an overlay UI.
- adj = ProcessList.PERCEPTIBLE_APP_ADJ;
- procState = PROCESS_STATE_IMPORTANT_FOREGROUND;
+ adjType = "has-overlay-ui";
+ newAdj = PERCEPTIBLE_APP_ADJ;
+ newProcState = PROCESS_STATE_IMPORTANT_FOREGROUND;
+
+ } else if (psr.hasForegroundServices() && !psr.hasNonShortForegroundServices()) {
+ // For short FGS.
+ adjType = "fg-service-short";
+ // We use MEDIUM_APP_ADJ + 1 so we can tell apart EJ (which uses MEDIUM_APP_ADJ + 1)
+ // from short-FGS.
+ // (We use +1 and +2, not +0 and +1, to be consistent with the following
+ // RECENT_FOREGROUND_APP_ADJ tweak)
+ newAdj = PERCEPTIBLE_MEDIUM_APP_ADJ + 1;
+
+ // Short-FGS gets a below-BFGS procstate, so it can't start another FGS from it.
+ newProcState = PROCESS_STATE_IMPORTANT_FOREGROUND;
+
+ // Same as EJ, we explicitly grant network access to short FGS,
+ // even when battery saver or data saver is enabled.
+ capabilityFromFGS |= PROCESS_CAPABILITY_NETWORK;
+ }
+
+ if (adjType != null) {
+ adj = newAdj;
+ procState = newProcState;
+ state.setAdjType(adjType);
state.setCached(false);
- state.setAdjType("has-overlay-ui");
- schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
+ schedGroup = SCHED_GROUP_DEFAULT;
+
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
- reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to overlay ui: " + app);
+ reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to " + adjType + ": "
+ + app + " ");
}
}
}
@@ -1804,11 +1852,18 @@ public class OomAdjuster {
// If the app was recently in the foreground and moved to a foreground service status,
// allow it to get a higher rank in memory for some time, compared to other foreground
// services so that it can finish performing any persistence/processing of in-memory state.
- if (psr.hasForegroundServices() && adj > ProcessList.PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ
+ if (psr.hasForegroundServices() && adj > PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ
&& (state.getLastTopTime() + mConstants.TOP_TO_FGS_GRACE_DURATION > now
|| state.getSetProcState() <= PROCESS_STATE_TOP)) {
- adj = ProcessList.PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ;
- state.setAdjType("fg-service-act");
+ if (psr.hasNonShortForegroundServices()) {
+ adj = PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ;
+ state.setAdjType("fg-service-act");
+ } else {
+ // For short-service FGS, we +1 the value, so we'll be able to detect it in
+ // various dashboards.
+ adj = PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ + 1;
+ state.setAdjType("fg-service-short-act");
+ }
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to recent fg: " + app);
}
@@ -1819,11 +1874,13 @@ public class OomAdjuster {
// foreground services so that it can finish performing any persistence/processing of
// in-memory state.
if (psr.hasTopStartedAlmostPerceptibleServices()
- && adj > ProcessList.PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ
+ && (adj > PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ + 2)
&& (state.getLastTopTime()
+ mConstants.TOP_TO_ALMOST_PERCEPTIBLE_GRACE_DURATION > now
|| state.getSetProcState() <= PROCESS_STATE_TOP)) {
- adj = ProcessList.PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ;
+ // For EJ, we +2 the value, so we'll be able to detect it in
+ // various dashboards.
+ adj = PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ + 2;
// This shall henceforth be called the "EJ" exemption, despite utilizing the
// ALMOST_PERCEPTIBLE flag to work.
state.setAdjType("top-ej-act");
@@ -1832,18 +1889,18 @@ public class OomAdjuster {
}
}
- if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
+ if (adj > PERCEPTIBLE_APP_ADJ
|| procState > PROCESS_STATE_TRANSIENT_BACKGROUND) {
if (state.getForcingToImportant() != null) {
// This is currently used for toasts... they are not interactive, and
// we don't want them to cause the app to become fully foreground (and
// thus out of background check), so we yes the best background level we can.
- adj = ProcessList.PERCEPTIBLE_APP_ADJ;
+ adj = PERCEPTIBLE_APP_ADJ;
procState = PROCESS_STATE_TRANSIENT_BACKGROUND;
state.setCached(false);
state.setAdjType("force-imp");
state.setAdjSource(state.getForcingToImportant());
- schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
+ schedGroup = SCHED_GROUP_DEFAULT;
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to force imp: " + app);
}
@@ -1851,10 +1908,10 @@ public class OomAdjuster {
}
if (state.getCachedIsHeavyWeight()) {
- if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
+ if (adj > HEAVY_WEIGHT_APP_ADJ) {
// We don't want to kill the current heavy-weight process.
- adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
- schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
+ adj = HEAVY_WEIGHT_APP_ADJ;
+ schedGroup = SCHED_GROUP_BACKGROUND;
state.setCached(false);
state.setAdjType("heavy");
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
@@ -1871,11 +1928,11 @@ public class OomAdjuster {
}
if (state.getCachedIsHomeProcess()) {
- if (adj > ProcessList.HOME_APP_ADJ) {
+ if (adj > HOME_APP_ADJ) {
// This process is hosting what we currently consider to be the
// home app, so we don't want to let it go into the background.
- adj = ProcessList.HOME_APP_ADJ;
- schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
+ adj = HOME_APP_ADJ;
+ schedGroup = SCHED_GROUP_BACKGROUND;
state.setCached(false);
state.setAdjType("home");
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
@@ -1892,12 +1949,12 @@ public class OomAdjuster {
}
if (state.getCachedIsPreviousProcess() && state.getCachedHasActivities()) {
- if (adj > ProcessList.PREVIOUS_APP_ADJ) {
+ if (adj > PREVIOUS_APP_ADJ) {
// This was the previous process that showed UI to the user.
// We want to try to keep it around more aggressively, to give
// a good experience around switching between two apps.
- adj = ProcessList.PREVIOUS_APP_ADJ;
- schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
+ adj = PREVIOUS_APP_ADJ;
+ schedGroup = SCHED_GROUP_BACKGROUND;
state.setCached(false);
state.setAdjType("previous");
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
@@ -1935,9 +1992,9 @@ public class OomAdjuster {
final BackupRecord backupTarget = mService.mBackupTargets.get(app.userId);
if (backupTarget != null && app == backupTarget.app) {
// If possible we want to avoid killing apps while they're being backed up
- if (adj > ProcessList.BACKUP_APP_ADJ) {
+ if (adj > BACKUP_APP_ADJ) {
if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
- adj = ProcessList.BACKUP_APP_ADJ;
+ adj = BACKUP_APP_ADJ;
if (procState > PROCESS_STATE_TRANSIENT_BACKGROUND) {
procState = PROCESS_STATE_TRANSIENT_BACKGROUND;
}
@@ -1956,12 +2013,11 @@ public class OomAdjuster {
}
}
- int capabilityFromFGS = 0; // capability from foreground service.
boolean boundByNonBgRestricted = state.isCurBoundByNonBgRestrictedApp();
boolean scheduleLikeTopApp = false;
for (int is = psr.numberOfRunningServices() - 1;
- is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
- || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
+ is >= 0 && (adj > FOREGROUND_APP_ADJ
+ || schedGroup == SCHED_GROUP_BACKGROUND
|| procState > PROCESS_STATE_TOP);
is--) {
ServiceRecord s = psr.getRunningServiceAt(is);
@@ -1980,7 +2036,7 @@ public class OomAdjuster {
// go to the LRU list because it may be pretty heavy with
// UI stuff. We'll tag it with a label just to help
// debug and understand what is going on.
- if (adj > ProcessList.SERVICE_ADJ) {
+ if (adj > SERVICE_ADJ) {
state.setAdjType("cch-started-ui-services");
}
} else {
@@ -1989,8 +2045,8 @@ public class OomAdjuster {
// This service has seen some activity within
// recent memory, so we will keep its process ahead
// of the background processes.
- if (adj > ProcessList.SERVICE_ADJ) {
- adj = ProcessList.SERVICE_ADJ;
+ if (adj > SERVICE_ADJ) {
+ adj = SERVICE_ADJ;
state.setAdjType("started-services");
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
reportOomAdjMessageLocked(TAG_OOM_ADJ,
@@ -2002,12 +2058,14 @@ public class OomAdjuster {
// If we have let the service slide into the background
// state, still have some text describing what it is doing
// even though the service no longer has an impact.
- if (adj > ProcessList.SERVICE_ADJ) {
+ if (adj > SERVICE_ADJ) {
state.setAdjType("cch-started-services");
}
}
}
+ // TODO(short-service): While-in-user permissions. Do we need any change here for
+ // short-FGS? (Likely not)
if (s.isForeground) {
final int fgsType = s.foregroundServiceType;
if (s.mAllowWhileInUsePermissionInFgs) {
@@ -2033,14 +2091,14 @@ public class OomAdjuster {
ArrayMap<IBinder, ArrayList<ConnectionRecord>> serviceConnections = s.getConnections();
for (int conni = serviceConnections.size() - 1;
- conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
- || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
+ conni >= 0 && (adj > FOREGROUND_APP_ADJ
+ || schedGroup == SCHED_GROUP_BACKGROUND
|| procState > PROCESS_STATE_TOP);
conni--) {
ArrayList<ConnectionRecord> clist = serviceConnections.valueAt(conni);
for (int i = 0;
- i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
- || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
+ i < clist.size() && (adj > FOREGROUND_APP_ADJ
+ || schedGroup == SCHED_GROUP_BACKGROUND
|| procState > PROCESS_STATE_TOP);
i++) {
// XXX should compute this based on the max of
@@ -2090,6 +2148,7 @@ public class OomAdjuster {
// in this case unless they explicitly request it.
if ((cstate.getCurCapability() & PROCESS_CAPABILITY_NETWORK) != 0) {
if (clientProcState <= PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
+ // This is used to grant network access to Expedited Jobs.
if ((cr.flags & Context.BIND_BYPASS_POWER_NETWORK_RESTRICTIONS)
!= 0) {
capability |= PROCESS_CAPABILITY_NETWORK;
@@ -2112,7 +2171,7 @@ public class OomAdjuster {
String adjType = null;
if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
// Similar to BIND_WAIVE_PRIORITY, keep it unfrozen.
- if (clientAdj < ProcessList.CACHED_APP_MIN_ADJ) {
+ if (clientAdj < CACHED_APP_MIN_ADJ) {
app.mOptRecord.setShouldNotFreeze(true);
}
// Not doing bind OOM management, so treat
@@ -2152,46 +2211,50 @@ public class OomAdjuster {
// list to be killed and restarted if needed for
// memory.
if (state.hasShownUi() && !state.getCachedIsHomeProcess()
- && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
- if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
+ && clientAdj > PERCEPTIBLE_APP_ADJ) {
+ if (adj >= CACHED_APP_MIN_ADJ) {
adjType = "cch-bound-ui-services";
}
} else {
int newAdj;
+ int lbAdj = VISIBLE_APP_ADJ; // lower bound of adj.
if ((cr.flags&(Context.BIND_ABOVE_CLIENT
|Context.BIND_IMPORTANT)) != 0) {
- if (clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ) {
+ if (clientAdj >= PERSISTENT_SERVICE_ADJ) {
newAdj = clientAdj;
} else {
// make this service persistent
- newAdj = ProcessList.PERSISTENT_SERVICE_ADJ;
- schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
+ newAdj = PERSISTENT_SERVICE_ADJ;
+ schedGroup = SCHED_GROUP_DEFAULT;
procState = ActivityManager.PROCESS_STATE_PERSISTENT;
cr.trackProcState(procState, mAdjSeq);
trackedProcState = true;
}
} else if ((cr.flags & Context.BIND_NOT_PERCEPTIBLE) != 0
- && clientAdj <= ProcessList.PERCEPTIBLE_APP_ADJ
- && adj >= ProcessList.PERCEPTIBLE_LOW_APP_ADJ) {
- newAdj = ProcessList.PERCEPTIBLE_LOW_APP_ADJ;
+ && clientAdj <= PERCEPTIBLE_APP_ADJ
+ && adj >= (lbAdj = PERCEPTIBLE_LOW_APP_ADJ)) {
+ newAdj = PERCEPTIBLE_LOW_APP_ADJ;
} else if ((cr.flags & Context.BIND_ALMOST_PERCEPTIBLE) != 0
- && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
- && adj >= ProcessList.PERCEPTIBLE_MEDIUM_APP_ADJ) {
- newAdj = ProcessList.PERCEPTIBLE_MEDIUM_APP_ADJ;
+ && clientAdj < PERCEPTIBLE_APP_ADJ
+ && adj >= (lbAdj = (PERCEPTIBLE_MEDIUM_APP_ADJ + 2))) {
+ // This is for expedited jobs.
+ // We use MEDIUM_APP_ADJ + 2 here, so we can tell apart
+ // EJ and short-FGS.
+ newAdj = PERCEPTIBLE_MEDIUM_APP_ADJ + 2;
} else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
- && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
- && adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
- newAdj = ProcessList.PERCEPTIBLE_APP_ADJ;
- } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
+ && clientAdj < PERCEPTIBLE_APP_ADJ
+ && adj >= (lbAdj = PERCEPTIBLE_APP_ADJ)) {
+ newAdj = PERCEPTIBLE_APP_ADJ;
+ } else if (clientAdj >= PERCEPTIBLE_APP_ADJ) {
newAdj = clientAdj;
} else if (cr.hasFlag(BIND_TREAT_LIKE_VISIBLE_FOREGROUND_SERVICE)
- && clientAdj <= ProcessList.VISIBLE_APP_ADJ
- && adj > ProcessList.VISIBLE_APP_ADJ) {
- newAdj = ProcessList.VISIBLE_APP_ADJ;
+ && clientAdj <= VISIBLE_APP_ADJ
+ && adj > VISIBLE_APP_ADJ) {
+ newAdj = VISIBLE_APP_ADJ;
} else {
- if (adj > ProcessList.VISIBLE_APP_ADJ) {
+ if (adj > VISIBLE_APP_ADJ) {
// TODO: Is this too limiting for apps bound from TOP?
- newAdj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
+ newAdj = Math.max(clientAdj, lbAdj);
} else {
newAdj = adj;
}
@@ -2216,7 +2279,7 @@ public class OomAdjuster {
if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
schedGroup = curSchedGroup;
} else {
- schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
+ schedGroup = SCHED_GROUP_DEFAULT;
}
}
if (clientProcState < PROCESS_STATE_TOP) {
@@ -2269,10 +2332,10 @@ public class OomAdjuster {
}
}
- if (schedGroup < ProcessList.SCHED_GROUP_TOP_APP
+ if (schedGroup < SCHED_GROUP_TOP_APP
&& (cr.flags & Context.BIND_SCHEDULE_LIKE_TOP_APP) != 0
&& clientIsSystem) {
- schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
+ schedGroup = SCHED_GROUP_TOP_APP;
scheduleLikeTopApp = true;
}
@@ -2315,7 +2378,7 @@ public class OomAdjuster {
// pings a frozen process. Accordingly, any cached app that is
// bound by an unfrozen app via a WPRI binding has to remain
// unfrozen.
- if (clientAdj < ProcessList.CACHED_APP_MIN_ADJ) {
+ if (clientAdj < CACHED_APP_MIN_ADJ) {
app.mOptRecord.setShouldNotFreeze(true);
}
}
@@ -2324,15 +2387,15 @@ public class OomAdjuster {
}
final ActivityServiceConnectionsHolder a = cr.activity;
if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
- if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ
+ if (a != null && adj > FOREGROUND_APP_ADJ
&& a.isActivityVisible()) {
- adj = ProcessList.FOREGROUND_APP_ADJ;
+ adj = FOREGROUND_APP_ADJ;
state.setCurRawAdj(adj);
if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
- schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
+ schedGroup = SCHED_GROUP_TOP_APP_BOUND;
} else {
- schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
+ schedGroup = SCHED_GROUP_DEFAULT;
}
}
state.setCached(false);
@@ -2354,14 +2417,14 @@ public class OomAdjuster {
final ProcessProviderRecord ppr = app.mProviders;
for (int provi = ppr.numberOfProviders() - 1;
- provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
- || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
+ provi >= 0 && (adj > FOREGROUND_APP_ADJ
+ || schedGroup == SCHED_GROUP_BACKGROUND
|| procState > PROCESS_STATE_TOP);
provi--) {
ContentProviderRecord cpr = ppr.getProviderAt(provi);
for (int i = cpr.connections.size() - 1;
- i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
- || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
+ i >= 0 && (adj > FOREGROUND_APP_ADJ
+ || schedGroup == SCHED_GROUP_BACKGROUND
|| procState > PROCESS_STATE_TOP);
i--) {
ContentProviderConnection conn = cpr.connections.get(i);
@@ -2403,11 +2466,10 @@ public class OomAdjuster {
String adjType = null;
if (adj > clientAdj) {
if (state.hasShownUi() && !state.getCachedIsHomeProcess()
- && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
+ && clientAdj > PERCEPTIBLE_APP_ADJ) {
adjType = "cch-ui-provider";
} else {
- adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
- ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
+ adj = Math.max(clientAdj, FOREGROUND_APP_ADJ);
state.setCurRawAdj(adj);
adjType = "provider";
}
@@ -2431,7 +2493,7 @@ public class OomAdjuster {
state.setCurRawProcState(procState);
}
if (cstate.getCurrentSchedulingGroup() > schedGroup) {
- schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
+ schedGroup = SCHED_GROUP_DEFAULT;
}
if (adjType != null) {
state.setAdjType(adjType);
@@ -2452,10 +2514,10 @@ public class OomAdjuster {
// dependencies, ensure that its adjustment is at least
// FOREGROUND_APP_ADJ.
if (cpr.hasExternalProcessHandles()) {
- if (adj > ProcessList.FOREGROUND_APP_ADJ) {
- adj = ProcessList.FOREGROUND_APP_ADJ;
+ if (adj > FOREGROUND_APP_ADJ) {
+ adj = FOREGROUND_APP_ADJ;
state.setCurRawAdj(adj);
- schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
+ schedGroup = SCHED_GROUP_DEFAULT;
state.setCached(false);
state.setAdjType("ext-provider");
state.setAdjTarget(cpr.name);
@@ -2477,9 +2539,9 @@ public class OomAdjuster {
if (ppr.getLastProviderTime() > 0
&& (ppr.getLastProviderTime() + mConstants.CONTENT_PROVIDER_RETAIN_TIME) > now) {
- if (adj > ProcessList.PREVIOUS_APP_ADJ) {
- adj = ProcessList.PREVIOUS_APP_ADJ;
- schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
+ if (adj > PREVIOUS_APP_ADJ) {
+ adj = PREVIOUS_APP_ADJ;
+ schedGroup = SCHED_GROUP_BACKGROUND;
state.setCached(false);
state.setAdjType("recent-provider");
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
@@ -2510,7 +2572,7 @@ public class OomAdjuster {
}
}
- if (adj == ProcessList.SERVICE_ADJ) {
+ if (adj == SERVICE_ADJ) {
if (doingAll && !cycleReEval) {
state.setServiceB(mNewNumAServiceProcs > (mNumServiceProcs / 3));
mNewNumServiceProcs++;
@@ -2534,7 +2596,7 @@ public class OomAdjuster {
}
}
if (state.isServiceB()) {
- adj = ProcessList.SERVICE_B_ADJ;
+ adj = SERVICE_B_ADJ;
}
}
@@ -2542,8 +2604,8 @@ public class OomAdjuster {
if (adj > state.getMaxAdj()) {
adj = state.getMaxAdj();
- if (adj <= ProcessList.PERCEPTIBLE_LOW_APP_ADJ) {
- schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
+ if (adj <= PERCEPTIBLE_LOW_APP_ADJ) {
+ schedGroup = SCHED_GROUP_DEFAULT;
}
}
@@ -2552,8 +2614,8 @@ public class OomAdjuster {
if (procState >= PROCESS_STATE_BOUND_FOREGROUND_SERVICE
&& mService.mWakefulness.get() != PowerManagerInternal.WAKEFULNESS_AWAKE
&& !scheduleLikeTopApp) {
- if (schedGroup > ProcessList.SCHED_GROUP_RESTRICTED) {
- schedGroup = ProcessList.SCHED_GROUP_RESTRICTED;
+ if (schedGroup > SCHED_GROUP_RESTRICTED) {
+ schedGroup = SCHED_GROUP_RESTRICTED;
}
}
@@ -2685,7 +2747,7 @@ public class OomAdjuster {
mCachedAppOptimizer.onOomAdjustChanged(state.getSetAdj(), state.getCurAdj(), app);
} else if (mService.mWakefulness.get() != PowerManagerInternal.WAKEFULNESS_AWAKE) {
// See if we can compact persistent and bfgs services now that screen is off
- if (state.getSetAdj() < ProcessList.FOREGROUND_APP_ADJ
+ if (state.getSetAdj() < FOREGROUND_APP_ADJ
&& !state.isRunningRemoteAnimation()
// Because these can fire independent of oom_adj/procstate changes, we need
// to throttle the actual dispatch of these requests in addition to the
@@ -2714,7 +2776,7 @@ public class OomAdjuster {
if (uidRec != null) {
uidRec.noteProcAdjChanged();
}
- state.setVerifiedAdj(ProcessList.INVALID_ADJ);
+ state.setVerifiedAdj(INVALID_ADJ);
}
final int curSchedGroup = state.getCurrentSchedulingGroup();
@@ -2734,14 +2796,14 @@ public class OomAdjuster {
} else {
int processGroup;
switch (curSchedGroup) {
- case ProcessList.SCHED_GROUP_BACKGROUND:
+ case SCHED_GROUP_BACKGROUND:
processGroup = THREAD_GROUP_BACKGROUND;
break;
- case ProcessList.SCHED_GROUP_TOP_APP:
- case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
+ case SCHED_GROUP_TOP_APP:
+ case SCHED_GROUP_TOP_APP_BOUND:
processGroup = THREAD_GROUP_TOP_APP;
break;
- case ProcessList.SCHED_GROUP_RESTRICTED:
+ case SCHED_GROUP_RESTRICTED:
processGroup = THREAD_GROUP_RESTRICTED;
break;
default:
@@ -2752,9 +2814,9 @@ public class OomAdjuster {
0 /* unused */, app.getPid(), processGroup, app.processName));
try {
final int renderThreadTid = app.getRenderThreadTid();
- if (curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
+ if (curSchedGroup == SCHED_GROUP_TOP_APP) {
// do nothing if we already switched to RT
- if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
+ if (oldSchedGroup != SCHED_GROUP_TOP_APP) {
app.getWindowProcessController().onTopProcChanged();
if (mService.mUseFifoUiScheduling) {
// Switch UI pipeline for app to SCHED_FIFO
@@ -2785,8 +2847,8 @@ public class OomAdjuster {
}
}
}
- } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
- curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
+ } else if (oldSchedGroup == SCHED_GROUP_TOP_APP
+ && curSchedGroup != SCHED_GROUP_TOP_APP) {
app.getWindowProcessController().onTopProcChanged();
if (mService.mUseFifoUiScheduling) {
try {
@@ -2972,18 +3034,18 @@ public class OomAdjuster {
@GuardedBy({"mService", "mProcLock"})
void setAttachingSchedGroupLSP(ProcessRecord app) {
- int initialSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
+ int initialSchedGroup = SCHED_GROUP_DEFAULT;
final ProcessStateRecord state = app.mState;
// If the process has been marked as foreground, it is starting as the top app (with
// Zygote#START_AS_TOP_APP_ARG), so boost the thread priority of its default UI thread.
if (state.hasForegroundActivities()) {
try {
// The priority must be the same as how does {@link #applyOomAdjLSP} set for
- // {@link ProcessList.SCHED_GROUP_TOP_APP}. We don't check render thread because it
+ // {@link SCHED_GROUP_TOP_APP}. We don't check render thread because it
// is not ready when attaching.
app.getWindowProcessController().onTopProcChanged();
setThreadPriority(app.getPid(), THREAD_PRIORITY_TOP_APP_BOOST);
- initialSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
+ initialSchedGroup = SCHED_GROUP_TOP_APP;
} catch (Exception e) {
Slog.w(TAG, "Failed to pre-set top priority to " + app + " " + e);
}
@@ -3204,10 +3266,10 @@ public class OomAdjuster {
final ProcessStateRecord state = app.mState;
// Use current adjustment when freezing, set adjustment when unfreezing.
- if (state.getCurAdj() >= ProcessList.CACHED_APP_MIN_ADJ && !opt.isFrozen()
+ if (state.getCurAdj() >= CACHED_APP_MIN_ADJ && !opt.isFrozen()
&& !opt.shouldNotFreeze()) {
mCachedAppOptimizer.freezeAppAsyncLSP(app);
- } else if (state.getSetAdj() < ProcessList.CACHED_APP_MIN_ADJ) {
+ } else if (state.getSetAdj() < CACHED_APP_MIN_ADJ) {
mCachedAppOptimizer.unfreezeAppLSP(app, oomAdjReason);
}
}
diff --git a/services/core/java/com/android/server/am/ProcessServiceRecord.java b/services/core/java/com/android/server/am/ProcessServiceRecord.java
index 67eb675503ad..13264db01680 100644
--- a/services/core/java/com/android/server/am/ProcessServiceRecord.java
+++ b/services/core/java/com/android/server/am/ProcessServiceRecord.java
@@ -21,6 +21,7 @@ import static com.android.server.am.ProcessProfileRecord.HOSTING_COMPONENT_TYPE_
import android.app.ActivityManager;
import android.content.Context;
+import android.content.pm.ServiceInfo;
import android.os.IBinder;
import android.os.SystemClock;
import android.util.ArrayMap;
@@ -78,11 +79,20 @@ final class ProcessServiceRecord {
private int mConnectionImportance;
/**
- * Type of foreground service, if there is a foreground service.
+ * The OR'ed foreground service types that are running on this process.
+ * Note, because TYPE_NONE (==0) is also a valid type for pre-U apps, this field doesn't tell
+ * if the process has any TYPE_NONE FGS or not, but {@link #mHasTypeNoneFgs} will be set
+ * in that case.
*/
private int mFgServiceTypes;
/**
+ * Whether the process has any foreground services of TYPE_NONE running.
+ * @see #mFgServiceTypes
+ */
+ private boolean mHasTypeNoneFgs;
+
+ /**
* Last reported foreground service types.
*/
private int mRepFgServiceTypes;
@@ -145,9 +155,18 @@ final class ProcessServiceRecord {
return mHasClientActivities;
}
- void setHasForegroundServices(boolean hasForegroundServices, int fgServiceTypes) {
+ void setHasForegroundServices(boolean hasForegroundServices, int fgServiceTypes,
+ boolean hasTypeNoneFgs) {
+ // hasForegroundServices should be the same as "either it has any FGS types, or none types".
+ // We still take this as a parameter because it's used in the callsite...
+ if (ActivityManagerDebugConfig.DEBUG_SERVICE
+ && hasForegroundServices != ((fgServiceTypes != 0) || hasTypeNoneFgs)) {
+ throw new IllegalStateException("hasForegroundServices mismatch");
+ }
+
mHasForegroundServices = hasForegroundServices;
mFgServiceTypes = fgServiceTypes;
+ mHasTypeNoneFgs = hasTypeNoneFgs;
mApp.getWindowProcessController().setHasForegroundServices(hasForegroundServices);
if (hasForegroundServices) {
mApp.mProfile.addHostingComponentType(HOSTING_COMPONENT_TYPE_FOREGROUND_SERVICE);
@@ -168,10 +187,43 @@ final class ProcessServiceRecord {
return mRepHasForegroundServices;
}
- int getForegroundServiceTypes() {
+ /**
+ * Returns the FGS typps, but it doesn't tell if the types include "NONE" or not, so
+ * do not use it outside of this class.
+ */
+ private int getForegroundServiceTypes() {
return mHasForegroundServices ? mFgServiceTypes : 0;
}
+ boolean areForegroundServiceTypesSame(@ServiceInfo.ForegroundServiceType int types,
+ boolean hasTypeNoneFgs) {
+ return ((getForegroundServiceTypes() & types) == types)
+ && (mHasTypeNoneFgs == hasTypeNoneFgs);
+ }
+
+ /**
+ * @return true if the fgs types includes any of the given types.
+ * (wouldn't work for TYPE_NONE, which is 0)
+ */
+ boolean containsAnyForegroundServiceTypes(@ServiceInfo.ForegroundServiceType int types) {
+ return (getForegroundServiceTypes() & types) != 0;
+ }
+
+ /**
+ * @return true if the process has any FGS that are _not_ a "short" FGS.
+ */
+ boolean hasNonShortForegroundServices() {
+ if (!mHasForegroundServices) {
+ return false; // Process has no FGS running.
+ }
+ // Does the process has any FGS of TYPE_NONE?
+ if (mHasTypeNoneFgs) {
+ return true;
+ }
+ // If not, we can just check mFgServiceTypes.
+ return mFgServiceTypes != ServiceInfo.FOREGROUND_SERVICE_TYPE_SHORT_SERVICE;
+ }
+
int getReportedForegroundServiceTypes() {
return mRepFgServiceTypes;
}
diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java
index c27ed7a46844..0468152acdd8 100644
--- a/services/core/java/com/android/server/am/ServiceRecord.java
+++ b/services/core/java/com/android/server/am/ServiceRecord.java
@@ -201,7 +201,9 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN
ActivityManagerService.FgsTempAllowListItem mInfoTempFgsAllowListReason;
// Is the same mInfoAllowStartForeground string has been logged before? Used for dedup.
boolean mLoggedInfoAllowStartForeground;
- // The number of times Service.startForeground() is called;
+ // The number of times Service.startForeground() is called, after this service record is
+ // created. (i.e. due to "bound" or "start".) It never decreases, even when stopForeground()
+ // is called.
int mStartForegroundCount;
// Last time mAllowWhileInUsePermissionInFgs or mAllowStartForeground is set.
long mLastSetFgsRestrictionTime;
@@ -769,6 +771,7 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN
* has no reason to start again. Note this condition doesn't consider the bindings.
*/
boolean canStopIfKilled(boolean isStartCanceled) {
+ // TODO(short-service): If it's a "short FGS", we should stop it if killed.
return startRequested && (stopIfKilled || isStartCanceled) && pendingStarts.isEmpty();
}
@@ -1223,4 +1226,16 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN
public ComponentName getComponentName() {
return name;
}
+
+ /**
+ * @return true if it's a foreground service of the "short service" type and don't have
+ * other fgs type bits set.
+ */
+ public boolean isShortFgs() {
+ // Note if the type contains FOREGROUND_SERVICE_TYPE_SHORT_SERVICE but also other bits
+ // set, it's _not_ considered be a short service. (because we shouldn't apply
+ // the short-service restrictions)
+ return isForeground
+ && (foregroundServiceType == ServiceInfo.FOREGROUND_SERVICE_TYPE_SHORT_SERVICE);
+ }
}
diff --git a/services/core/java/com/android/server/am/UidRecord.java b/services/core/java/com/android/server/am/UidRecord.java
index 51568d83157e..b617582dce44 100644
--- a/services/core/java/com/android/server/am/UidRecord.java
+++ b/services/core/java/com/android/server/am/UidRecord.java
@@ -238,11 +238,13 @@ public final class UidRecord {
mEphemeral = ephemeral;
}
+ /** Returns whether the UID has any FGS of any type or not (including "short fgs") */
@GuardedBy(anyOf = {"mService", "mProcLock"})
boolean hasForegroundServices() {
return mForegroundServices;
}
+ /** Sets whether the UID has any FGS of any type or not (including "short fgs") */
@GuardedBy({"mService", "mProcLock"})
void setForegroundServices(boolean foregroundServices) {
mForegroundServices = foregroundServices;
diff --git a/services/core/java/com/android/server/app/GameManagerService.java b/services/core/java/com/android/server/app/GameManagerService.java
index 64f2aa38e5b1..b92c1635d7c6 100644
--- a/services/core/java/com/android/server/app/GameManagerService.java
+++ b/services/core/java/com/android/server/app/GameManagerService.java
@@ -35,9 +35,11 @@ import android.app.ActivityManager;
import android.app.GameManager;
import android.app.GameManager.GameMode;
import android.app.GameManagerInternal;
+import android.app.GameModeConfiguration;
import android.app.GameModeInfo;
import android.app.GameState;
import android.app.IGameManagerService;
+import android.app.IGameModeListener;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -57,10 +59,12 @@ import android.os.Bundle;
import android.os.Environment;
import android.os.FileUtils;
import android.os.Handler;
+import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.PowerManagerInternal;
import android.os.Process;
+import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.ShellCallback;
import android.os.UserManager;
@@ -131,6 +135,7 @@ public final class GameManagerService extends IGameManagerService.Stub {
private final Context mContext;
private final Object mLock = new Object();
private final Object mDeviceConfigLock = new Object();
+ private final Object mGameModeListenerLock = new Object();
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
final Handler mHandler;
private final PackageManager mPackageManager;
@@ -144,6 +149,9 @@ public final class GameManagerService extends IGameManagerService.Stub {
private final ArrayMap<Integer, GameManagerSettings> mSettings = new ArrayMap<>();
@GuardedBy("mDeviceConfigLock")
private final ArrayMap<String, GamePackageConfiguration> mConfigs = new ArrayMap<>();
+ // listener to caller uid map
+ @GuardedBy("mGameModeListenerLock")
+ private final ArrayMap<IGameModeListener, Integer> mGameModeListeners = new ArrayMap<>();
@Nullable
private final GameServiceController mGameServiceController;
@@ -399,6 +407,7 @@ public final class GameManagerService extends IGameManagerService.Stub {
// Turn the raw string to the corresponding fps int.
// Return 0 when disabling, -1 for invalid fps.
static int getFpsInt(String raw) {
+ // TODO(b/243448953): make sure this translates to proper values based on current display
switch (raw) {
case "30":
return FrameRate.FPS_30.fps;
@@ -596,6 +605,14 @@ public final class GameManagerService extends IGameManagerService.Stub {
}
}
+ // used to check if the override package config has any game mode config, if not, it's
+ // considered empty and safe to delete from settings
+ boolean hasActiveGameModeConfig() {
+ synchronized (mModeConfigLock) {
+ return !mModeConfigs.isEmpty();
+ }
+ }
+
/**
* GameModeConfiguration contains all the values for all the interventions associated with
* a game mode.
@@ -691,10 +708,27 @@ public final class GameManagerService extends IGameManagerService.Stub {
public boolean isActive() {
return (mGameMode == GameManager.GAME_MODE_STANDARD
|| mGameMode == GameManager.GAME_MODE_PERFORMANCE
- || mGameMode == GameManager.GAME_MODE_BATTERY)
+ || mGameMode == GameManager.GAME_MODE_BATTERY
+ || mGameMode == GameManager.GAME_MODE_CUSTOM)
&& !willGamePerformOptimizations(mGameMode);
}
+ android.app.GameModeConfiguration toPublicGameModeConfig() {
+ int fpsOverride = getFpsInt(mFps);
+ // TODO(b/243448953): match to proper value in case of display change?
+ fpsOverride = fpsOverride > 0 ? fpsOverride
+ : android.app.GameModeConfiguration.FPS_OVERRIDE_NONE;
+ final float scaling = mScaling == DEFAULT_SCALING ? 1.0f : mScaling;
+ return new android.app.GameModeConfiguration.Builder()
+ .setScalingFactor(scaling)
+ .setFpsOverride(fpsOverride).build();
+ }
+
+ void updateFromPublicGameModeConfig(android.app.GameModeConfiguration config) {
+ mScaling = config.getScalingFactor();
+ mFps = String.valueOf(config.getFpsOverride());
+ }
+
/**
* @hide
*/
@@ -723,7 +757,8 @@ public final class GameManagerService extends IGameManagerService.Stub {
}
private int getAvailableGameModesBitfield() {
- int field = 0;
+ int field = modeToBitmask(GameManager.GAME_MODE_CUSTOM)
+ | modeToBitmask(GameManager.GAME_MODE_STANDARD);
synchronized (mModeConfigLock) {
for (final int mode : mModeConfigs.keySet()) {
field |= modeToBitmask(mode);
@@ -735,13 +770,6 @@ public final class GameManagerService extends IGameManagerService.Stub {
if (mPerfModeOptedIn) {
field |= modeToBitmask(GameManager.GAME_MODE_PERFORMANCE);
}
- // The lowest bit is reserved for UNSUPPORTED, STANDARD is supported if we support any
- // other mode.
- if (field > 1) {
- field |= modeToBitmask(GameManager.GAME_MODE_STANDARD);
- } else {
- field |= modeToBitmask(GameManager.GAME_MODE_UNSUPPORTED);
- }
return field;
}
@@ -763,6 +791,21 @@ public final class GameManagerService extends IGameManagerService.Stub {
}
/**
+ * Get an array of a package's opted-in game modes.
+ */
+ public @GameMode int[] getOptedInGameModes() {
+ if (mBatteryModeOptedIn && mPerfModeOptedIn) {
+ return new int[]{GameManager.GAME_MODE_BATTERY, GameManager.GAME_MODE_PERFORMANCE};
+ } else if (mBatteryModeOptedIn) {
+ return new int[]{GameManager.GAME_MODE_BATTERY};
+ } else if (mPerfModeOptedIn) {
+ return new int[]{GameManager.GAME_MODE_PERFORMANCE};
+ } else {
+ return new int[]{};
+ }
+ }
+
+ /**
* Get a GameModeConfiguration for a given game mode.
*
* @return The package's GameModeConfiguration for the provided mode or null if absent
@@ -848,7 +891,7 @@ public final class GameManagerService extends IGameManagerService.Stub {
private final class LocalService extends GameManagerInternal {
@Override
public float getResolutionScalingFactor(String packageName, int userId) {
- final int gameMode = getGameModeFromSettings(packageName, userId);
+ final int gameMode = getGameModeFromSettingsUnchecked(packageName, userId);
return getResolutionScalingFactorInternal(packageName, gameMode, userId);
}
}
@@ -927,7 +970,7 @@ public final class GameManagerService extends IGameManagerService.Stub {
config = mConfigs.get(packageName);
}
if (config == null) {
- return new int[]{};
+ return new int[]{GameManager.GAME_MODE_STANDARD, GameManager.GAME_MODE_CUSTOM};
}
return config.getAvailableGameModes();
}
@@ -953,12 +996,13 @@ public final class GameManagerService extends IGameManagerService.Stub {
return getAvailableGameModesUnchecked(packageName);
}
- private @GameMode int getGameModeFromSettings(String packageName, @UserIdInt int userId) {
+ private @GameMode int getGameModeFromSettingsUnchecked(String packageName,
+ @UserIdInt int userId) {
synchronized (mLock) {
if (!mSettings.containsKey(userId)) {
Slog.d(TAG, "User ID '" + userId + "' does not have a Game Mode"
- + " selected for package: '" + packageName + "'");
- return GameManager.GAME_MODE_UNSUPPORTED;
+ + " selected for package: '" + packageName + "'");
+ return GameManager.GAME_MODE_STANDARD;
}
return mSettings.get(userId).getGameModeLocked(packageName);
@@ -991,12 +1035,12 @@ public final class GameManagerService extends IGameManagerService.Stub {
// return a value if the package name is valid. Next, check if the caller has the necessary
// permission and return a value. Do this check last, since it can throw an exception.
if (isValidPackageName(packageName, userId)) {
- return getGameModeFromSettings(packageName, userId);
+ return getGameModeFromSettingsUnchecked(packageName, userId);
}
// Since the package name doesn't match, check the caller has the necessary permission.
checkPermission(Manifest.permission.MANAGE_GAME_MODE);
- return getGameModeFromSettings(packageName, userId);
+ return getGameModeFromSettingsUnchecked(packageName, userId);
}
/**
@@ -1021,10 +1065,34 @@ public final class GameManagerService extends IGameManagerService.Stub {
return null;
}
- final @GameMode int activeGameMode = getGameModeFromSettings(packageName, userId);
- final @GameMode int[] availableGameModes = getAvailableGameModesUnchecked(packageName);
-
- return new GameModeInfo(activeGameMode, availableGameModes);
+ final @GameMode int activeGameMode = getGameModeFromSettingsUnchecked(packageName, userId);
+ final GamePackageConfiguration config = getConfig(packageName, userId);
+ if (config != null) {
+ final @GameMode int[] optedInGameModes = config.getOptedInGameModes();
+ final @GameMode int[] availableGameModes = config.getAvailableGameModes();
+ GameModeInfo.Builder gameModeInfoBuilder = new GameModeInfo.Builder()
+ .setActiveGameMode(activeGameMode)
+ .setAvailableGameModes(availableGameModes)
+ .setOptedInGameModes(optedInGameModes)
+ .setDownscalingAllowed(config.mAllowDownscale)
+ .setFpsOverrideAllowed(config.mAllowFpsOverride);
+ for (int gameMode : availableGameModes) {
+ if (!config.willGamePerformOptimizations(gameMode)) {
+ GamePackageConfiguration.GameModeConfiguration gameModeConfig =
+ config.getGameModeConfiguration(gameMode);
+ if (gameModeConfig != null) {
+ gameModeInfoBuilder.setGameModeConfiguration(gameMode,
+ gameModeConfig.toPublicGameModeConfig());
+ }
+ }
+ }
+ return gameModeInfoBuilder.build();
+ } else {
+ return new GameModeInfo.Builder()
+ .setActiveGameMode(activeGameMode)
+ .setAvailableGameModes(getAvailableGameModesUnchecked(packageName))
+ .build();
+ }
}
/**
@@ -1037,11 +1105,11 @@ public final class GameManagerService extends IGameManagerService.Stub {
throws SecurityException {
checkPermission(Manifest.permission.MANAGE_GAME_MODE);
- if (!isPackageGame(packageName, userId)) {
- // Restrict to games only.
+ if (!isPackageGame(packageName, userId) || gameMode == GameManager.GAME_MODE_UNSUPPORTED) {
+ // Restrict to games and valid game modes only.
return;
}
-
+ int fromGameMode;
synchronized (mLock) {
userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
Binder.getCallingUid(), userId, false, true, "setGameMode",
@@ -1053,9 +1121,21 @@ public final class GameManagerService extends IGameManagerService.Stub {
return;
}
GameManagerSettings userSettings = mSettings.get(userId);
+ fromGameMode = userSettings.getGameModeLocked(packageName);
userSettings.setGameModeLocked(packageName, gameMode);
}
updateInterventions(packageName, gameMode, userId);
+ synchronized (mGameModeListenerLock) {
+ for (IGameModeListener listener : mGameModeListeners.keySet()) {
+ Binder.allowBlocking(listener.asBinder());
+ try {
+ listener.onGameModeChanged(packageName, fromGameMode, gameMode, userId);
+ } catch (RemoteException ex) {
+ Slog.w(TAG, "Cannot notify game mode change for listener added by "
+ + mGameModeListeners.get(listener));
+ }
+ }
+ }
sendUserMessage(userId, WRITE_SETTINGS, "SET_GAME_MODE", WRITE_DELAY_MILLIS);
sendUserMessage(userId, WRITE_GAME_MODE_INTERVENTION_LIST_FILE,
"SET_GAME_MODE", 0 /*delayMillis*/);
@@ -1237,6 +1317,101 @@ public final class GameManagerService extends IGameManagerService.Stub {
}
/**
+ * Updates the config for the game's {@link GameManager#GAME_MODE_CUSTOM} mode.
+ *
+ * @throws SecurityException if caller doesn't have
+ * {@link android.Manifest.permission#MANAGE_GAME_MODE}
+ * permission.
+ * @throws IllegalArgumentException if the user ID provided doesn't exist.
+ */
+ @Override
+ @RequiresPermission(Manifest.permission.MANAGE_GAME_MODE)
+ public void updateCustomGameModeConfiguration(String packageName,
+ GameModeConfiguration gameModeConfig, int userId)
+ throws SecurityException, IllegalArgumentException {
+ checkPermission(Manifest.permission.MANAGE_GAME_MODE);
+ synchronized (mLock) {
+ if (!mSettings.containsKey(userId)) {
+ throw new IllegalArgumentException("User " + userId + " wasn't started");
+ }
+ }
+ // TODO(b/243448953): add validation on gameModeConfig provided
+ // Adding game mode config override of the given package name
+ GamePackageConfiguration configOverride;
+ synchronized (mLock) {
+ if (!mSettings.containsKey(userId)) {
+ return;
+ }
+ final GameManagerSettings settings = mSettings.get(userId);
+ // look for the existing GamePackageConfiguration override
+ configOverride = settings.getConfigOverride(packageName);
+ if (configOverride == null) {
+ configOverride = new GamePackageConfiguration(packageName);
+ settings.setConfigOverride(packageName, configOverride);
+ }
+
+ }
+ GamePackageConfiguration.GameModeConfiguration internalConfig =
+ configOverride.getOrAddDefaultGameModeConfiguration(GameManager.GAME_MODE_CUSTOM);
+ internalConfig.updateFromPublicGameModeConfig(gameModeConfig);
+
+ Slog.i(TAG, "Updated custom game mode config for package: " + packageName
+ + " with FPS=" + internalConfig.getFps() + ";Scaling="
+ + internalConfig.getScaling());
+ }
+
+ /**
+ * Adds a game mode listener.
+ *
+ * @throws SecurityException if caller doesn't have
+ * {@link android.Manifest.permission#MANAGE_GAME_MODE}
+ * permission.
+ */
+ @Override
+ @RequiresPermission(Manifest.permission.MANAGE_GAME_MODE)
+ public void addGameModeListener(@NonNull IGameModeListener listener) {
+ checkPermission(Manifest.permission.MANAGE_GAME_MODE);
+ try {
+ final IBinder listenerBinder = listener.asBinder();
+ listenerBinder.linkToDeath(new DeathRecipient() {
+ @Override public void binderDied() {
+ // TODO(b/258851194): add traces on binder death based listener removal
+ removeGameModeListenerUnchecked(listener);
+ listenerBinder.unlinkToDeath(this, 0 /*flags*/);
+ }
+ }, 0 /*flags*/);
+ synchronized (mGameModeListenerLock) {
+ mGameModeListeners.put(listener, Binder.getCallingUid());
+ }
+ } catch (RemoteException ex) {
+ Slog.e(TAG,
+ "Failed to link death recipient for IGameModeListener from caller "
+ + Binder.getCallingUid() + ", abandoned its listener registration", ex);
+ }
+ }
+
+ /**
+ * Removes a game mode listener.
+ *
+ * @throws SecurityException if caller doesn't have
+ * {@link android.Manifest.permission#MANAGE_GAME_MODE}
+ * permission.
+ */
+ @Override
+ @RequiresPermission(Manifest.permission.MANAGE_GAME_MODE)
+ public void removeGameModeListener(@NonNull IGameModeListener listener) {
+ // TODO(b/258851194): add traces on manual listener removal
+ checkPermission(Manifest.permission.MANAGE_GAME_MODE);
+ removeGameModeListenerUnchecked(listener);
+ }
+
+ private void removeGameModeListenerUnchecked(IGameModeListener listener) {
+ synchronized (mGameModeListenerLock) {
+ mGameModeListeners.remove(listener);
+ }
+ }
+
+ /**
* Notified when boot is completed.
*/
@VisibleForTesting
@@ -1376,7 +1551,8 @@ public final class GameManagerService extends IGameManagerService.Stub {
final GamePackageConfiguration packageConfig = getConfig(packageName, userId);
if (gameMode == GameManager.GAME_MODE_STANDARD
|| gameMode == GameManager.GAME_MODE_UNSUPPORTED || packageConfig == null
- || packageConfig.willGamePerformOptimizations(gameMode)) {
+ || packageConfig.willGamePerformOptimizations(gameMode)
+ || packageConfig.getGameModeConfiguration(gameMode) == null) {
resetFps(packageName, userId);
// resolution scaling does not need to be reset as it's now read dynamically on game
// restart, see #getResolutionScalingFactor and CompatModePackages#getCompatScale.
@@ -1464,13 +1640,9 @@ public final class GameManagerService extends IGameManagerService.Stub {
if (!bitFieldContainsModeBitmask(modesBitfield, gameModeToReset)) {
return;
}
- // if the game mode to reset is the only mode other than standard mode or there
- // is device config, the entire package config override is removed.
- if (Integer.bitCount(modesBitfield) <= 2 || deviceConfig == null) {
+ configOverride.removeModeConfig(gameModeToReset);
+ if (!configOverride.hasActiveGameModeConfig()) {
settings.removeConfigOverride(packageName);
- } else {
- // otherwise we reset the mode by removing the game mode config override
- configOverride.removeModeConfig(gameModeToReset);
}
} else {
settings.removeConfigOverride(packageName);
@@ -1498,20 +1670,12 @@ public final class GameManagerService extends IGameManagerService.Stub {
// want to check if we support selectable game modes
modesBitfield &= ~modeToBitmask(GameManager.GAME_MODE_UNSUPPORTED);
if (!bitFieldContainsModeBitmask(modesBitfield, gameMode)) {
- if (bitFieldContainsModeBitmask(modesBitfield,
- GameManager.GAME_MODE_STANDARD)) {
- // If the current set mode isn't supported,
- // but we support STANDARD, then set the mode to STANDARD.
- newGameMode = GameManager.GAME_MODE_STANDARD;
- } else {
- // If we don't support any game modes, then set to UNSUPPORTED
- newGameMode = GameManager.GAME_MODE_UNSUPPORTED;
- }
+ // always default to STANDARD if there is no mode config
+ newGameMode = GameManager.GAME_MODE_STANDARD;
}
- } else if (gameMode != GameManager.GAME_MODE_UNSUPPORTED) {
- // If we have no config for the package, but the configured mode is not
- // UNSUPPORTED, then set to UNSUPPORTED
- newGameMode = GameManager.GAME_MODE_UNSUPPORTED;
+ } else {
+ // always default to STANDARD if there is no package config
+ newGameMode = GameManager.GAME_MODE_STANDARD;
}
return newGameMode;
}
diff --git a/services/core/java/com/android/server/app/GameManagerSettings.java b/services/core/java/com/android/server/app/GameManagerSettings.java
index 1e688371fa4d..638bc4e7a070 100644
--- a/services/core/java/com/android/server/app/GameManagerSettings.java
+++ b/services/core/java/com/android/server/app/GameManagerSettings.java
@@ -90,9 +90,14 @@ public class GameManagerSettings {
*/
int getGameModeLocked(String packageName) {
if (mGameModes.containsKey(packageName)) {
- return mGameModes.get(packageName);
+ final int gameMode = mGameModes.get(packageName);
+ if (gameMode == GameManager.GAME_MODE_UNSUPPORTED) {
+ // force replace cached UNSUPPORTED mode with STANDARD starting in U
+ return GameManager.GAME_MODE_STANDARD;
+ }
+ return gameMode;
}
- return GameManager.GAME_MODE_UNSUPPORTED;
+ return GameManager.GAME_MODE_STANDARD;
}
/**
@@ -255,7 +260,7 @@ public class GameManagerSettings {
XmlUtils.skipCurrentTag(parser);
return;
}
- int gameMode = GameManager.GAME_MODE_UNSUPPORTED;
+ int gameMode;
try {
gameMode = parser.getAttributeInt(null, ATTR_GAME_MODE);
} catch (XmlPullParserException e) {
@@ -282,7 +287,7 @@ public class GameManagerSettings {
+ type);
}
}
- if (config.getAvailableGameModes().length > 1) {
+ if (config.hasActiveGameModeConfig()) {
mConfigOverrides.put(name, config);
}
}
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 4fda2336403a..3cf53ef73d0f 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -3750,6 +3750,9 @@ public class AudioService extends IAudioService.Stub
throw new IllegalArgumentException("changing device volume requires a volume index");
}
+ AudioService.sVolumeLogger.enqueueAndLog("setDeviceVolume" + " from:" + callingPackage
+ + " " + vi + " " + ada, EventLogger.Event.ALOGI, TAG);
+
if (vi.getMinVolumeIndex() == VolumeInfo.INDEX_NOT_SET
|| vi.getMaxVolumeIndex() == VolumeInfo.INDEX_NOT_SET) {
// assume index meant to be in stream type range, validate
@@ -7882,6 +7885,7 @@ public class AudioService extends IAudioService.Stub
boolean hasModifyAudioSettings) {
boolean changed;
int oldIndex;
+ final boolean isCurrentDevice;
synchronized (mSettingsLock) {
synchronized (VolumeStreamState.class) {
oldIndex = getIndex(device);
@@ -7897,7 +7901,7 @@ public class AudioService extends IAudioService.Stub
// - there is no volume index stored for this device on alias stream.
// If changing volume of current device, also change volume of current
// device on aliased stream
- final boolean isCurrentDevice = (device == getDeviceForStream(mStreamType));
+ isCurrentDevice = (device == getDeviceForStream(mStreamType));
final int numStreamTypes = AudioSystem.getNumStreamTypes();
for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
final VolumeStreamState aliasStreamState = mStreamStates[streamType];
@@ -7937,8 +7941,9 @@ public class AudioService extends IAudioService.Stub
EventLogTags.writeVolumeChanged(mStreamType, oldIndex, index, mIndexMax / 10,
caller);
}
- // fire changed intents for all streams
- if (index != oldIndex) {
+ // fire changed intents for all streams, but only when the device it changed on
+ // is the current device
+ if ((index != oldIndex) && isCurrentDevice) {
mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, index);
mVolumeChanged.putExtra(AudioManager.EXTRA_PREV_VOLUME_STREAM_VALUE, oldIndex);
mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE_ALIAS,
diff --git a/services/core/java/com/android/server/broadcastradio/RadioServiceUserController.java b/services/core/java/com/android/server/broadcastradio/RadioServiceUserController.java
new file mode 100644
index 000000000000..38b323395329
--- /dev/null
+++ b/services/core/java/com/android/server/broadcastradio/RadioServiceUserController.java
@@ -0,0 +1,56 @@
+/**
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.broadcastradio;
+
+import android.app.ActivityManager;
+import android.os.Binder;
+import android.os.UserHandle;
+
+/**
+ * Controller to handle users in {@link com.android.server.broadcastradio.BroadcastRadioService}
+ */
+public final class RadioServiceUserController {
+
+ private RadioServiceUserController() {
+ throw new UnsupportedOperationException(
+ "RadioServiceUserController class is noninstantiable");
+ }
+
+ /**
+ * Check if the user calling the method in Broadcast Radio Service is the current user or the
+ * system user.
+ *
+ * @return {@code true} if the user calling this method is the current user of system user,
+ * {@code false} otherwise.
+ */
+ public static boolean isCurrentOrSystemUser() {
+ int callingUser = Binder.getCallingUserHandle().getIdentifier();
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ int currentUser = ActivityManager.getCurrentUser();
+ if (callingUser != currentUser && callingUser != UserHandle.USER_SYSTEM) {
+ return false;
+ }
+ return true;
+ } catch (RuntimeException e) {
+ // Activity manager not running, nothing we can do assume user 0.
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ return false;
+ }
+}
diff --git a/services/core/java/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImpl.java b/services/core/java/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImpl.java
index 4fcfea2d0e07..1d7112133b48 100644
--- a/services/core/java/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImpl.java
+++ b/services/core/java/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImpl.java
@@ -34,6 +34,7 @@ import android.util.Log;
import android.util.SparseArray;
import com.android.internal.annotations.GuardedBy;
+import com.android.server.broadcastradio.RadioServiceUserController;
import com.android.server.utils.Slogf;
import java.util.ArrayList;
@@ -149,8 +150,7 @@ public final class BroadcastRadioServiceImpl {
public BroadcastRadioServiceImpl(ArrayList<String> serviceNameList) {
mNextModuleId = 0;
if (DEBUG) {
- Slogf.d(TAG, "Initializing BroadcastRadioServiceImpl %s",
- IBroadcastRadio.DESCRIPTOR);
+ Slogf.d(TAG, "Initializing BroadcastRadioServiceImpl %s", IBroadcastRadio.DESCRIPTOR);
}
for (int i = 0; i < serviceNameList.size(); i++) {
try {
@@ -203,6 +203,10 @@ public final class BroadcastRadioServiceImpl {
if (DEBUG) {
Slogf.d(TAG, "Open AIDL radio session");
}
+ if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ Slogf.e(TAG, "Cannot open tuner on AIDL HAL client for non-current user");
+ throw new IllegalStateException("Cannot open session for non-current user");
+ }
Objects.requireNonNull(callback);
if (!withAudio) {
diff --git a/services/core/java/com/android/server/broadcastradio/aidl/RadioModule.java b/services/core/java/com/android/server/broadcastradio/aidl/RadioModule.java
index d4c7242f71a9..eb9dafbe5281 100644
--- a/services/core/java/com/android/server/broadcastradio/aidl/RadioModule.java
+++ b/services/core/java/com/android/server/broadcastradio/aidl/RadioModule.java
@@ -175,7 +175,7 @@ final class RadioModule {
}
@Nullable
- public static RadioModule tryLoadingModule(int moduleId, String moduleName,
+ static RadioModule tryLoadingModule(int moduleId, String moduleName,
IBinder serviceBinder, Object lock) {
try {
Slogf.i(TAG, "Try loading module for module id = %d, module name = %s",
@@ -213,11 +213,11 @@ final class RadioModule {
}
}
- public IBroadcastRadio getService() {
+ IBroadcastRadio getService() {
return mService;
}
- public RadioManager.ModuleProperties getProperties() {
+ RadioManager.ModuleProperties getProperties() {
return mProperties;
}
@@ -227,7 +227,7 @@ final class RadioModule {
}
}
- public TunerSession openSession(android.hardware.radio.ITunerCallback userCb)
+ TunerSession openSession(android.hardware.radio.ITunerCallback userCb)
throws RemoteException {
mLogger.logRadioEvent("Open TunerSession");
TunerSession tunerSession;
@@ -252,7 +252,7 @@ final class RadioModule {
return tunerSession;
}
- public void closeSessions(int error) {
+ void closeSessions(int error) {
mLogger.logRadioEvent("Close TunerSessions %d", error);
// TunerSession.close() must be called without mAidlTunerSessions locked because
// it can call onTunerSessionClosed(). Therefore, the contents of mAidlTunerSessions
@@ -275,8 +275,7 @@ final class RadioModule {
@GuardedBy("mLock")
@Nullable
- private android.hardware.radio.ProgramList.Filter
- buildUnionOfTunerSessionFiltersLocked() {
+ private android.hardware.radio.ProgramList.Filter buildUnionOfTunerSessionFiltersLocked() {
Set<Integer> idTypes = null;
Set<android.hardware.radio.ProgramSelector.Identifier> ids = null;
boolean includeCategories = false;
@@ -423,7 +422,7 @@ final class RadioModule {
}
}
- public android.hardware.radio.ICloseHandle addAnnouncementListener(
+ android.hardware.radio.ICloseHandle addAnnouncementListener(
android.hardware.radio.IAnnouncementListener listener,
int[] enabledTypes) throws RemoteException {
mLogger.logRadioEvent("Add AnnouncementListener");
diff --git a/services/core/java/com/android/server/broadcastradio/aidl/TunerSession.java b/services/core/java/com/android/server/broadcastradio/aidl/TunerSession.java
index 7c26a8741a03..d33633c435b1 100644
--- a/services/core/java/com/android/server/broadcastradio/aidl/TunerSession.java
+++ b/services/core/java/com/android/server/broadcastradio/aidl/TunerSession.java
@@ -26,10 +26,12 @@ import android.hardware.radio.ProgramList;
import android.hardware.radio.ProgramSelector;
import android.hardware.radio.RadioManager;
import android.os.RemoteException;
+import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.IndentingPrintWriter;
import com.android.internal.annotations.GuardedBy;
+import com.android.server.broadcastradio.RadioServiceUserController;
import com.android.server.utils.Slogf;
import java.util.List;
@@ -70,7 +72,7 @@ final class TunerSession extends ITuner.Stub {
@Override
public void close() {
- mLogger.logRadioEvent("Close tuner session");
+ mLogger.logRadioEvent("Close tuner");
close(null);
}
@@ -118,6 +120,10 @@ final class TunerSession extends ITuner.Stub {
@Override
public void setConfiguration(RadioManager.BandConfig config) {
+ if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ Slogf.w(TAG, "Cannot set configuration for AIDL HAL client from non-current user");
+ return;
+ }
synchronized (mLock) {
checkNotClosedLocked();
mPlaceHolderConfig = Objects.requireNonNull(config, "config cannot be null");
@@ -157,6 +163,10 @@ final class TunerSession extends ITuner.Stub {
public void step(boolean directionDown, boolean skipSubChannel) throws RemoteException {
mLogger.logRadioEvent("Step with direction %s, skipSubChannel? %s",
directionDown ? "down" : "up", skipSubChannel ? "yes" : "no");
+ if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ Slogf.w(TAG, "Cannot step on AIDL HAL client from non-current user");
+ return;
+ }
synchronized (mLock) {
checkNotClosedLocked();
try {
@@ -171,6 +181,10 @@ final class TunerSession extends ITuner.Stub {
public void scan(boolean directionDown, boolean skipSubChannel) throws RemoteException {
mLogger.logRadioEvent("Scan with direction %s, skipSubChannel? %s",
directionDown ? "down" : "up", skipSubChannel ? "yes" : "no");
+ if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ Slogf.w(TAG, "Cannot scan on AIDL HAL client from non-current user");
+ return;
+ }
synchronized (mLock) {
checkNotClosedLocked();
try {
@@ -184,6 +198,10 @@ final class TunerSession extends ITuner.Stub {
@Override
public void tune(ProgramSelector selector) throws RemoteException {
mLogger.logRadioEvent("Tune with selector %s", selector);
+ if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ Slogf.w(TAG, "Cannot tune on AIDL HAL client from non-current user");
+ return;
+ }
synchronized (mLock) {
checkNotClosedLocked();
try {
@@ -197,6 +215,10 @@ final class TunerSession extends ITuner.Stub {
@Override
public void cancel() {
Slogf.i(TAG, "Cancel");
+ if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ Slogf.w(TAG, "Cannot cancel on AIDL HAL client from non-current user");
+ return;
+ }
synchronized (mLock) {
checkNotClosedLocked();
try {
@@ -223,6 +245,10 @@ final class TunerSession extends ITuner.Stub {
@Override
public boolean startBackgroundScan() {
Slogf.i(TAG, "Explicit background scan trigger is not supported with HAL AIDL");
+ if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ Slogf.w(TAG, "Cannot start background scan on AIDL HAL client from non-current user");
+ return false;
+ }
mModule.fanoutAidlCallback(ITunerCallback::onBackgroundScanComplete);
return true;
}
@@ -230,6 +256,11 @@ final class TunerSession extends ITuner.Stub {
@Override
public void startProgramListUpdates(ProgramList.Filter filter) throws RemoteException {
mLogger.logRadioEvent("Start programList updates %s", filter);
+ if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ Slogf.w(TAG,
+ "Cannot start program list updates on AIDL HAL client from non-current user");
+ return;
+ }
// If the AIDL client provides a null filter, it wants all updates, so use the most broad
// filter.
if (filter == null) {
@@ -291,6 +322,11 @@ final class TunerSession extends ITuner.Stub {
@Override
public void stopProgramListUpdates() throws RemoteException {
mLogger.logRadioEvent("Stop programList updates");
+ if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ Slogf.w(TAG,
+ "Cannot stop program list updates on AIDL HAL client from non-current user");
+ return;
+ }
synchronized (mLock) {
checkNotClosedLocked();
mProgramInfoCache = null;
@@ -331,6 +367,10 @@ final class TunerSession extends ITuner.Stub {
public void setConfigFlag(int flag, boolean value) throws RemoteException {
mLogger.logRadioEvent("set ConfigFlag %s to %b ",
ConfigFlag.$.toString(flag), value);
+ if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ Slogf.w(TAG, "Cannot set config flag for AIDL HAL client from non-current user");
+ return;
+ }
synchronized (mLock) {
checkNotClosedLocked();
try {
@@ -344,6 +384,10 @@ final class TunerSession extends ITuner.Stub {
@Override
public Map<String, String> setParameters(Map<String, String> parameters) {
mLogger.logRadioEvent("Set parameters ");
+ if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ Slogf.w(TAG, "Cannot set parameters for AIDL HAL client from non-current user");
+ return new ArrayMap<>();
+ }
synchronized (mLock) {
checkNotClosedLocked();
try {
diff --git a/services/core/java/com/android/server/broadcastradio/hal1/BroadcastRadioService.java b/services/core/java/com/android/server/broadcastradio/hal1/BroadcastRadioService.java
index 5da60328cd70..e50c6e8c21b8 100644
--- a/services/core/java/com/android/server/broadcastradio/hal1/BroadcastRadioService.java
+++ b/services/core/java/com/android/server/broadcastradio/hal1/BroadcastRadioService.java
@@ -21,10 +21,16 @@ import android.hardware.radio.ITuner;
import android.hardware.radio.ITunerCallback;
import android.hardware.radio.RadioManager;
+import com.android.server.broadcastradio.RadioServiceUserController;
+import com.android.server.utils.Slogf;
+
import java.util.List;
import java.util.Objects;
public class BroadcastRadioService {
+
+ private static final String TAG = "BcRadio1Srv";
+
/**
* This field is used by native code, do not access or modify.
*/
@@ -48,7 +54,7 @@ public class BroadcastRadioService {
* Constructor. should pass
* {@code com.android.server.broadcastradio.BroadcastRadioService#mLock} for lock.
*/
- public BroadcastRadioService(@NonNull Object lock) {
+ public BroadcastRadioService(Object lock) {
mLock = lock;
}
@@ -59,7 +65,11 @@ public class BroadcastRadioService {
}
public ITuner openTuner(int moduleId, RadioManager.BandConfig bandConfig,
- boolean withAudio, @NonNull ITunerCallback callback) {
+ boolean withAudio, ITunerCallback callback) {
+ if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ Slogf.e(TAG, "Cannot open tuner on HAL 1.x client for non-current user");
+ throw new IllegalStateException("Cannot open tuner for non-current user");
+ }
synchronized (mLock) {
return nativeOpenTuner(mNativeContext, moduleId, bandConfig, withAudio, callback);
}
diff --git a/services/core/java/com/android/server/broadcastradio/hal1/Convert.java b/services/core/java/com/android/server/broadcastradio/hal1/Convert.java
index 80c776254d98..219ee4c3229a 100644
--- a/services/core/java/com/android/server/broadcastradio/hal1/Convert.java
+++ b/services/core/java/com/android/server/broadcastradio/hal1/Convert.java
@@ -24,7 +24,8 @@ import java.util.Map;
import java.util.Set;
class Convert {
- private static final String TAG = "BroadcastRadioService.Convert";
+
+ private static final String TAG = "BcRadio1Srv.Convert";
/**
* Converts string map to an array that's easily accessible by native code.
diff --git a/services/core/java/com/android/server/broadcastradio/hal1/Tuner.java b/services/core/java/com/android/server/broadcastradio/hal1/Tuner.java
index e7118ad72bf4..ed8a37aab14a 100644
--- a/services/core/java/com/android/server/broadcastradio/hal1/Tuner.java
+++ b/services/core/java/com/android/server/broadcastradio/hal1/Tuner.java
@@ -28,11 +28,15 @@ import android.os.IBinder;
import android.os.RemoteException;
import android.util.Slog;
+import com.android.server.broadcastradio.RadioServiceUserController;
+import com.android.server.utils.Slogf;
+
import java.util.List;
import java.util.Map;
class Tuner extends ITuner.Stub {
- private static final String TAG = "BroadcastRadioService.Tuner";
+
+ private static final String TAG = "BcRadio1Srv.Tuner";
/**
* This field is used by native code, do not access or modify.
@@ -124,6 +128,10 @@ class Tuner extends ITuner.Stub {
@Override
public void setConfiguration(RadioManager.BandConfig config) {
+ if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ Slogf.w(TAG, "Cannot set configuration for HAL 1.x client from non-current user");
+ return;
+ }
if (config == null) {
throw new IllegalArgumentException("The argument must not be a null pointer");
}
@@ -169,6 +177,10 @@ class Tuner extends ITuner.Stub {
@Override
public void step(boolean directionDown, boolean skipSubChannel) {
+ if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ Slogf.w(TAG, "Cannot step on HAL 1.x client from non-current user");
+ return;
+ }
synchronized (mLock) {
checkNotClosedLocked();
if (!checkConfiguredLocked()) return;
@@ -178,6 +190,10 @@ class Tuner extends ITuner.Stub {
@Override
public void scan(boolean directionDown, boolean skipSubChannel) {
+ if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ Slogf.w(TAG, "Cannot scan on HAL 1.x client from non-current user");
+ return;
+ }
synchronized (mLock) {
checkNotClosedLocked();
if (!checkConfiguredLocked()) return;
@@ -187,6 +203,10 @@ class Tuner extends ITuner.Stub {
@Override
public void tune(ProgramSelector selector) {
+ if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ Slogf.w(TAG, "Cannot tune on HAL 1.x client from non-current user");
+ return;
+ }
if (selector == null) {
throw new IllegalArgumentException("The argument must not be a null pointer");
}
@@ -200,6 +220,10 @@ class Tuner extends ITuner.Stub {
@Override
public void cancel() {
+ if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ Slogf.w(TAG, "Cannot cancel on HAL 1.x client from non-current user");
+ return;
+ }
synchronized (mLock) {
checkNotClosedLocked();
nativeCancel(mNativeContext);
@@ -208,6 +232,10 @@ class Tuner extends ITuner.Stub {
@Override
public void cancelAnnouncement() {
+ if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ Slogf.w(TAG, "Cannot cancel announcement on HAL 1.x client from non-current user");
+ return;
+ }
synchronized (mLock) {
checkNotClosedLocked();
nativeCancelAnnouncement(mNativeContext);
@@ -233,6 +261,11 @@ class Tuner extends ITuner.Stub {
@Override
public boolean startBackgroundScan() {
+ if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ Slogf.w(TAG,
+ "Cannot start background scan on HAL 1.x client from non-current user");
+ return false;
+ }
synchronized (mLock) {
checkNotClosedLocked();
return nativeStartBackgroundScan(mNativeContext);
@@ -253,11 +286,21 @@ class Tuner extends ITuner.Stub {
@Override
public void startProgramListUpdates(ProgramList.Filter filter) {
+ if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ Slogf.w(TAG,
+ "Cannot start program list updates on HAL 1.x client from non-current user");
+ return;
+ }
mTunerCallback.startProgramListUpdates(filter);
}
@Override
public void stopProgramListUpdates() {
+ if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ Slogf.w(TAG,
+ "Cannot stop program list updates on HAL 1.x client from non-current user");
+ return;
+ }
mTunerCallback.stopProgramListUpdates();
}
@@ -279,6 +322,10 @@ class Tuner extends ITuner.Stub {
@Override
public void setConfigFlag(int flag, boolean value) {
+ if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ Slogf.w(TAG, "Cannot set config flag for HAL 1.x client from non-current user");
+ return;
+ }
if (flag == RadioManager.CONFIG_FORCE_ANALOG) {
synchronized (mLock) {
checkNotClosedLocked();
diff --git a/services/core/java/com/android/server/broadcastradio/hal1/TunerCallback.java b/services/core/java/com/android/server/broadcastradio/hal1/TunerCallback.java
index 867d5b4b6f49..0cc3833896be 100644
--- a/services/core/java/com/android/server/broadcastradio/hal1/TunerCallback.java
+++ b/services/core/java/com/android/server/broadcastradio/hal1/TunerCallback.java
@@ -34,7 +34,8 @@ import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
class TunerCallback implements ITunerCallback {
- private static final String TAG = "BroadcastRadioService.TunerCallback";
+
+ private static final String TAG = "BcRadio1Srv.TunerCallback";
/**
* This field is used by native code, do not access or modify.
diff --git a/services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java b/services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java
index 4c3760928df3..3d6962783f4a 100644
--- a/services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java
+++ b/services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java
@@ -34,6 +34,8 @@ import android.util.Slog;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.broadcastradio.RadioServiceUserController;
+import com.android.server.utils.Slogf;
import java.util.Collection;
import java.util.HashMap;
@@ -168,6 +170,10 @@ public class BroadcastRadioService {
public ITuner openSession(int moduleId, @Nullable RadioManager.BandConfig legacyConfig,
boolean withAudio, @NonNull ITunerCallback callback) throws RemoteException {
Slog.v(TAG, "Open HIDL 2.0 session with module id " + moduleId);
+ if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ Slogf.e(TAG, "Cannot open tuner on HAL 2.0 client for non-current user");
+ throw new IllegalStateException("Cannot open session for non-current user");
+ }
Objects.requireNonNull(callback);
if (!withAudio) {
diff --git a/services/core/java/com/android/server/broadcastradio/hal2/ProgramInfoCache.java b/services/core/java/com/android/server/broadcastradio/hal2/ProgramInfoCache.java
index 6654c0c2304d..9831af6b523e 100644
--- a/services/core/java/com/android/server/broadcastradio/hal2/ProgramInfoCache.java
+++ b/services/core/java/com/android/server/broadcastradio/hal2/ProgramInfoCache.java
@@ -33,7 +33,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
-class ProgramInfoCache {
+final class ProgramInfoCache {
// Maximum number of RadioManager.ProgramInfo elements that will be put into a
// ProgramList.Chunk.mModified array. Used to try to ensure a single ProgramList.Chunk stays
// within the AIDL data size limit.
diff --git a/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java b/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java
index 5913e0685eb4..cf1b504037bc 100644
--- a/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java
+++ b/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java
@@ -53,7 +53,7 @@ import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
-class RadioModule {
+final class RadioModule {
private static final String TAG = "BcRadio2Srv.module";
private static final int RADIO_EVENT_LOGGER_QUEUE_SIZE = 25;
@@ -143,7 +143,8 @@ class RadioModule {
mEventLogger = new RadioEventLogger(TAG, RADIO_EVENT_LOGGER_QUEUE_SIZE);
}
- public static @Nullable RadioModule tryLoadingModule(int idx, @NonNull String fqName,
+ @Nullable
+ static RadioModule tryLoadingModule(int idx, @NonNull String fqName,
Object lock) {
try {
Slog.i(TAG, "Try loading module for idx " + idx + ", fqName " + fqName);
@@ -173,7 +174,8 @@ class RadioModule {
}
}
- public @NonNull IBroadcastRadio getService() {
+ @NonNull
+ IBroadcastRadio getService() {
return mService;
}
@@ -181,7 +183,7 @@ class RadioModule {
return mProperties;
}
- public @NonNull TunerSession openSession(@NonNull android.hardware.radio.ITunerCallback userCb)
+ TunerSession openSession(@NonNull android.hardware.radio.ITunerCallback userCb)
throws RemoteException {
mEventLogger.logRadioEvent("Open TunerSession");
synchronized (mLock) {
@@ -211,7 +213,7 @@ class RadioModule {
}
}
- public void closeSessions(Integer error) {
+ void closeSessions(Integer error) {
// Copy the contents of mAidlTunerSessions into a local array because TunerSession.close()
// must be called without mAidlTunerSessions locked because it can call
// onTunerSessionClosed().
@@ -227,7 +229,8 @@ class RadioModule {
}
}
- private @Nullable android.hardware.radio.ProgramList.Filter
+ @Nullable
+ private android.hardware.radio.ProgramList.Filter
buildUnionOfTunerSessionFiltersLocked() {
Set<Integer> idTypes = null;
Set<android.hardware.radio.ProgramSelector.Identifier> ids = null;
@@ -378,8 +381,8 @@ class RadioModule {
}
}
- public android.hardware.radio.ICloseHandle addAnnouncementListener(@NonNull int[] enabledTypes,
- @NonNull android.hardware.radio.IAnnouncementListener listener) throws RemoteException {
+ android.hardware.radio.ICloseHandle addAnnouncementListener(int[] enabledTypes,
+ android.hardware.radio.IAnnouncementListener listener) throws RemoteException {
mEventLogger.logRadioEvent("Add AnnouncementListener");
ArrayList<Byte> enabledList = new ArrayList<>();
for (int type : enabledTypes) {
diff --git a/services/core/java/com/android/server/broadcastradio/hal2/TunerSession.java b/services/core/java/com/android/server/broadcastradio/hal2/TunerSession.java
index 918dc98e3a9e..12211eed47fd 100644
--- a/services/core/java/com/android/server/broadcastradio/hal2/TunerSession.java
+++ b/services/core/java/com/android/server/broadcastradio/hal2/TunerSession.java
@@ -27,11 +27,15 @@ import android.hardware.radio.ProgramList;
import android.hardware.radio.ProgramSelector;
import android.hardware.radio.RadioManager;
import android.os.RemoteException;
+import android.util.ArrayMap;
import android.util.IndentingPrintWriter;
import android.util.MutableBoolean;
import android.util.MutableInt;
import android.util.Slog;
+import com.android.server.broadcastradio.RadioServiceUserController;
+import com.android.server.utils.Slogf;
+
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -107,6 +111,10 @@ class TunerSession extends ITuner.Stub {
@Override
public void setConfiguration(RadioManager.BandConfig config) {
+ if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ Slogf.w(TAG, "Cannot set configuration for HAL 2.0 client from non-current user");
+ return;
+ }
synchronized (mLock) {
checkNotClosedLocked();
mDummyConfig = Objects.requireNonNull(config);
@@ -145,6 +153,10 @@ class TunerSession extends ITuner.Stub {
public void step(boolean directionDown, boolean skipSubChannel) throws RemoteException {
mEventLogger.logRadioEvent("Step with direction %s, skipSubChannel? %s",
directionDown ? "down" : "up", skipSubChannel ? "yes" : "no");
+ if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ Slogf.w(TAG, "Cannot step on HAL 2.0 client from non-current user");
+ return;
+ }
synchronized (mLock) {
checkNotClosedLocked();
int halResult = mHwSession.step(!directionDown);
@@ -156,6 +168,10 @@ class TunerSession extends ITuner.Stub {
public void scan(boolean directionDown, boolean skipSubChannel) throws RemoteException {
mEventLogger.logRadioEvent("Scan with direction %s, skipSubChannel? %s",
directionDown ? "down" : "up", skipSubChannel ? "yes" : "no");
+ if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ Slogf.w(TAG, "Cannot scan on HAL 2.0 client from non-current user");
+ return;
+ }
synchronized (mLock) {
checkNotClosedLocked();
int halResult = mHwSession.scan(!directionDown, skipSubChannel);
@@ -166,6 +182,10 @@ class TunerSession extends ITuner.Stub {
@Override
public void tune(ProgramSelector selector) throws RemoteException {
mEventLogger.logRadioEvent("Tune with selector %s", selector);
+ if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ Slogf.w(TAG, "Cannot tune on HAL 2.0 client from non-current user");
+ return;
+ }
synchronized (mLock) {
checkNotClosedLocked();
int halResult = mHwSession.tune(Convert.programSelectorToHal(selector));
@@ -176,6 +196,10 @@ class TunerSession extends ITuner.Stub {
@Override
public void cancel() {
Slog.i(TAG, "Cancel");
+ if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ Slogf.w(TAG, "Cannot cancel on HAL 2.0 client from non-current user");
+ return;
+ }
synchronized (mLock) {
checkNotClosedLocked();
Utils.maybeRethrow(mHwSession::cancel);
@@ -196,6 +220,11 @@ class TunerSession extends ITuner.Stub {
@Override
public boolean startBackgroundScan() {
Slog.i(TAG, "Explicit background scan trigger is not supported with HAL 2.0");
+ if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ Slogf.w(TAG,
+ "Cannot start background scan on HAL 2.0 client from non-current user");
+ return false;
+ }
mModule.fanoutAidlCallback(cb -> cb.onBackgroundScanComplete());
return true;
}
@@ -203,6 +232,11 @@ class TunerSession extends ITuner.Stub {
@Override
public void startProgramListUpdates(ProgramList.Filter filter) throws RemoteException {
mEventLogger.logRadioEvent("start programList updates %s", filter);
+ if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ Slogf.w(TAG,
+ "Cannot start program list updates on HAL 2.0 client from non-current user");
+ return;
+ }
// If the AIDL client provides a null filter, it wants all updates, so use the most broad
// filter.
if (filter == null) {
@@ -262,6 +296,11 @@ class TunerSession extends ITuner.Stub {
@Override
public void stopProgramListUpdates() throws RemoteException {
mEventLogger.logRadioEvent("Stop programList updates");
+ if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ Slogf.w(TAG,
+ "Cannot stop program list updates on HAL 2.0 client from non-current user");
+ return;
+ }
synchronized (mLock) {
checkNotClosedLocked();
mProgramInfoCache = null;
@@ -308,6 +347,10 @@ class TunerSession extends ITuner.Stub {
@Override
public void setConfigFlag(int flag, boolean value) throws RemoteException {
mEventLogger.logRadioEvent("Set ConfigFlag %s = %b", ConfigFlag.toString(flag), value);
+ if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ Slogf.w(TAG, "Cannot set config flag for HAL 2.0 client from non-current user");
+ return;
+ }
synchronized (mLock) {
checkNotClosedLocked();
int halResult = mHwSession.setConfigFlag(flag, value);
@@ -317,6 +360,10 @@ class TunerSession extends ITuner.Stub {
@Override
public Map<String, String> setParameters(Map<String, String> parameters) {
+ if (!RadioServiceUserController.isCurrentOrSystemUser()) {
+ Slogf.w(TAG, "Cannot set parameters for HAL 2.0 client from non-current user");
+ return new ArrayMap<>();
+ }
synchronized (mLock) {
checkNotClosedLocked();
return Convert.vendorInfoFromHal(Utils.maybeRethrow(
diff --git a/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java b/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java
index 925fc21737e5..c856cabdc967 100644
--- a/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java
+++ b/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java
@@ -17,10 +17,7 @@
package com.android.server.devicestate;
import static android.Manifest.permission.CONTROL_DEVICE_STATE;
-import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
-import static android.hardware.devicestate.DeviceStateManager.ACTION_SHOW_REAR_DISPLAY_OVERLAY;
-import static android.hardware.devicestate.DeviceStateManager.EXTRA_ORIGINAL_DEVICE_BASE_STATE;
import static android.hardware.devicestate.DeviceStateManager.INVALID_DEVICE_STATE;
import static android.hardware.devicestate.DeviceStateManager.MAXIMUM_DEVICE_STATE;
import static android.hardware.devicestate.DeviceStateManager.MINIMUM_DEVICE_STATE;
@@ -36,10 +33,7 @@ import android.annotation.IntDef;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.app.ActivityOptions;
-import android.app.WindowConfiguration;
import android.content.Context;
-import android.content.Intent;
import android.hardware.devicestate.DeviceStateInfo;
import android.hardware.devicestate.DeviceStateManager;
import android.hardware.devicestate.DeviceStateManagerInternal;
@@ -64,6 +58,7 @@ import com.android.internal.util.FrameworkStatsLog;
import com.android.server.DisplayThread;
import com.android.server.LocalServices;
import com.android.server.SystemService;
+import com.android.server.statusbar.StatusBarManagerInternal;
import com.android.server.wm.ActivityTaskManagerInternal;
import com.android.server.wm.WindowProcessController;
@@ -731,19 +726,18 @@ public final class DeviceStateManagerService extends SystemService {
/**
* If we get a request to enter rear display mode, we need to display an educational
- * overlay to let the user know what will happen. This creates the pending request and then
- * launches the {@link RearDisplayEducationActivity}
+ * overlay to let the user know what will happen. This calls into the
+ * {@link StatusBarManagerInternal} to notify SystemUI to display the educational dialog.
*/
@GuardedBy("mLock")
private void showRearDisplayEducationalOverlayLocked(OverrideRequest request) {
mRearDisplayPendingOverrideRequest = request;
- Intent intent = new Intent(ACTION_SHOW_REAR_DISPLAY_OVERLAY);
- intent.setFlags(FLAG_ACTIVITY_NEW_TASK);
- intent.putExtra(EXTRA_ORIGINAL_DEVICE_BASE_STATE, mBaseState.get().getIdentifier());
- final ActivityOptions options = ActivityOptions.makeBasic();
- options.setLaunchWindowingMode(WindowConfiguration.WINDOWING_MODE_FULLSCREEN);
- getUiContext().startActivity(intent, options.toBundle());
+ StatusBarManagerInternal statusBar =
+ LocalServices.getService(StatusBarManagerInternal.class);
+ if (statusBar != null) {
+ statusBar.showRearDisplayDialog(mBaseState.get().getIdentifier());
+ }
}
private void cancelStateRequestInternal(int callingPid) {
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 78b697d13f7b..05cd67f2f808 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -58,6 +58,7 @@ import android.content.res.TypedArray;
import android.database.ContentObserver;
import android.graphics.ColorSpace;
import android.graphics.Point;
+import android.hardware.OverlayProperties;
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.hardware.devicestate.DeviceStateManager;
@@ -411,6 +412,7 @@ public final class DisplayManagerService extends SystemService {
private final Curve mMinimumBrightnessCurve;
private final Spline mMinimumBrightnessSpline;
private final ColorSpace mWideColorSpace;
+ private final OverlayProperties mOverlayProperties;
private SensorManager mSensorManager;
private BrightnessTracker mBrightnessTracker;
@@ -503,6 +505,7 @@ public final class DisplayManagerService extends SystemService {
mCurrentUserId = UserHandle.USER_SYSTEM;
ColorSpace[] colorSpaces = SurfaceControl.getCompositionColorSpaces();
mWideColorSpace = colorSpaces[1];
+ mOverlayProperties = SurfaceControl.getOverlaySupport();
mAllowNonNativeRefreshRateOverride = mInjector.getAllowNonNativeRefreshRateOverride();
mSystemReady = false;
}
@@ -1785,6 +1788,10 @@ public final class DisplayManagerService extends SystemService {
return mWideColorSpace.getId();
}
+ OverlayProperties getOverlaySupportInternal() {
+ return mOverlayProperties;
+ }
+
void setUserPreferredDisplayModeInternal(int displayId, Display.Mode mode) {
synchronized (mSyncRoot) {
if (mode != null && !isResolutionAndRefreshRateValid(mode)
@@ -2644,7 +2651,7 @@ public final class DisplayManagerService extends SystemService {
final DisplayPowerControllerInterface displayPowerController;
if (DeviceConfig.getBoolean("display_manager",
- "use_newly_structured_display_power_controller", false)) {
+ "use_newly_structured_display_power_controller", true)) {
displayPowerController = new DisplayPowerController2(
mContext, /* injector= */ null, mDisplayPowerCallbacks, mPowerHandler,
mSensorManager, mDisplayBlanker, display, mBrightnessTracker, brightnessSetting,
@@ -3597,6 +3604,16 @@ public final class DisplayManagerService extends SystemService {
}
}
}
+
+ @Override
+ public OverlayProperties getOverlaySupport() {
+ final long token = Binder.clearCallingIdentity();
+ try {
+ return getOverlaySupportInternal();
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
}
private static boolean isValidBrightness(float brightness) {
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index 8497dfb58ba6..c20d8806412d 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -273,9 +273,9 @@ public class InputManagerService extends IInputManager.Stub
// to display id (int). Currently only accessed by InputReader.
private final Map<String, Integer> mStaticAssociations;
private final Object mAssociationsLock = new Object();
- @GuardedBy("mAssociationLock")
+ @GuardedBy("mAssociationsLock")
private final Map<String, Integer> mRuntimeAssociations = new ArrayMap<>();
- @GuardedBy("mAssociationLock")
+ @GuardedBy("mAssociationsLock")
private final Map<String, String> mUniqueIdAssociations = new ArrayMap<>();
// Guards per-display input properties and properties relating to the mouse pointer.
@@ -369,7 +369,7 @@ public class InputManagerService extends IInputManager.Stub
/** Switch code: Camera lens cover. When set the lens is covered. */
public static final int SW_CAMERA_LENS_COVER = 0x09;
- /** Switch code: Microphone. When set it is off. */
+ /** Switch code: Microphone. When set, the mic is muted. */
public static final int SW_MUTE_DEVICE = 0x0e;
public static final int SW_LID_BIT = 1 << SW_LID;
@@ -536,14 +536,14 @@ public class InputManagerService extends IInputManager.Stub
// Set the HW mic toggle switch state
final int micMuteState = getSwitchState(-1 /* deviceId */, InputDevice.SOURCE_ANY,
SW_MUTE_DEVICE);
- if (micMuteState != InputManager.SWITCH_STATE_UNKNOWN) {
- setSensorPrivacy(Sensors.MICROPHONE, micMuteState != InputManager.SWITCH_STATE_OFF);
+ if (micMuteState == InputManager.SWITCH_STATE_ON) {
+ setSensorPrivacy(Sensors.MICROPHONE, true);
}
// Set the HW camera toggle switch state
final int cameraMuteState = getSwitchState(-1 /* deviceId */, InputDevice.SOURCE_ANY,
SW_CAMERA_LENS_COVER);
- if (cameraMuteState != InputManager.SWITCH_STATE_UNKNOWN) {
- setSensorPrivacy(Sensors.CAMERA, cameraMuteState != InputManager.SWITCH_STATE_OFF);
+ if (cameraMuteState == InputManager.SWITCH_STATE_ON) {
+ setSensorPrivacy(Sensors.CAMERA, true);
}
IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
diff --git a/services/core/java/com/android/server/media/MediaButtonReceiverHolder.java b/services/core/java/com/android/server/media/MediaButtonReceiverHolder.java
index 72ce38b72340..dcdb881df12b 100644
--- a/services/core/java/com/android/server/media/MediaButtonReceiverHolder.java
+++ b/services/core/java/com/android/server/media/MediaButtonReceiverHolder.java
@@ -275,10 +275,6 @@ final class MediaButtonReceiverHolder {
String.valueOf(mComponentType));
}
- public ComponentName getComponentName() {
- return mComponentName;
- }
-
@ComponentType
private static int getComponentType(PendingIntent pendingIntent) {
if (pendingIntent.isBroadcast()) {
diff --git a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
index f5ec880ed235..a6b7fe2a29b6 100644
--- a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
+++ b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
@@ -348,6 +348,9 @@ class MediaRouter2ServiceImpl {
@NonNull String uniqueSessionId, int volume) {
Objects.requireNonNull(router, "router must not be null");
Objects.requireNonNull(uniqueSessionId, "uniqueSessionId must not be null");
+ if (TextUtils.isEmpty(uniqueSessionId)) {
+ throw new IllegalArgumentException("uniqueSessionId must not be empty");
+ }
final long token = Binder.clearCallingIdentity();
try {
@@ -2443,10 +2446,9 @@ class MediaRouter2ServiceImpl {
List<RouterRecord> routerRecords = getRouterRecords();
List<ManagerRecord> managerRecords = getManagerRecords();
- boolean shouldBindProviders = false;
-
+ boolean isManagerScanning = false;
if (service.mPowerManager.isInteractive()) {
- boolean isManagerScanning = managerRecords.stream().anyMatch(manager ->
+ isManagerScanning = managerRecords.stream().anyMatch(manager ->
manager.mIsScanning && service.mActivityManager
.getPackageImportance(manager.mPackageName)
<= PACKAGE_IMPORTANCE_FOR_DISCOVERY);
@@ -2455,7 +2457,6 @@ class MediaRouter2ServiceImpl {
discoveryPreferences = routerRecords.stream()
.map(record -> record.mDiscoveryPreference)
.collect(Collectors.toList());
- shouldBindProviders = true;
} else {
discoveryPreferences = routerRecords.stream().filter(record ->
service.mActivityManager.getPackageImportance(record.mPackageName)
@@ -2468,7 +2469,7 @@ class MediaRouter2ServiceImpl {
for (MediaRoute2Provider provider : mRouteProviders) {
if (provider instanceof MediaRoute2ProviderServiceProxy) {
((MediaRoute2ProviderServiceProxy) provider)
- .setManagerScanning(shouldBindProviders);
+ .setManagerScanning(isManagerScanning);
}
}
@@ -2484,7 +2485,7 @@ class MediaRouter2ServiceImpl {
activeScan |= preference.shouldPerformActiveScan();
}
RouteDiscoveryPreference newPreference = new RouteDiscoveryPreference.Builder(
- List.copyOf(preferredFeatures), activeScan).build();
+ List.copyOf(preferredFeatures), activeScan || isManagerScanning).build();
synchronized (service.mLock) {
if (newPreference.equals(mUserRecord.mCompositeDiscoveryPreference)) {
diff --git a/services/core/java/com/android/server/pm/AppsFilterUtils.java b/services/core/java/com/android/server/pm/AppsFilterUtils.java
index 483fa8ade150..bf28479e7419 100644
--- a/services/core/java/com/android/server/pm/AppsFilterUtils.java
+++ b/services/core/java/com/android/server/pm/AppsFilterUtils.java
@@ -69,11 +69,11 @@ final class AppsFilterUtils {
public static boolean canQueryAsInstaller(PackageStateInternal querying,
AndroidPackage potentialTarget) {
final InstallSource installSource = querying.getInstallSource();
- if (potentialTarget.getPackageName().equals(installSource.installerPackageName)) {
+ if (potentialTarget.getPackageName().equals(installSource.mInstallerPackageName)) {
return true;
}
- if (!installSource.isInitiatingPackageUninstalled
- && potentialTarget.getPackageName().equals(installSource.initiatingPackageName)) {
+ if (!installSource.mIsInitiatingPackageUninstalled
+ && potentialTarget.getPackageName().equals(installSource.mInitiatingPackageName)) {
return true;
}
return false;
diff --git a/services/core/java/com/android/server/pm/BackgroundDexOptService.java b/services/core/java/com/android/server/pm/BackgroundDexOptService.java
index d72aacc0db74..dd4183024314 100644
--- a/services/core/java/com/android/server/pm/BackgroundDexOptService.java
+++ b/services/core/java/com/android/server/pm/BackgroundDexOptService.java
@@ -17,8 +17,11 @@
package com.android.server.pm;
import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
+import static com.android.server.pm.PackageManagerServiceCompilerMapping.getCompilerFilterForReason;
import static com.android.server.pm.dex.ArtStatsLogUtils.BackgroundDexoptJobStatsLogger;
+import static dalvik.system.DexFile.isProfileGuidedCompilerFilter;
+
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -748,10 +751,21 @@ public final class BackgroundDexOptService {
return PackageDexOptimizer.DEX_OPT_CANCELLED;
}
int reason = PackageManagerService.REASON_INACTIVE_PACKAGE_DOWNGRADE;
+ String filter = getCompilerFilterForReason(reason);
int dexoptFlags = DexoptOptions.DEXOPT_BOOT_COMPLETE | DexoptOptions.DEXOPT_DOWNGRADE;
+
+ if (isProfileGuidedCompilerFilter(filter)) {
+ // We don't expect updates in current profiles to be significant here, but
+ // DEXOPT_CHECK_FOR_PROFILES_UPDATES is set to replicate behaviour that will be
+ // unconditionally enabled for profile guided filters when ART Service is called instead
+ // of the legacy PackageDexOptimizer implementation.
+ dexoptFlags |= DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES;
+ }
+
if (!isPostBootUpdate) {
dexoptFlags |= DexoptOptions.DEXOPT_IDLE_BACKGROUND_JOB;
}
+
long package_size_before = getPackageSize(snapshot, pkg);
int result = PackageDexOptimizer.DEX_OPT_SKIPPED;
if (isForPrimaryDex || PLATFORM_PACKAGE_NAME.equals(pkg)) {
@@ -762,10 +776,10 @@ public final class BackgroundDexOptService {
// remove their compiler artifacts from dalvik cache.
pm.deleteOatArtifactsOfPackage(snapshot, pkg);
} else {
- result = performDexOptPrimary(pkg, reason, dexoptFlags);
+ result = performDexOptPrimary(pkg, reason, filter, dexoptFlags);
}
} else {
- result = performDexOptSecondary(pkg, reason, dexoptFlags);
+ result = performDexOptSecondary(pkg, reason, filter, dexoptFlags);
}
if (result == PackageDexOptimizer.DEX_OPT_PERFORMED) {
@@ -801,32 +815,42 @@ public final class BackgroundDexOptService {
private int optimizePackage(String pkg, boolean isForPrimaryDex, boolean isPostBootUpdate) {
int reason = isPostBootUpdate ? PackageManagerService.REASON_POST_BOOT
: PackageManagerService.REASON_BACKGROUND_DEXOPT;
+ String filter = getCompilerFilterForReason(reason);
+
int dexoptFlags = DexoptOptions.DEXOPT_BOOT_COMPLETE;
if (!isPostBootUpdate) {
dexoptFlags |= DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES
| DexoptOptions.DEXOPT_IDLE_BACKGROUND_JOB;
}
+ if (isProfileGuidedCompilerFilter(filter)) {
+ // Ensure DEXOPT_CHECK_FOR_PROFILES_UPDATES is enabled if the filter is profile guided,
+ // to replicate behaviour that will be unconditionally enabled when ART Service is
+ // called instead of the legacy PackageDexOptimizer implementation.
+ dexoptFlags |= DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES;
+ }
+
// System server share the same code path as primary dex files.
// PackageManagerService will select the right optimization path for it.
if (isForPrimaryDex || PLATFORM_PACKAGE_NAME.equals(pkg)) {
- return performDexOptPrimary(pkg, reason, dexoptFlags);
+ return performDexOptPrimary(pkg, reason, filter, dexoptFlags);
} else {
- return performDexOptSecondary(pkg, reason, dexoptFlags);
+ return performDexOptSecondary(pkg, reason, filter, dexoptFlags);
}
}
@DexOptResult
- private int performDexOptPrimary(String pkg, int reason, int dexoptFlags) {
- DexoptOptions dexoptOptions = new DexoptOptions(pkg, reason, dexoptFlags);
+ private int performDexOptPrimary(String pkg, int reason, String filter, int dexoptFlags) {
+ DexoptOptions dexoptOptions =
+ new DexoptOptions(pkg, reason, filter, /*splitName=*/null, dexoptFlags);
return trackPerformDexOpt(pkg, /*isForPrimaryDex=*/true,
() -> mDexOptHelper.performDexOptWithStatus(dexoptOptions));
}
@DexOptResult
- private int performDexOptSecondary(String pkg, int reason, int dexoptFlags) {
- DexoptOptions dexoptOptions = new DexoptOptions(
- pkg, reason, dexoptFlags | DexoptOptions.DEXOPT_ONLY_SECONDARY_DEX);
+ private int performDexOptSecondary(String pkg, int reason, String filter, int dexoptFlags) {
+ DexoptOptions dexoptOptions = new DexoptOptions(pkg, reason, filter, /*splitName=*/null,
+ dexoptFlags | DexoptOptions.DEXOPT_ONLY_SECONDARY_DEX);
return trackPerformDexOpt(pkg, /*isForPrimaryDex=*/false,
()
-> mDexOptHelper.performDexOpt(dexoptOptions)
diff --git a/services/core/java/com/android/server/pm/ComputerEngine.java b/services/core/java/com/android/server/pm/ComputerEngine.java
index a8534b0b497c..45b633f02e50 100644
--- a/services/core/java/com/android/server/pm/ComputerEngine.java
+++ b/services/core/java/com/android/server/pm/ComputerEngine.java
@@ -44,6 +44,7 @@ import static android.content.pm.PackageManager.TYPE_PROVIDER;
import static android.content.pm.PackageManager.TYPE_RECEIVER;
import static android.content.pm.PackageManager.TYPE_SERVICE;
import static android.content.pm.PackageManager.TYPE_UNKNOWN;
+import static android.os.Process.INVALID_UID;
import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
@@ -2576,7 +2577,7 @@ public class ComputerEngine implements Computer {
}
}
- return -1;
+ return INVALID_UID;
}
/**
@@ -4325,18 +4326,18 @@ public class ComputerEngine implements Computer {
@Override
public int getUidForSharedUser(@NonNull String sharedUserName) {
if (sharedUserName == null) {
- return Process.INVALID_UID;
+ return INVALID_UID;
}
final int callingUid = Binder.getCallingUid();
if (getInstantAppPackageName(callingUid) != null) {
- return Process.INVALID_UID;
+ return INVALID_UID;
}
final SharedUserSetting suid = mSettings.getSharedUserFromId(sharedUserName);
if (suid != null && !shouldFilterApplicationIncludingUninstalled(suid, callingUid,
UserHandle.getUserId(callingUid))) {
return suid.mAppId;
}
- return Process.INVALID_UID;
+ return INVALID_UID;
}
@Override
@@ -4918,7 +4919,7 @@ public class ComputerEngine implements Computer {
if (installSource == null) {
throw new IllegalArgumentException("Unknown package: " + packageName);
}
- String installerPackageName = installSource.installerPackageName;
+ String installerPackageName = installSource.mInstallerPackageName;
if (installerPackageName != null) {
final PackageStateInternal ps = mSettings.getPackage(installerPackageName);
if (ps == null || shouldFilterApplicationIncludingUninstalled(ps, callingUid,
@@ -4961,7 +4962,7 @@ public class ComputerEngine implements Computer {
return null;
}
- installerPackageName = installSource.installerPackageName;
+ installerPackageName = installSource.mInstallerPackageName;
if (installerPackageName != null) {
final PackageStateInternal ps = mSettings.getPackage(installerPackageName);
if (ps == null
@@ -4970,25 +4971,25 @@ public class ComputerEngine implements Computer {
}
}
- if (installSource.isInitiatingPackageUninstalled) {
+ if (installSource.mIsInitiatingPackageUninstalled) {
// We can't check visibility in the usual way, since the initiating package is no
// longer present. So we apply simpler rules to whether to expose the info:
// 1. Instant apps can't see it.
// 2. Otherwise only the installed app itself can see it.
final boolean isInstantApp = getInstantAppPackageName(callingUid) != null;
if (!isInstantApp && isCallerSameApp(packageName, callingUid)) {
- initiatingPackageName = installSource.initiatingPackageName;
+ initiatingPackageName = installSource.mInitiatingPackageName;
} else {
initiatingPackageName = null;
}
} else {
- if (Objects.equals(installSource.initiatingPackageName,
- installSource.installerPackageName)) {
+ if (Objects.equals(installSource.mInitiatingPackageName,
+ installSource.mInstallerPackageName)) {
// The installer and initiator will often be the same, and when they are
// we can skip doing the same check again.
initiatingPackageName = installerPackageName;
} else {
- initiatingPackageName = installSource.initiatingPackageName;
+ initiatingPackageName = installSource.mInitiatingPackageName;
final PackageStateInternal ps = mSettings.getPackage(initiatingPackageName);
if (ps == null
|| shouldFilterApplicationIncludingUninstalled(ps, callingUid, userId)) {
@@ -4997,7 +4998,7 @@ public class ComputerEngine implements Computer {
}
}
- originatingPackageName = installSource.originatingPackageName;
+ originatingPackageName = installSource.mOriginatingPackageName;
if (originatingPackageName != null) {
final PackageStateInternal ps = mSettings.getPackage(originatingPackageName);
if (ps == null
@@ -5017,7 +5018,7 @@ public class ComputerEngine implements Computer {
// If you can see the initiatingPackageName, and we have valid signing info for it,
// then we let you see that too.
final SigningInfo initiatingPackageSigningInfo;
- final PackageSignatures signatures = installSource.initiatingPackageSignatures;
+ final PackageSignatures signatures = installSource.mInitiatingPackageSignatures;
if (initiatingPackageName != null && signatures != null
&& signatures.mSigningDetails != SigningDetails.UNKNOWN) {
initiatingPackageSigningInfo = new SigningInfo(signatures.mSigningDetails);
@@ -5026,7 +5027,7 @@ public class ComputerEngine implements Computer {
}
return new InstallSourceInfo(initiatingPackageName, initiatingPackageSigningInfo,
- originatingPackageName, installerPackageName, installSource.packageSource);
+ originatingPackageName, installerPackageName, installSource.mPackageSource);
}
@PackageManager.EnabledState
@@ -5246,7 +5247,7 @@ public class ComputerEngine implements Computer {
final int targetAppId = UserHandle.getAppId(
getPackageUid(targetPackageName, 0 /* flags */, userId));
// For update or already installed case, leverage the existing visibility rule.
- if (targetAppId != Process.INVALID_UID) {
+ if (targetAppId != INVALID_UID) {
final Object targetSetting = mSettings.getSettingBase(targetAppId);
if (targetSetting instanceof PackageSetting) {
return !shouldFilterApplication(
@@ -5307,7 +5308,7 @@ public class ComputerEngine implements Computer {
}
final PackageStateInternal installerPackageState = getPackageStateInternal(
- packageState.getInstallSource().installerPackageName);
+ packageState.getInstallSource().mInstallerPackageName);
return installerPackageState != null
&& UserHandle.isSameApp(installerPackageState.getAppId(), callingUid);
}
@@ -5592,7 +5593,8 @@ public class ComputerEngine implements Computer {
return PackageInfoUtils.generateProcessInfo(sus.processes, 0);
} else if (settingBase instanceof PackageSetting) {
final PackageSetting ps = (PackageSetting) settingBase;
- return PackageInfoUtils.generateProcessInfo(ps.getPkg().getProcesses(), 0);
+ final AndroidPackage pkg = ps.getPkg();
+ return pkg == null ? null : PackageInfoUtils.generateProcessInfo(pkg.getProcesses(), 0);
}
return null;
}
diff --git a/services/core/java/com/android/server/pm/CrossProfileIntentResolverEngine.java b/services/core/java/com/android/server/pm/CrossProfileIntentResolverEngine.java
index 4362956b3c09..5d97cb7c61ae 100644
--- a/services/core/java/com/android/server/pm/CrossProfileIntentResolverEngine.java
+++ b/services/core/java/com/android/server/pm/CrossProfileIntentResolverEngine.java
@@ -36,18 +36,15 @@ import android.util.FeatureFlagUtils;
import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
-import android.util.SparseBooleanArray;
import com.android.server.LocalServices;
import com.android.server.pm.pkg.PackageStateInternal;
import com.android.server.pm.verify.domain.DomainVerificationManagerInternal;
import com.android.server.pm.verify.domain.DomainVerificationUtils;
-import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
-import java.util.Queue;
import java.util.Set;
import java.util.function.Function;
@@ -62,6 +59,7 @@ public class CrossProfileIntentResolverEngine {
private final DomainVerificationManagerInternal mDomainVerificationManager;
private final DefaultAppProvider mDefaultAppProvider;
private final Context mContext;
+ private final UserManagerInternal mUserManagerInternal;
public CrossProfileIntentResolverEngine(UserManagerService userManager,
DomainVerificationManagerInternal domainVerificationManager,
@@ -70,6 +68,7 @@ public class CrossProfileIntentResolverEngine {
mDomainVerificationManager = domainVerificationManager;
mDefaultAppProvider = defaultAppProvider;
mContext = context;
+ mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
}
/**
@@ -92,14 +91,14 @@ public class CrossProfileIntentResolverEngine {
String resolvedType, int userId, long flags, String pkgName,
boolean hasNonNegativePriorityResult,
Function<String, PackageStateInternal> pkgSettingFunction) {
- return resolveIntentInternal(computer, intent, resolvedType, userId, flags, pkgName,
- hasNonNegativePriorityResult, pkgSettingFunction);
+ return resolveIntentInternal(computer, intent, resolvedType, userId, userId, flags, pkgName,
+ hasNonNegativePriorityResult, pkgSettingFunction, null);
}
/**
* Resolves intent in directly linked profiles and return list of {@link CrossProfileDomainInfo}
- * which contains {@link ResolveInfo}. This would also iteratively call profiles not directly
- * linked using Breadth First Search.
+ * which contains {@link ResolveInfo}. This would also recursively call profiles not directly
+ * linked using Depth First Search.
*
* It first finds {@link CrossProfileIntentFilter} configured in current profile to find list of
* target user profiles that can serve current intent request. It uses corresponding strategy
@@ -108,123 +107,124 @@ public class CrossProfileIntentResolverEngine {
* @param computer {@link Computer} instance used for resolution by {@link ComponentResolverApi}
* @param intent request
* @param resolvedType the MIME data type of intent request
- * @param userId source user for which intent request is called
+ * @param sourceUserId source user for which intent request is called
+ * @param userId current user for cross profile resolution
* @param flags used for intent resolution
* @param pkgName the application package name this Intent is limited to.
* @param hasNonNegativePriorityResult signifies if current profile have any non-negative(active
* and valid) ResolveInfo in current profile.
* @param pkgSettingFunction function to find PackageStateInternal for given package
+ * @param visitedUserIds users for which we have already performed resolution
* @return list of {@link CrossProfileDomainInfo} from linked profiles.
*/
private List<CrossProfileDomainInfo> resolveIntentInternal(@NonNull Computer computer,
- Intent intent, String resolvedType, int userId, long flags, String pkgName,
- boolean hasNonNegativePriorityResult,
- Function<String, PackageStateInternal> pkgSettingFunction) {
- Queue<Integer> pendingUsers = new ArrayDeque<>();
- Set<Integer> visitedUserIds = new HashSet<>();
- SparseBooleanArray hasNonNegativePriorityResultFromParent = new SparseBooleanArray();
- visitedUserIds.add(userId);
- pendingUsers.add(userId);
- hasNonNegativePriorityResultFromParent.put(userId, hasNonNegativePriorityResult);
- UserManagerInternal umInternal = LocalServices.getService(UserManagerInternal.class);
+ Intent intent, String resolvedType, int sourceUserId, int userId, long flags,
+ String pkgName, boolean hasNonNegativePriorityResult,
+ Function<String, PackageStateInternal> pkgSettingFunction,
+ Set<Integer> visitedUserIds) {
+
+ if (visitedUserIds != null) visitedUserIds.add(userId);
List<CrossProfileDomainInfo> crossProfileDomainInfos = new ArrayList<>();
- while (!pendingUsers.isEmpty()) {
- int currentUserId = pendingUsers.poll();
- List<CrossProfileIntentFilter> matchingFilters =
- computer.getMatchingCrossProfileIntentFilters(intent, resolvedType,
- currentUserId);
-
- if (matchingFilters == null || matchingFilters.isEmpty()) {
- /** if intent is web intent, checking if parent profile should handle the intent
- * even if there is no matching filter. The configuration is based on user profile
- * restriction android.os.UserManager#ALLOW_PARENT_PROFILE_APP_LINKING **/
- if (currentUserId == userId && intent.hasWebURI()) {
- UserInfo parent = computer.getProfileParent(currentUserId);
- if (parent != null) {
- CrossProfileDomainInfo generalizedCrossProfileDomainInfo = computer
- .getCrossProfileDomainPreferredLpr(intent, resolvedType, flags,
- currentUserId, parent.id);
- if (generalizedCrossProfileDomainInfo != null) {
- crossProfileDomainInfos.add(generalizedCrossProfileDomainInfo);
- }
+
+ List<CrossProfileIntentFilter> matchingFilters =
+ computer.getMatchingCrossProfileIntentFilters(intent, resolvedType,
+ userId);
+
+ if (matchingFilters == null || matchingFilters.isEmpty()) {
+ /** if intent is web intent, checking if parent profile should handle the intent
+ * even if there is no matching filter. The configuration is based on user profile
+ * restriction android.os.UserManager#ALLOW_PARENT_PROFILE_APP_LINKING **/
+ if (sourceUserId == userId && intent.hasWebURI()) {
+ UserInfo parent = computer.getProfileParent(userId);
+ if (parent != null) {
+ CrossProfileDomainInfo generalizedCrossProfileDomainInfo = computer
+ .getCrossProfileDomainPreferredLpr(intent, resolvedType, flags,
+ userId, parent.id);
+ if (generalizedCrossProfileDomainInfo != null) {
+ crossProfileDomainInfos.add(generalizedCrossProfileDomainInfo);
}
}
- continue;
}
+ return crossProfileDomainInfos;
+ }
- UserInfo sourceUserInfo = umInternal.getUserInfo(currentUserId);
+ UserInfo userInfo = mUserManagerInternal.getUserInfo(userId);
- // Grouping the CrossProfileIntentFilters based on targerId
- SparseArray<List<CrossProfileIntentFilter>> crossProfileIntentFiltersByUser =
- new SparseArray<>();
+ // Grouping the CrossProfileIntentFilters based on targerId
+ SparseArray<List<CrossProfileIntentFilter>> crossProfileIntentFiltersByUser =
+ new SparseArray<>();
- for (int index = 0; index < matchingFilters.size(); index++) {
- CrossProfileIntentFilter crossProfileIntentFilter = matchingFilters.get(index);
+ for (int index = 0; index < matchingFilters.size(); index++) {
+ CrossProfileIntentFilter crossProfileIntentFilter = matchingFilters.get(index);
- if (!crossProfileIntentFiltersByUser
- .contains(crossProfileIntentFilter.mTargetUserId)) {
- crossProfileIntentFiltersByUser.put(crossProfileIntentFilter.mTargetUserId,
- new ArrayList<>());
- }
- crossProfileIntentFiltersByUser.get(crossProfileIntentFilter.mTargetUserId)
- .add(crossProfileIntentFilter);
+ if (!crossProfileIntentFiltersByUser
+ .contains(crossProfileIntentFilter.mTargetUserId)) {
+ crossProfileIntentFiltersByUser.put(crossProfileIntentFilter.mTargetUserId,
+ new ArrayList<>());
}
+ crossProfileIntentFiltersByUser.get(crossProfileIntentFilter.mTargetUserId)
+ .add(crossProfileIntentFilter);
+ }
- /*
- For each target user, we would call their corresponding strategy
- {@link CrossProfileResolver} to resolve intent in corresponding user
- */
- for (int index = 0; index < crossProfileIntentFiltersByUser.size(); index++) {
+ if (visitedUserIds == null) {
+ visitedUserIds = new HashSet<>();
+ visitedUserIds.add(userId);
+ }
- int targetUserId = crossProfileIntentFiltersByUser.keyAt(index);
+ /*
+ For each target user, we would call their corresponding strategy
+ {@link CrossProfileResolver} to resolve intent in corresponding user
+ */
+ for (int index = 0; index < crossProfileIntentFiltersByUser.size(); index++) {
- //if user is already visited then skip resolution for particular user.
- if (visitedUserIds.contains(targetUserId)) {
- continue;
- }
+ int targetUserId = crossProfileIntentFiltersByUser.keyAt(index);
- UserInfo targetUserInfo = umInternal.getUserInfo(targetUserId);
+ //if user is already visited then skip resolution for particular user.
+ if (visitedUserIds.contains(targetUserId)) {
+ continue;
+ }
- // Choosing strategy based on source and target user
- CrossProfileResolver crossProfileResolver =
- chooseCrossProfileResolver(computer, sourceUserInfo, targetUserInfo);
+ UserInfo targetUserInfo = mUserManagerInternal.getUserInfo(targetUserId);
- /*
- If {@link CrossProfileResolver} is available for source,target pair we will call it to
- get {@link CrossProfileDomainInfo}s from that user.
- */
- if (crossProfileResolver != null) {
- List<CrossProfileDomainInfo> crossProfileInfos = crossProfileResolver
- .resolveIntent(computer, intent, resolvedType, currentUserId,
- targetUserId, flags, pkgName,
- crossProfileIntentFiltersByUser.valueAt(index),
- hasNonNegativePriorityResultFromParent.get(currentUserId),
- pkgSettingFunction);
- crossProfileDomainInfos.addAll(crossProfileInfos);
-
- hasNonNegativePriorityResultFromParent.put(targetUserId,
- hasNonNegativePriority(crossProfileInfos));
-
- /*
- Adding target user to queue if flag
- {@link CrossProfileIntentFilter#FLAG_ALLOW_CHAINED_RESOLUTION} is set for any
- {@link CrossProfileIntentFilter}
- */
- boolean allowChainedResolution = false;
- for (int filterIndex = 0; filterIndex < crossProfileIntentFiltersByUser
- .valueAt(index).size(); filterIndex++) {
- if ((CrossProfileIntentFilter
- .FLAG_ALLOW_CHAINED_RESOLUTION & crossProfileIntentFiltersByUser
- .valueAt(index).get(filterIndex).mFlags) != 0) {
- allowChainedResolution = true;
- break;
- }
- }
- if (allowChainedResolution) {
- pendingUsers.add(targetUserId);
+ // Choosing strategy based on source and target user
+ CrossProfileResolver crossProfileResolver =
+ chooseCrossProfileResolver(computer, userInfo, targetUserInfo);
+
+ /*
+ If {@link CrossProfileResolver} is available for source,target pair we will call it to
+ get {@link CrossProfileDomainInfo}s from that user.
+ */
+ if (crossProfileResolver != null) {
+ List<CrossProfileDomainInfo> crossProfileInfos = crossProfileResolver
+ .resolveIntent(computer, intent, resolvedType, userId,
+ targetUserId, flags, pkgName,
+ crossProfileIntentFiltersByUser.valueAt(index),
+ hasNonNegativePriorityResult, pkgSettingFunction);
+ crossProfileDomainInfos.addAll(crossProfileInfos);
+ visitedUserIds.add(targetUserId);
+
+ /*
+ Adding target user to queue if flag
+ {@link CrossProfileIntentFilter#FLAG_ALLOW_CHAINED_RESOLUTION} is set for any
+ {@link CrossProfileIntentFilter}
+ */
+ boolean allowChainedResolution = false;
+ for (int filterIndex = 0; filterIndex < crossProfileIntentFiltersByUser
+ .valueAt(index).size(); filterIndex++) {
+ if ((CrossProfileIntentFilter
+ .FLAG_ALLOW_CHAINED_RESOLUTION & crossProfileIntentFiltersByUser
+ .valueAt(index).get(filterIndex).mFlags) != 0) {
+ allowChainedResolution = true;
+ break;
}
- visitedUserIds.add(targetUserId);
}
+ if (allowChainedResolution) {
+ crossProfileDomainInfos.addAll(resolveIntentInternal(computer, intent,
+ resolvedType, sourceUserId, targetUserId, flags, pkgName,
+ hasNonNegativePriority(crossProfileInfos), pkgSettingFunction,
+ visitedUserIds));
+ }
+
}
}
@@ -275,56 +275,54 @@ public class CrossProfileIntentResolverEngine {
public boolean canReachTo(@NonNull Computer computer, @NonNull Intent intent,
@Nullable String resolvedType, @UserIdInt int sourceUserId,
@UserIdInt int targetUserId) {
- return canReachToInternal(computer, intent, resolvedType, sourceUserId, targetUserId);
+ Set<Integer> visitedUserIds = new HashSet<>();
+ return canReachToInternal(computer, intent, resolvedType, sourceUserId, targetUserId,
+ visitedUserIds);
}
/**
* Returns true if we source user can reach target user for given intent. The source can
- * directly or indirectly reach to target. This will perform breadth first search to check if
+ * directly or indirectly reach to target. This will perform depth first search to check if
* source can reach target.
* @param computer {@link Computer} instance used for resolution by {@link ComponentResolverApi}
* @param intent request
* @param resolvedType the MIME data type of intent request
* @param sourceUserId source user
* @param targetUserId target user
+ * @param visitedUserIds users for which resolution is checked
* @return true if we source user can reach target user for given intent
*/
private boolean canReachToInternal(@NonNull Computer computer, @NonNull Intent intent,
@Nullable String resolvedType, @UserIdInt int sourceUserId,
- @UserIdInt int targetUserId) {
+ @UserIdInt int targetUserId, Set<Integer> visitedUserIds) {
if (sourceUserId == targetUserId) return true;
-
- Queue<Integer> pendingUsers = new ArrayDeque<>();
- Set<Integer> visitedUserIds = new HashSet<>();
visitedUserIds.add(sourceUserId);
- pendingUsers.add(sourceUserId);
-
- while (!pendingUsers.isEmpty()) {
- int currentUserId = pendingUsers.poll();
-
- List<CrossProfileIntentFilter> matches =
- computer.getMatchingCrossProfileIntentFilters(intent, resolvedType,
- currentUserId);
- if (matches != null) {
- for (int index = 0; index < matches.size(); index++) {
- CrossProfileIntentFilter crossProfileIntentFilter = matches.get(index);
- if (crossProfileIntentFilter.mTargetUserId == targetUserId) {
- return true;
- }
- if (visitedUserIds.contains(crossProfileIntentFilter.mTargetUserId)) {
- continue;
- }
- /*
- If source cannot directly reach to target, we will add
- CrossProfileIntentFilter.mTargetUserId user to queue to check if target user
- can be reached via CrossProfileIntentFilter.mTargetUserId i.e. it can be
- indirectly reached through chained/linked profiles.
- */
- if ((CrossProfileIntentFilter.FLAG_ALLOW_CHAINED_RESOLUTION
- & crossProfileIntentFilter.mFlags) != 0) {
- pendingUsers.add(crossProfileIntentFilter.mTargetUserId);
- visitedUserIds.add(crossProfileIntentFilter.mTargetUserId);
+ List<CrossProfileIntentFilter> matches =
+ computer.getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId);
+
+ if (matches != null) {
+ for (int index = 0; index < matches.size(); index++) {
+ CrossProfileIntentFilter crossProfileIntentFilter = matches.get(index);
+ if (crossProfileIntentFilter.mTargetUserId == targetUserId) {
+ return true;
+ }
+ if (visitedUserIds.contains(crossProfileIntentFilter.mTargetUserId)) {
+ continue;
+ }
+
+ /*
+ If source cannot directly reach to target, we will add
+ CrossProfileIntentFilter.mTargetUserId user to queue to check if target user
+ can be reached via CrossProfileIntentFilter.mTargetUserId i.e. it can be
+ indirectly reached through chained/linked profiles.
+ */
+ if ((CrossProfileIntentFilter.FLAG_ALLOW_CHAINED_RESOLUTION
+ & crossProfileIntentFilter.mFlags) != 0) {
+ visitedUserIds.add(crossProfileIntentFilter.mTargetUserId);
+ if (canReachToInternal(computer, intent, resolvedType,
+ crossProfileIntentFilter.mTargetUserId, targetUserId, visitedUserIds)) {
+ return true;
}
}
}
@@ -628,8 +626,7 @@ public class CrossProfileIntentResolverEngine {
categorizeResolveInfoByTargetUser, int sourceUserId, int highestApprovalLevel) {
List<CrossProfileDomainInfo> crossProfileDomainInfos = new ArrayList<>();
- UserManagerInternal umInternal = LocalServices.getService(UserManagerInternal.class);
- UserInfo sourceUserInfo = umInternal.getUserInfo(sourceUserId);
+ UserInfo sourceUserInfo = mUserManagerInternal.getUserInfo(sourceUserId);
for (int index = 0; index < categorizeResolveInfoByTargetUser.size(); index++) {
@@ -639,7 +636,7 @@ public class CrossProfileIntentResolverEngine {
} else {
// finding cross profile strategy based on source and target user
CrossProfileResolver crossProfileIntentResolver =
- chooseCrossProfileResolver(computer, sourceUserInfo, umInternal
+ chooseCrossProfileResolver(computer, sourceUserInfo, mUserManagerInternal
.getUserInfo(categorizeResolveInfoByTargetUser.keyAt(index)));
// if strategy is available call it and add its filtered results
if (crossProfileIntentResolver != null) {
diff --git a/services/core/java/com/android/server/pm/DeletePackageHelper.java b/services/core/java/com/android/server/pm/DeletePackageHelper.java
index 095a7f6066b5..6998db76e338 100644
--- a/services/core/java/com/android/server/pm/DeletePackageHelper.java
+++ b/services/core/java/com/android/server/pm/DeletePackageHelper.java
@@ -544,7 +544,7 @@ final class DeletePackageHelper {
outInfo.mDataRemoved = true;
}
outInfo.mRemovedPackage = ps.getPackageName();
- outInfo.mInstallerPackageName = ps.getInstallSource().installerPackageName;
+ outInfo.mInstallerPackageName = ps.getInstallSource().mInstallerPackageName;
outInfo.mIsStaticSharedLib = pkg != null && pkg.getStaticSharedLibraryName() != null;
outInfo.mRemovedAppId = ps.getAppId();
outInfo.mRemovedUsers = userIds;
@@ -814,7 +814,7 @@ final class DeletePackageHelper {
private boolean isOrphaned(@NonNull Computer snapshot, String packageName) {
final PackageStateInternal packageState = snapshot.getPackageStateInternal(packageName);
- return packageState != null && packageState.getInstallSource().isOrphaned;
+ return packageState != null && packageState.getInstallSource().mIsOrphaned;
}
private boolean isCallerAllowedToSilentlyUninstall(@NonNull Computer snapshot, int callingUid,
diff --git a/services/core/java/com/android/server/pm/DexOptHelper.java b/services/core/java/com/android/server/pm/DexOptHelper.java
index c4f6836eba7b..0066592de8c4 100644
--- a/services/core/java/com/android/server/pm/DexOptHelper.java
+++ b/services/core/java/com/android/server/pm/DexOptHelper.java
@@ -33,6 +33,8 @@ import static com.android.server.pm.PackageManagerServiceCompilerMapping.getDefa
import static com.android.server.pm.PackageManagerServiceUtils.REMOVE_IF_APEX_PKG;
import static com.android.server.pm.PackageManagerServiceUtils.REMOVE_IF_NULL_PKG;
+import static dalvik.system.DexFile.isProfileGuidedCompilerFilter;
+
import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -70,8 +72,6 @@ import com.android.server.pm.pkg.AndroidPackage;
import com.android.server.pm.pkg.PackageState;
import com.android.server.pm.pkg.PackageStateInternal;
-import dalvik.system.DexFile;
-
import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
@@ -236,20 +236,24 @@ public final class DexOptHelper {
mPm.mArtManagerService.compileLayouts(pkg);
}
- // checkProfiles is false to avoid merging profiles during boot which
- // might interfere with background compilation (b/28612421).
- // Unfortunately this will also means that "pm.dexopt.boot=speed-profile" will
- // behave differently than "pm.dexopt.bg-dexopt=speed-profile" but that's a
- // trade-off worth doing to save boot time work.
int dexoptFlags = bootComplete ? DexoptOptions.DEXOPT_BOOT_COMPLETE : 0;
+
+ String filter = getCompilerFilterForReason(pkgCompilationReason);
+ if (isProfileGuidedCompilerFilter(filter)) {
+ // DEXOPT_CHECK_FOR_PROFILES_UPDATES used to be false to avoid merging profiles
+ // during boot which might interfere with background compilation (b/28612421).
+ // However those problems were related to the verify-profile compiler filter which
+ // doesn't exist any more, so enable it again.
+ dexoptFlags |= DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES;
+ }
+
if (compilationReason == REASON_FIRST_BOOT) {
// TODO: This doesn't cover the upgrade case, we should check for this too.
dexoptFlags |= DexoptOptions.DEXOPT_INSTALL_WITH_DEX_METADATA_FILE;
}
- int primaryDexOptStatus = performDexOptTraced(new DexoptOptions(
- pkg.getPackageName(),
- pkgCompilationReason,
- dexoptFlags));
+ int primaryDexOptStatus = performDexOptTraced(
+ new DexoptOptions(pkg.getPackageName(), pkgCompilationReason, filter,
+ /*splitName*/ null, dexoptFlags));
switch (primaryDexOptStatus) {
case PackageDexOptimizer.DEX_OPT_PERFORMED:
@@ -297,7 +301,7 @@ public final class DexOptHelper {
SystemProperties.get("dalvik.vm.systemuicompilerfilter", defaultCompilerFilter);
String compilerFilter;
- if (DexFile.isProfileGuidedCompilerFilter(targetCompilerFilter)) {
+ if (isProfileGuidedCompilerFilter(targetCompilerFilter)) {
compilerFilter = defaultCompilerFilter;
File profileFile = new File(getPrebuildProfilePath(pkg));
@@ -322,8 +326,16 @@ public final class DexOptHelper {
compilerFilter = targetCompilerFilter;
}
+ // We don't expect updates in current profiles to be significant here, but
+ // DEXOPT_CHECK_FOR_PROFILES_UPDATES is set to replicate behaviour that will be
+ // unconditionally enabled for profile guided filters when ART Service is called instead of
+ // the legacy PackageDexOptimizer implementation.
+ int dexoptFlags = isProfileGuidedCompilerFilter(compilerFilter)
+ ? DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES
+ : 0;
+
performDexOptTraced(new DexoptOptions(pkg.getPackageName(), REASON_BOOT_AFTER_OTA,
- compilerFilter, null /* splitName */, 0 /* dexoptFlags */));
+ compilerFilter, null /* splitName */, dexoptFlags));
}
@RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG)
@@ -622,16 +634,21 @@ public final class DexOptHelper {
}
public boolean performDexOptMode(@NonNull Computer snapshot, String packageName,
- boolean checkProfiles, String targetCompilerFilter, boolean force,
- boolean bootComplete, String splitName) {
+ String targetCompilerFilter, boolean force, boolean bootComplete, String splitName) {
if (!PackageManagerServiceUtils.isSystemOrRootOrShell()
&& !isCallerInstallerForPackage(snapshot, packageName)) {
throw new SecurityException("performDexOptMode");
}
- int flags = (checkProfiles ? DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES : 0)
- | (force ? DexoptOptions.DEXOPT_FORCE : 0)
+ int flags = (force ? DexoptOptions.DEXOPT_FORCE : 0)
| (bootComplete ? DexoptOptions.DEXOPT_BOOT_COMPLETE : 0);
+
+ if (isProfileGuidedCompilerFilter(targetCompilerFilter)) {
+ // Set this flag whenever the filter is profile guided, to align with ART Service
+ // behavior.
+ flags |= DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES;
+ }
+
return performDexOpt(new DexoptOptions(packageName, REASON_CMDLINE,
targetCompilerFilter, splitName, flags));
}
@@ -644,7 +661,7 @@ public final class DexOptHelper {
final InstallSource installSource = packageState.getInstallSource();
final PackageStateInternal installerPackageState =
- snapshot.getPackageStateInternal(installSource.installerPackageName);
+ snapshot.getPackageStateInternal(installSource.mInstallerPackageName);
if (installerPackageState == null) {
return false;
}
diff --git a/services/core/java/com/android/server/pm/IPackageManagerBase.java b/services/core/java/com/android/server/pm/IPackageManagerBase.java
index 05a0adcf0a6d..5c3890c192dd 100644
--- a/services/core/java/com/android/server/pm/IPackageManagerBase.java
+++ b/services/core/java/com/android/server/pm/IPackageManagerBase.java
@@ -57,6 +57,7 @@ import android.os.RemoteException;
import android.os.Trace;
import android.os.UserHandle;
import android.permission.PermissionManager;
+import android.util.Log;
import com.android.internal.R;
import com.android.internal.content.InstallLocationUtils;
@@ -964,8 +965,12 @@ public abstract class IPackageManagerBase extends IPackageManager.Stub {
boolean checkProfiles, String targetCompilerFilter, boolean force,
boolean bootComplete, String splitName) {
final Computer snapshot = snapshot();
- return mDexOptHelper.performDexOptMode(snapshot, packageName, checkProfiles,
- targetCompilerFilter, force, bootComplete, splitName);
+ if (!checkProfiles) {
+ // There is no longer a flag to skip profile checking.
+ Log.w(PackageManagerService.TAG, "Ignored checkProfiles=false flag");
+ }
+ return mDexOptHelper.performDexOptMode(
+ snapshot, packageName, targetCompilerFilter, force, bootComplete, splitName);
}
/**
diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java
index 70bd24ce20a2..b02d1a8c0353 100644
--- a/services/core/java/com/android/server/pm/InstallPackageHelper.java
+++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java
@@ -174,6 +174,7 @@ import com.android.server.pm.pkg.component.ParsedPermission;
import com.android.server.pm.pkg.component.ParsedPermissionGroup;
import com.android.server.pm.pkg.parsing.ParsingPackageUtils;
import com.android.server.rollback.RollbackManagerInternal;
+import com.android.server.security.FileIntegrityService;
import com.android.server.utils.WatchedArrayMap;
import com.android.server.utils.WatchedLongSparseArray;
@@ -307,9 +308,9 @@ final class InstallPackageHelper {
// previous device state.
InstallSource installSource = request.getInstallSource();
if (installSource != null) {
- if (installSource.initiatingPackageName != null) {
+ if (installSource.mInitiatingPackageName != null) {
final PackageSetting ips = mPm.mSettings.getPackageLPr(
- installSource.initiatingPackageName);
+ installSource.mInitiatingPackageName);
if (ips != null) {
installSource = installSource.setInitiatingPackageSignatures(
ips.getSignatures());
@@ -1565,7 +1566,7 @@ final class InstallPackageHelper {
removedInfo.mUid = oldPackage.getUid();
removedInfo.mRemovedPackage = oldPackage.getPackageName();
removedInfo.mInstallerPackageName =
- ps.getInstallSource().installerPackageName;
+ ps.getInstallSource().mInstallerPackageName;
removedInfo.mIsStaticSharedLib =
parsedPackage.getStaticSharedLibraryName() != null;
removedInfo.mIsUpdate = true;
@@ -1815,8 +1816,6 @@ final class InstallPackageHelper {
// Collect files we care for fs-verity setup.
ArrayMap<String, String> fsverityCandidates = new ArrayMap<>();
- // NB: These files will become only accessible if the signing key is loaded in kernel's
- // .fs-verity keyring.
fsverityCandidates.put(pkg.getBaseApkPath(),
VerityUtils.getFsveritySignatureFilePath(pkg.getBaseApkPath()));
@@ -1836,6 +1835,7 @@ final class InstallPackageHelper {
}
}
+ var fis = FileIntegrityService.getService();
for (Map.Entry<String, String> entry : fsverityCandidates.entrySet()) {
try {
final String filePath = entry.getKey();
@@ -1843,13 +1843,17 @@ final class InstallPackageHelper {
continue;
}
- // Set up fs-verity with optional signature.
final String signaturePath = entry.getValue();
- String optionalSignaturePath = null;
if (new File(signaturePath).exists()) {
- optionalSignaturePath = signaturePath;
+ // If signature is provided, enable fs-verity first so that the file can be
+ // measured for signature check below.
+ VerityUtils.setUpFsverity(filePath, (byte[]) null);
+
+ if (!fis.verifyPkcs7DetachedSignature(signaturePath, filePath)) {
+ throw new PrepareFailure(PackageManager.INSTALL_FAILED_BAD_SIGNATURE,
+ "fs-verity signature does not verify against a known key");
+ }
}
- VerityUtils.setUpFsverity(filePath, optionalSignaturePath);
} catch (IOException e) {
throw new PrepareFailure(PackageManager.INSTALL_FAILED_BAD_SIGNATURE,
"Failed to enable fs-verity: " + e);
@@ -2223,6 +2227,22 @@ final class InstallPackageHelper {
}
incrementalStorages.add(storage);
}
+
+ try {
+ if (!VerityUtils.hasFsverity(pkg.getBaseApkPath())) {
+ VerityUtils.setUpFsverity(pkg.getBaseApkPath(), (byte[]) null);
+ }
+ for (String path : pkg.getSplitCodePaths()) {
+ if (!VerityUtils.hasFsverity(path)) {
+ VerityUtils.setUpFsverity(path, (byte[]) null);
+ }
+ }
+ } catch (IOException e) {
+ // There's nothing we can do if the setup failed. Since fs-verity is
+ // optional, just ignore the error for now.
+ Slog.e(TAG, "Failed to fully enable fs-verity to " + packageName);
+ }
+
// Hardcode previousAppId to 0 to disable any data migration (http://b/221088088)
mAppDataHelper.prepareAppDataPostCommitLIF(pkg, 0);
if (installRequest.isClearCodeCache()) {
diff --git a/services/core/java/com/android/server/pm/InstallRequest.java b/services/core/java/com/android/server/pm/InstallRequest.java
index 4e5a6f9fa2b5..71571dc4f306 100644
--- a/services/core/java/com/android/server/pm/InstallRequest.java
+++ b/services/core/java/com/android/server/pm/InstallRequest.java
@@ -81,7 +81,7 @@ final class InstallRequest {
/** Package Installed Info */
@Nullable
private String mName;
- private int mUid = -1;
+ private int mUid = INVALID_UID;
// The set of users that originally had this package installed.
@Nullable
private int[] mOrigUsers;
@@ -314,7 +314,12 @@ final class InstallRequest {
@Nullable
public String getInstallerPackageName() {
return (mInstallArgs != null && mInstallArgs.mInstallSource != null)
- ? mInstallArgs.mInstallSource.installerPackageName : null;
+ ? mInstallArgs.mInstallSource.mInstallerPackageName : null;
+ }
+
+ public int getInstallerPackageUid() {
+ return (mInstallArgs != null && mInstallArgs.mInstallSource != null)
+ ? mInstallArgs.mInstallSource.mInstallerPackageUid : INVALID_UID;
}
public int getDataLoaderType() {
@@ -343,7 +348,7 @@ final class InstallRequest {
@Nullable
public String getSourceInstallerPackageName() {
- return mInstallArgs.mInstallSource.installerPackageName;
+ return mInstallArgs.mInstallSource.mInstallerPackageName;
}
public boolean isRollback() {
@@ -608,12 +613,18 @@ final class InstallRequest {
setReturnCode(code);
setReturnMessage(msg);
Slog.w(TAG, msg);
+ if (mPackageMetrics != null) {
+ mPackageMetrics.onInstallFailed();
+ }
}
public void setError(String msg, PackageManagerException e) {
mReturnCode = e.error;
setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
Slog.w(TAG, msg, e);
+ if (mPackageMetrics != null) {
+ mPackageMetrics.onInstallFailed();
+ }
}
public void setReturnCode(int returnCode) {
@@ -757,10 +768,10 @@ final class InstallRequest {
}
}
- public void onInstallCompleted(Computer snapshot) {
+ public void onInstallCompleted() {
if (getReturnCode() == INSTALL_SUCCEEDED) {
if (mPackageMetrics != null) {
- mPackageMetrics.onInstallSucceed(snapshot);
+ mPackageMetrics.onInstallSucceed();
}
}
}
diff --git a/services/core/java/com/android/server/pm/InstallSource.java b/services/core/java/com/android/server/pm/InstallSource.java
index e5f7f7166186..dde9905ccc86 100644
--- a/services/core/java/com/android/server/pm/InstallSource.java
+++ b/services/core/java/com/android/server/pm/InstallSource.java
@@ -16,6 +16,8 @@
package com.android.server.pm;
+import static android.os.Process.INVALID_UID;
+
import android.annotation.Nullable;
import android.content.pm.PackageInstaller;
@@ -32,27 +34,27 @@ public final class InstallSource {
* An instance of InstallSource representing an absence of knowledge of the source of
* a package. Used in preference to null.
*/
- static final InstallSource EMPTY = new InstallSource(null, null, null, null, false, false,
- null, PackageInstaller.PACKAGE_SOURCE_UNSPECIFIED);
+ static final InstallSource EMPTY = new InstallSource(null, null, null, INVALID_UID, null,
+ false, false, null, PackageInstaller.PACKAGE_SOURCE_UNSPECIFIED);
/** We also memoize this case because it is common - all un-updated system apps. */
private static final InstallSource EMPTY_ORPHANED = new InstallSource(
- null, null, null, null, true, false, null,
+ null, null, null, INVALID_UID, null, true, false, null,
PackageInstaller.PACKAGE_SOURCE_UNSPECIFIED);
/**
* The package that requested the installation, if known. May not correspond to a currently
- * installed package if {@link #isInitiatingPackageUninstalled} is true.
+ * installed package if {@link #mIsInitiatingPackageUninstalled} is true.
*/
@Nullable
- final String initiatingPackageName;
+ final String mInitiatingPackageName;
/**
* The signing details of the initiating package, if known. Always null if
- * {@link #initiatingPackageName} is null.
+ * {@link #mInitiatingPackageName} is null.
*/
@Nullable
- final PackageSignatures initiatingPackageSignatures;
+ final PackageSignatures mInitiatingPackageSignatures;
/**
* The package on behalf of which the initiating package requested the installation, if any.
@@ -61,64 +63,63 @@ public final class InstallSource {
* verified by the framework.
*/
@Nullable
- final String originatingPackageName;
+ final String mOriginatingPackageName;
/**
* Package name of the app that installed this package (the installer of record). Note that
* this may be modified.
*/
@Nullable
- final String installerPackageName;
+ final String mInstallerPackageName;
+ /**
+ * UID of the installer package, corresponding to the {@link #mInstallerPackageName}.
+ */
+ final int mInstallerPackageUid;
/**
* {@link android.content.Context#getAttributionTag()} of installing context.
*/
@Nullable
- final String installerAttributionTag;
+ final String mInstallerAttributionTag;
/** Indicates if the package that was the installerPackageName has been uninstalled. */
- final boolean isOrphaned;
+ final boolean mIsOrphaned;
/**
* Indicates if the package in initiatingPackageName has been uninstalled. Always false if
- * {@link #initiatingPackageName} is null.
+ * {@link #mInitiatingPackageName} is null.
*/
- final boolean isInitiatingPackageUninstalled;
+ final boolean mIsInitiatingPackageUninstalled;
- final int packageSource;
+ final int mPackageSource;
static InstallSource create(@Nullable String initiatingPackageName,
@Nullable String originatingPackageName, @Nullable String installerPackageName,
- @Nullable String installerAttributionTag) {
- return create(initiatingPackageName, originatingPackageName, installerPackageName,
- installerAttributionTag, PackageInstaller.PACKAGE_SOURCE_UNSPECIFIED);
- }
-
- static InstallSource create(@Nullable String initiatingPackageName,
- @Nullable String originatingPackageName, @Nullable String installerPackageName,
- @Nullable String installerAttributionTag, boolean isOrphaned,
+ int installerPackageUid, @Nullable String installerAttributionTag, boolean isOrphaned,
boolean isInitiatingPackageUninstalled) {
return create(initiatingPackageName, originatingPackageName, installerPackageName,
- installerAttributionTag, PackageInstaller.PACKAGE_SOURCE_UNSPECIFIED, isOrphaned,
+ installerPackageUid, installerAttributionTag,
+ PackageInstaller.PACKAGE_SOURCE_UNSPECIFIED, isOrphaned,
isInitiatingPackageUninstalled);
}
static InstallSource create(@Nullable String initiatingPackageName,
@Nullable String originatingPackageName, @Nullable String installerPackageName,
- @Nullable String installerAttributionTag, int packageSource) {
+ int installerPackageUid, @Nullable String installerAttributionTag, int packageSource) {
return create(initiatingPackageName, originatingPackageName, installerPackageName,
- installerAttributionTag, packageSource, false, false);
+ installerPackageUid, installerAttributionTag, packageSource, false, false);
}
static InstallSource create(@Nullable String initiatingPackageName,
@Nullable String originatingPackageName, @Nullable String installerPackageName,
- @Nullable String installerAttributionTag, int packageSource, boolean isOrphaned,
- boolean isInitiatingPackageUninstalled) {
+ int installerPackageUid, @Nullable String installerAttributionTag, int packageSource,
+ boolean isOrphaned, boolean isInitiatingPackageUninstalled) {
return createInternal(
intern(initiatingPackageName),
intern(originatingPackageName),
intern(installerPackageName),
+ installerPackageUid,
installerAttributionTag,
packageSource,
isOrphaned, isInitiatingPackageUninstalled, null);
@@ -126,8 +127,8 @@ public final class InstallSource {
private static InstallSource createInternal(@Nullable String initiatingPackageName,
@Nullable String originatingPackageName, @Nullable String installerPackageName,
- @Nullable String installerAttributionTag, int packageSource, boolean isOrphaned,
- boolean isInitiatingPackageUninstalled,
+ int installerPackageUid, @Nullable String installerAttributionTag, int packageSource,
+ boolean isOrphaned, boolean isInitiatingPackageUninstalled,
@Nullable PackageSignatures initiatingPackageSignatures) {
if (initiatingPackageName == null && originatingPackageName == null
&& installerPackageName == null && initiatingPackageSignatures == null
@@ -136,13 +137,14 @@ public final class InstallSource {
return isOrphaned ? EMPTY_ORPHANED : EMPTY;
}
return new InstallSource(initiatingPackageName, originatingPackageName,
- installerPackageName, installerAttributionTag, isOrphaned,
+ installerPackageName, installerPackageUid, installerAttributionTag, isOrphaned,
isInitiatingPackageUninstalled, initiatingPackageSignatures, packageSource
);
}
private InstallSource(@Nullable String initiatingPackageName,
@Nullable String originatingPackageName, @Nullable String installerPackageName,
+ int installerPackageUid,
@Nullable String installerAttributionTag, boolean isOrphaned,
boolean isInitiatingPackageUninstalled,
@Nullable PackageSignatures initiatingPackageSignatures,
@@ -151,53 +153,58 @@ public final class InstallSource {
Preconditions.checkArgument(initiatingPackageSignatures == null);
Preconditions.checkArgument(!isInitiatingPackageUninstalled);
}
- this.initiatingPackageName = initiatingPackageName;
- this.originatingPackageName = originatingPackageName;
- this.installerPackageName = installerPackageName;
- this.installerAttributionTag = installerAttributionTag;
- this.isOrphaned = isOrphaned;
- this.isInitiatingPackageUninstalled = isInitiatingPackageUninstalled;
- this.initiatingPackageSignatures = initiatingPackageSignatures;
- this.packageSource = packageSource;
+ mInitiatingPackageName = initiatingPackageName;
+ mOriginatingPackageName = originatingPackageName;
+ mInstallerPackageName = installerPackageName;
+ mInstallerPackageUid = installerPackageUid;
+ mInstallerAttributionTag = installerAttributionTag;
+ mIsOrphaned = isOrphaned;
+ mIsInitiatingPackageUninstalled = isInitiatingPackageUninstalled;
+ mInitiatingPackageSignatures = initiatingPackageSignatures;
+ mPackageSource = packageSource;
}
/**
* Return an InstallSource the same as this one except with the specified
- * {@link #installerPackageName}.
+ * {@link #mInstallerPackageName}.
*/
- InstallSource setInstallerPackage(@Nullable String installerPackageName) {
- if (Objects.equals(installerPackageName, this.installerPackageName)) {
+ InstallSource setInstallerPackage(@Nullable String installerPackageName,
+ int installerPackageUid) {
+ if (Objects.equals(installerPackageName, mInstallerPackageName)) {
return this;
}
- return createInternal(initiatingPackageName, originatingPackageName,
- intern(installerPackageName), installerAttributionTag, packageSource, isOrphaned,
- isInitiatingPackageUninstalled, initiatingPackageSignatures);
+ return createInternal(mInitiatingPackageName, mOriginatingPackageName,
+ intern(installerPackageName), installerPackageUid, mInstallerAttributionTag,
+ mPackageSource, mIsOrphaned, mIsInitiatingPackageUninstalled,
+ mInitiatingPackageSignatures);
}
/**
* Return an InstallSource the same as this one except with the specified value for
- * {@link #isOrphaned}.
+ * {@link #mIsOrphaned}.
*/
InstallSource setIsOrphaned(boolean isOrphaned) {
- if (isOrphaned == this.isOrphaned) {
+ if (isOrphaned == mIsOrphaned) {
return this;
}
- return createInternal(initiatingPackageName, originatingPackageName, installerPackageName,
- installerAttributionTag, packageSource, isOrphaned, isInitiatingPackageUninstalled,
- initiatingPackageSignatures);
+ return createInternal(mInitiatingPackageName, mOriginatingPackageName,
+ mInstallerPackageName,
+ mInstallerPackageUid, mInstallerAttributionTag, mPackageSource, isOrphaned,
+ mIsInitiatingPackageUninstalled, mInitiatingPackageSignatures);
}
/**
* Return an InstallSource the same as this one except with the specified
- * {@link #initiatingPackageSignatures}.
+ * {@link #mInitiatingPackageSignatures}.
*/
InstallSource setInitiatingPackageSignatures(@Nullable PackageSignatures signatures) {
- if (signatures == initiatingPackageSignatures) {
+ if (signatures == mInitiatingPackageSignatures) {
return this;
}
- return createInternal(initiatingPackageName, originatingPackageName, installerPackageName,
- installerAttributionTag, packageSource, isOrphaned,
- isInitiatingPackageUninstalled, signatures);
+ return createInternal(mInitiatingPackageName, mOriginatingPackageName,
+ mInstallerPackageName,
+ mInstallerPackageUid, mInstallerAttributionTag, mPackageSource, mIsOrphaned,
+ mIsInitiatingPackageUninstalled, signatures);
}
/**
@@ -210,12 +217,13 @@ public final class InstallSource {
}
boolean modified = false;
- boolean isInitiatingPackageUninstalled = this.isInitiatingPackageUninstalled;
- String originatingPackageName = this.originatingPackageName;
- String installerPackageName = this.installerPackageName;
- boolean isOrphaned = this.isOrphaned;
+ boolean isInitiatingPackageUninstalled = mIsInitiatingPackageUninstalled;
+ String originatingPackageName = mOriginatingPackageName;
+ String installerPackageName = mInstallerPackageName;
+ int installerPackageUid = mInstallerPackageUid;
+ boolean isOrphaned = mIsOrphaned;
- if (packageName.equals(this.initiatingPackageName)) {
+ if (packageName.equals(mInitiatingPackageName)) {
if (!isInitiatingPackageUninstalled) {
// In this case we deliberately do not clear the package name (and signatures).
// We allow an app to retrieve details of its own install initiator even after
@@ -230,6 +238,7 @@ public final class InstallSource {
}
if (packageName.equals(installerPackageName)) {
installerPackageName = null;
+ installerPackageUid = INVALID_UID;
isOrphaned = true;
modified = true;
}
@@ -238,9 +247,9 @@ public final class InstallSource {
return this;
}
- return createInternal(initiatingPackageName, originatingPackageName, installerPackageName,
- null, packageSource, isOrphaned,
- isInitiatingPackageUninstalled, initiatingPackageSignatures);
+ return createInternal(mInitiatingPackageName, originatingPackageName, installerPackageName,
+ installerPackageUid, null, mPackageSource, isOrphaned,
+ isInitiatingPackageUninstalled, mInitiatingPackageSignatures);
}
@Nullable
diff --git a/services/core/java/com/android/server/pm/InstallingSession.java b/services/core/java/com/android/server/pm/InstallingSession.java
index d8494dbaa827..69ced1b39585 100644
--- a/services/core/java/com/android/server/pm/InstallingSession.java
+++ b/services/core/java/com/android/server/pm/InstallingSession.java
@@ -143,7 +143,7 @@ class InstallingSession {
mOriginInfo = OriginInfo.fromStagedFile(stagedDir);
mMoveInfo = null;
mInstallReason = fixUpInstallReason(
- installSource.installerPackageName, installerUid, sessionParams.installReason);
+ installSource.mInstallerPackageName, installerUid, sessionParams.installReason);
mInstallScenario = sessionParams.installScenario;
mObserver = observer;
mInstallFlags = sessionParams.installFlags;
@@ -223,7 +223,7 @@ class InstallingSession {
* policy if needed and then create install arguments based
* on the install location.
*/
- private void handleStartCopy() {
+ private void handleStartCopy(InstallRequest request) {
if ((mInstallFlags & PackageManager.INSTALL_APEX) != 0) {
mRet = INSTALL_SUCCEEDED;
return;
@@ -239,6 +239,7 @@ class InstallingSession {
pkgLite, mRequiredInstalledVersionCode, mInstallFlags);
mRet = ret.first;
if (mRet != INSTALL_SUCCEEDED) {
+ request.setError(mRet, "Failed to verify version code");
return;
}
}
@@ -258,14 +259,16 @@ class InstallingSession {
}
mRet = overrideInstallLocation(pkgLite.packageName, pkgLite.recommendedInstallLocation,
pkgLite.installLocation);
+ if (mRet != INSTALL_SUCCEEDED) {
+ request.setError(mRet, "Failed to override installation location");
+ }
}
- private void handleReturnCode() {
- processPendingInstall();
+ private void handleReturnCode(InstallRequest installRequest) {
+ processPendingInstall(installRequest);
}
- private void processPendingInstall() {
- InstallRequest installRequest = new InstallRequest(this);
+ private void processPendingInstall(InstallRequest installRequest) {
if (mRet == PackageManager.INSTALL_SUCCEEDED) {
mRet = copyApk(installRequest);
}
@@ -302,21 +305,26 @@ class InstallingSession {
request.setCodeFile(mOriginInfo.mFile);
return PackageManager.INSTALL_SUCCEEDED;
}
-
+ int ret;
try {
final boolean isEphemeral =
(mInstallFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
request.setCodeFile(
mPm.mInstallerService.allocateStageDirLegacy(mVolumeUuid, isEphemeral));
} catch (IOException e) {
- Slog.w(TAG, "Failed to create copy file: " + e);
- return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
+ final String errorMessage = "Failed to create copy file";
+ Slog.w(TAG, errorMessage + ": " + e);
+ ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
+ request.setError(ret, errorMessage);
+ return ret;
}
- int ret = PackageManagerServiceUtils.copyPackage(
+ ret = PackageManagerServiceUtils.copyPackage(
mOriginInfo.mFile.getAbsolutePath(), request.getCodeFile());
if (ret != PackageManager.INSTALL_SUCCEEDED) {
- Slog.e(TAG, "Failed to copy package");
+ final String errorMessage = "Failed to copy package";
+ Slog.e(TAG, errorMessage);
+ request.setError(ret, errorMessage);
return ret;
}
@@ -329,8 +337,10 @@ class InstallingSession {
ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
request.getAbiOverride(), isIncremental);
} catch (IOException e) {
- Slog.e(TAG, "Copying native libraries failed", e);
+ final String errorMessage = "Copying native libraries failed";
+ Slog.e(TAG, errorMessage, e);
ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
+ request.setError(ret, errorMessage);
} finally {
IoUtils.closeQuietly(handle);
}
@@ -352,8 +362,11 @@ class InstallingSession {
mMoveInfo.mPackageName, mMoveInfo.mAppId, mMoveInfo.mSeInfo,
mMoveInfo.mTargetSdkVersion, mMoveInfo.mFromCodePath);
} catch (Installer.InstallerException e) {
- Slog.w(TAG, "Failed to move app", e);
- return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
+ final String errorMessage = "Failed to move app";
+ final int ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
+ request.setError(ret, errorMessage);
+ Slog.w(TAG, errorMessage, e);
+ return ret;
}
}
@@ -456,8 +469,9 @@ class InstallingSession {
Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
System.identityHashCode(this));
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startInstall");
- handleStartCopy();
- handleReturnCode();
+ InstallRequest installRequest = new InstallRequest(this);
+ handleStartCopy(installRequest);
+ handleReturnCode(installRequest);
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
@@ -518,7 +532,7 @@ class InstallingSession {
mInstallPackageHelper.installPackagesTraced(installRequests);
for (InstallRequest request : installRequests) {
- request.onInstallCompleted(mPm.snapshotComputer());
+ request.onInstallCompleted();
doPostInstall(request);
}
}
@@ -635,11 +649,18 @@ class InstallingSession {
Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
System.identityHashCode(this));
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "start");
- for (InstallingSession childInstallingSession : mChildInstallingSessions) {
- childInstallingSession.handleStartCopy();
+
+ final int numChildSessions = mChildInstallingSessions.size();
+ final ArrayList<InstallRequest> installRequests = new ArrayList<>(numChildSessions);
+
+ for (int i = 0; i < numChildSessions; i++) {
+ final InstallingSession childSession = mChildInstallingSessions.get(i);
+ final InstallRequest installRequest = new InstallRequest(childSession);
+ installRequests.add(installRequest);
+ childSession.handleStartCopy(installRequest);
}
- for (InstallingSession childInstallingSession : mChildInstallingSessions) {
- childInstallingSession.handleReturnCode();
+ for (int i = 0; i < numChildSessions; i++) {
+ mChildInstallingSessions.get(i).handleReturnCode(installRequests.get(i));
}
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
@@ -647,6 +668,7 @@ class InstallingSession {
public void tryProcessInstallRequest(InstallRequest request) {
mCurrentInstallRequests.add(request);
if (mCurrentInstallRequests.size() != mChildInstallingSessions.size()) {
+ // Wait until all the installRequests have finished copying
return;
}
int completeStatus = PackageManager.INSTALL_SUCCEEDED;
diff --git a/services/core/java/com/android/server/pm/PackageDexOptimizer.java b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
index 2a2410fd1767..226a27eccc03 100644
--- a/services/core/java/com/android/server/pm/PackageDexOptimizer.java
+++ b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
@@ -785,7 +785,9 @@ public class PackageDexOptimizer {
private String getRealCompilerFilter(ApplicationInfo info, String targetCompilerFilter,
boolean isUsedByOtherApps) {
if (info.isEmbeddedDexUsed()) {
- return "verify";
+ // Downgrade optimizing filters to "verify", but don't upgrade lower filters.
+ return DexFile.isOptimizedCompilerFilter(targetCompilerFilter) ? "verify"
+ : targetCompilerFilter;
}
// We force vmSafeMode on debuggable apps as well:
@@ -822,7 +824,9 @@ public class PackageDexOptimizer {
*/
private String getRealCompilerFilter(AndroidPackage pkg, String targetCompilerFilter) {
if (pkg.isUseEmbeddedDex()) {
- return "verify";
+ // Downgrade optimizing filters to "verify", but don't upgrade lower filters.
+ return DexFile.isOptimizedCompilerFilter(targetCompilerFilter) ? "verify"
+ : targetCompilerFilter;
}
// We force vmSafeMode on debuggable apps as well:
diff --git a/services/core/java/com/android/server/pm/PackageHandler.java b/services/core/java/com/android/server/pm/PackageHandler.java
index 66ef93d12191..93a119c36f3d 100644
--- a/services/core/java/com/android/server/pm/PackageHandler.java
+++ b/services/core/java/com/android/server/pm/PackageHandler.java
@@ -36,7 +36,6 @@ import static com.android.server.pm.PackageManagerService.PRUNE_UNUSED_STATIC_SH
import static com.android.server.pm.PackageManagerService.SEND_PENDING_BROADCAST;
import static com.android.server.pm.PackageManagerService.TAG;
import static com.android.server.pm.PackageManagerService.WRITE_PACKAGE_LIST;
-import static com.android.server.pm.PackageManagerService.WRITE_PACKAGE_RESTRICTIONS;
import static com.android.server.pm.PackageManagerService.WRITE_SETTINGS;
import android.content.Intent;
@@ -119,10 +118,7 @@ final class PackageHandler extends Handler {
}
} break;
case WRITE_SETTINGS: {
- mPm.writeSettings();
- } break;
- case WRITE_PACKAGE_RESTRICTIONS: {
- mPm.writePendingRestrictions();
+ mPm.writeSettings(/*sync=*/false);
} break;
case WRITE_PACKAGE_LIST: {
mPm.writePackageList(msg.arg1);
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index cc1d87916e94..653a882b3447 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -17,6 +17,7 @@
package com.android.server.pm;
import static android.app.admin.DevicePolicyResources.Strings.Core.PACKAGE_DELETED_BY_DO;
+import static android.os.Process.INVALID_UID;
import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
import static org.xmlpull.v1.XmlPullParser.START_TAG;
@@ -847,8 +848,18 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
params.forceQueryableOverride = false;
}
}
+ int requestedInstallerPackageUid = INVALID_UID;
+ if (requestedInstallerPackageName != null) {
+ requestedInstallerPackageUid = snapshot.getPackageUid(requestedInstallerPackageName,
+ 0 /* flags */, userId);
+ }
+ if (requestedInstallerPackageUid == INVALID_UID) {
+ // Requested installer package is invalid, reset it
+ requestedInstallerPackageName = null;
+ }
+
InstallSource installSource = InstallSource.create(installerPackageName,
- originatingPackageName, requestedInstallerPackageName,
+ originatingPackageName, requestedInstallerPackageName, requestedInstallerPackageUid,
installerAttributionTag, params.packageSource);
session = new PackageInstallerSession(mInternalCallback, mContext, mPm, this,
mSilentUpdatePolicy, mInstallThread.getLooper(), mStagingManager, sessionId,
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 2e0022289f92..2ee12bf97823 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -33,6 +33,7 @@ import static android.content.pm.PackageManager.INSTALL_FAILED_PRE_APPROVAL_NOT_
import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_NO_CERTIFICATES;
import static android.content.pm.PackageManager.INSTALL_STAGED;
import static android.content.pm.PackageManager.INSTALL_SUCCEEDED;
+import static android.os.Process.INVALID_UID;
import static android.system.OsConstants.O_CREAT;
import static android.system.OsConstants.O_RDONLY;
import static android.system.OsConstants.O_WRONLY;
@@ -217,6 +218,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
private static final String ATTR_SESSION_ID = "sessionId";
private static final String ATTR_USER_ID = "userId";
private static final String ATTR_INSTALLER_PACKAGE_NAME = "installerPackageName";
+ private static final String ATTR_INSTALLER_PACKAGE_UID = "installerPackageUid";
private static final String ATTR_INSTALLER_ATTRIBUTION_TAG = "installerAttributionTag";
private static final String ATTR_INSTALLER_UID = "installerUid";
private static final String ATTR_INITIATING_PACKAGE_NAME =
@@ -812,7 +814,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
// It may wait for a long time to finish {@code dpmi.canSilentlyInstallPackage}.
// Please don't acquire mLock before calling {@code dpmi.canSilentlyInstallPackage}.
return dpmi != null && dpmi.canSilentlyInstallPackage(
- getInstallSource().installerPackageName, mInstallerUid);
+ getInstallSource().mInstallerPackageName, mInstallerUid);
}
private static final int USER_ACTION_NOT_NEEDED = 0;
@@ -936,7 +938,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
mOriginalInstallerUid = installerUid;
mInstallerUid = installerUid;
mInstallSource = Objects.requireNonNull(installSource);
- mOriginalInstallerPackageName = mInstallSource.installerPackageName;
+ mOriginalInstallerPackageName = mInstallSource.mInstallerPackageName;
this.params = params;
this.createdMillis = createdMillis;
this.updatedMillis = createdMillis;
@@ -1047,8 +1049,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
synchronized (mLock) {
info.sessionId = sessionId;
info.userId = userId;
- info.installerPackageName = mInstallSource.installerPackageName;
- info.installerAttributionTag = mInstallSource.installerAttributionTag;
+ info.installerPackageName = mInstallSource.mInstallerPackageName;
+ info.installerAttributionTag = mInstallSource.mInstallerAttributionTag;
info.resolvedBaseCodePath = (mResolvedBaseFile != null) ?
mResolvedBaseFile.getAbsolutePath() : null;
info.progress = progress;
@@ -1310,10 +1312,10 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
}
final String installerPackageName;
- if (!TextUtils.isEmpty(getInstallSource().initiatingPackageName)) {
- installerPackageName = getInstallSource().initiatingPackageName;
+ if (!TextUtils.isEmpty(getInstallSource().mInitiatingPackageName)) {
+ installerPackageName = getInstallSource().mInitiatingPackageName;
} else {
- installerPackageName = getInstallSource().installerPackageName;
+ installerPackageName = getInstallSource().mInstallerPackageName;
}
if (TextUtils.isEmpty(installerPackageName)) {
throw new IllegalStateException("Installer package is empty.");
@@ -1354,7 +1356,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
@NonNull IOnChecksumsReadyListener onChecksumsReadyListener) {
assertCallerIsOwnerRootOrVerifier();
final File file = new File(stageDir, name);
- final String installerPackageName = getInstallSource().initiatingPackageName;
+ final String installerPackageName = getInstallSource().mInitiatingPackageName;
try {
mPm.requestFileChecksums(file, installerPackageName, optional, required,
trustedInstallers, onChecksumsReadyListener);
@@ -2109,8 +2111,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
}
mInstallerUid = newOwnerAppInfo.uid;
- mInstallSource = InstallSource.create(packageName, null, packageName, null,
- params.packageSource);
+ mInstallSource = InstallSource.create(packageName, null, packageName,
+ mInstallerUid, null, params.packageSource);
}
}
@@ -2179,7 +2181,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
if (isInstallerDeviceOwnerOrAffiliatedProfileOwner()) {
DevicePolicyEventLogger
.createEvent(DevicePolicyEnums.INSTALL_PACKAGE)
- .setAdmin(getInstallSource().installerPackageName)
+ .setAdmin(getInstallSource().mInstallerPackageName)
.write();
}
@@ -2606,7 +2608,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
final int packageUid;
if (returnCode != INSTALL_SUCCEEDED) {
// Package didn't install; no valid uid
- packageUid = Process.INVALID_UID;
+ packageUid = INVALID_UID;
} else {
packageUid = mPm.snapshotComputer().getPackageUid(packageName, 0, userId);
}
@@ -3459,11 +3461,11 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
}
String getInstallerPackageName() {
- return getInstallSource().installerPackageName;
+ return getInstallSource().mInstallerPackageName;
}
String getInstallerAttributionTag() {
- return getInstallSource().installerAttributionTag;
+ return getInstallSource().mInstallerAttributionTag;
}
InstallSource getInstallSource() {
@@ -4451,9 +4453,9 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
pw.printPair("userId", userId);
pw.printPair("mOriginalInstallerUid", mOriginalInstallerUid);
pw.printPair("mOriginalInstallerPackageName", mOriginalInstallerPackageName);
- pw.printPair("installerPackageName", mInstallSource.installerPackageName);
- pw.printPair("installInitiatingPackageName", mInstallSource.initiatingPackageName);
- pw.printPair("installOriginatingPackageName", mInstallSource.originatingPackageName);
+ pw.printPair("installerPackageName", mInstallSource.mInstallerPackageName);
+ pw.printPair("installInitiatingPackageName", mInstallSource.mInitiatingPackageName);
+ pw.printPair("installOriginatingPackageName", mInstallSource.mOriginatingPackageName);
pw.printPair("mInstallerUid", mInstallerUid);
pw.printPair("createdMillis", createdMillis);
pw.printPair("updatedMillis", updatedMillis);
@@ -4642,14 +4644,15 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
out.attributeInt(null, ATTR_SESSION_ID, sessionId);
out.attributeInt(null, ATTR_USER_ID, userId);
writeStringAttribute(out, ATTR_INSTALLER_PACKAGE_NAME,
- mInstallSource.installerPackageName);
+ mInstallSource.mInstallerPackageName);
+ out.attributeInt(null, ATTR_INSTALLER_PACKAGE_UID, mInstallSource.mInstallerPackageUid);
writeStringAttribute(out, ATTR_INSTALLER_ATTRIBUTION_TAG,
- mInstallSource.installerAttributionTag);
+ mInstallSource.mInstallerAttributionTag);
out.attributeInt(null, ATTR_INSTALLER_UID, mInstallerUid);
writeStringAttribute(out, ATTR_INITIATING_PACKAGE_NAME,
- mInstallSource.initiatingPackageName);
+ mInstallSource.mInitiatingPackageName);
writeStringAttribute(out, ATTR_ORIGINATING_PACKAGE_NAME,
- mInstallSource.originatingPackageName);
+ mInstallSource.mOriginatingPackageName);
out.attributeLong(null, ATTR_CREATED_MILLIS, createdMillis);
out.attributeLong(null, ATTR_UPDATED_MILLIS, updatedMillis);
out.attributeLong(null, ATTR_COMMITTED_MILLIS, committedMillis);
@@ -4806,6 +4809,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
final int sessionId = in.getAttributeInt(null, ATTR_SESSION_ID);
final int userId = in.getAttributeInt(null, ATTR_USER_ID);
final String installerPackageName = readStringAttribute(in, ATTR_INSTALLER_PACKAGE_NAME);
+ final int installPackageUid = in.getAttributeInt(null, ATTR_INSTALLER_PACKAGE_UID,
+ INVALID_UID);
final String installerAttributionTag = readStringAttribute(in,
ATTR_INSTALLER_ATTRIBUTION_TAG);
final int installerUid = in.getAttributeInt(null, ATTR_INSTALLER_UID, pm.snapshotComputer()
@@ -4975,8 +4980,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
}
InstallSource installSource = InstallSource.create(installInitiatingPackageName,
- installOriginatingPackageName, installerPackageName, installerAttributionTag,
- params.packageSource);
+ installOriginatingPackageName, installerPackageName, installPackageUid,
+ installerAttributionTag, params.packageSource);
return new PackageInstallerSession(callback, context, pm, sessionProvider,
silentUpdatePolicy, installerThread, stagingManager, sessionId, userId,
installerUid, installSource, params, createdMillis, committedMillis, stageDir,
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 139c6ea28b7d..50eb92645166 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -29,6 +29,7 @@ import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
import static android.content.pm.PackageManager.MATCH_FACTORY_ONLY;
import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.os.Process.INVALID_UID;
import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
import static android.os.storage.StorageManager.FLAG_STORAGE_CE;
import static android.os.storage.StorageManager.FLAG_STORAGE_DE;
@@ -83,7 +84,6 @@ import android.content.pm.IOnChecksumsReadyListener;
import android.content.pm.IPackageDataObserver;
import android.content.pm.IPackageDeleteObserver2;
import android.content.pm.IPackageLoadingProgressCallback;
-import android.content.pm.IPackageManager;
import android.content.pm.IPackageMoveObserver;
import android.content.pm.IncrementalStatesInfo;
import android.content.pm.InstallSourceInfo;
@@ -558,6 +558,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
static final char RANDOM_CODEPATH_PREFIX = '-';
final Handler mHandler;
+ final Handler mBackgroundHandler;
final ProcessLoggingHandler mProcessLoggingHandler;
@@ -873,7 +874,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
// public static final int UNUSED = 5;
static final int POST_INSTALL = 9;
static final int WRITE_SETTINGS = 13;
- static final int WRITE_PACKAGE_RESTRICTIONS = 14;
+ static final int WRITE_DIRTY_PACKAGE_RESTRICTIONS = 14;
static final int PACKAGE_VERIFIED = 15;
static final int CHECK_PENDING_VERIFICATION = 16;
// public static final int UNUSED = 17;
@@ -890,6 +891,8 @@ public class PackageManagerService implements PackageSender, TestUtilityService
static final int PRUNE_UNUSED_STATIC_SHARED_LIBRARIES = 28;
static final int DEFERRED_PENDING_KILL_INSTALL_OBSERVER = 29;
+ static final int WRITE_USER_PACKAGE_RESTRICTIONS = 30;
+
static final int DEFERRED_NO_KILL_POST_DELETE_DELAY_MS = 3 * 1000;
private static final int DEFERRED_NO_KILL_INSTALL_OBSERVER_DELAY_MS = 500;
private static final int DEFERRED_PENDING_KILL_INSTALL_OBSERVER_DELAY_MS = 1000;
@@ -1397,28 +1400,33 @@ public class PackageManagerService implements PackageSender, TestUtilityService
mDirtyUsers.add(userId);
}
}
- if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
- mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
+ if (!mBackgroundHandler.hasMessages(WRITE_DIRTY_PACKAGE_RESTRICTIONS)) {
+ mBackgroundHandler.sendMessageDelayed(
+ mBackgroundHandler.obtainMessage(WRITE_DIRTY_PACKAGE_RESTRICTIONS, this),
+ WRITE_SETTINGS_DELAY);
}
}
void writePendingRestrictions() {
+ final Integer[] dirtyUsers;
synchronized (mLock) {
- mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS);
+ mBackgroundHandler.removeMessages(WRITE_DIRTY_PACKAGE_RESTRICTIONS);
synchronized (mDirtyUsers) {
- for (int userId : mDirtyUsers) {
- mSettings.writePackageRestrictionsLPr(userId);
+ if (mDirtyUsers.isEmpty()) {
+ return;
}
+ dirtyUsers = mDirtyUsers.toArray(Integer[]::new);
mDirtyUsers.clear();
}
}
+ mSettings.writePackageRestrictions(dirtyUsers);
}
- void writeSettings() {
+ void writeSettings(boolean sync) {
synchronized (mLock) {
mHandler.removeMessages(WRITE_SETTINGS);
- mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS);
- writeSettingsLPrTEMP();
+ mBackgroundHandler.removeMessages(WRITE_DIRTY_PACKAGE_RESTRICTIONS);
+ writeSettingsLPrTEMP(sync);
synchronized (mDirtyUsers) {
mDirtyUsers.clear();
}
@@ -1432,7 +1440,27 @@ public class PackageManagerService implements PackageSender, TestUtilityService
}
}
- public static Pair<PackageManagerService, IPackageManager> main(Context context,
+ private static final Handler.Callback BACKGROUND_HANDLER_CALLBACK = new Handler.Callback() {
+ @Override
+ public boolean handleMessage(@NonNull Message msg) {
+ switch (msg.what) {
+ case WRITE_DIRTY_PACKAGE_RESTRICTIONS: {
+ PackageManagerService pm = (PackageManagerService) msg.obj;
+ pm.writePendingRestrictions();
+ return true;
+ }
+ case WRITE_USER_PACKAGE_RESTRICTIONS: {
+ final Runnable r = (Runnable) msg.obj;
+ r.run();
+ return true;
+ }
+ }
+ return false;
+ }
+ };
+
+ /** Starts PackageManagerService. */
+ public static PackageManagerService main(Context context,
Installer installer, @NonNull DomainVerificationService domainVerificationService,
boolean factoryTest) {
// Self-check for initial settings.
@@ -1446,7 +1474,8 @@ public class PackageManagerService implements PackageSender, TestUtilityService
HandlerThread backgroundThread = new ServiceThread("PackageManagerBg",
Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
backgroundThread.start();
- Handler backgroundHandler = new Handler(backgroundThread.getLooper());
+ Handler backgroundHandler = new Handler(backgroundThread.getLooper(),
+ BACKGROUND_HANDLER_CALLBACK);
PackageManagerServiceInjector injector = new PackageManagerServiceInjector(
context, lock, installer, installLock, new PackageAbiHelperImpl(),
@@ -1460,7 +1489,8 @@ public class PackageManagerService implements PackageSender, TestUtilityService
(i, pm) -> new Settings(Environment.getDataDirectory(),
RuntimePermissionsPersistence.createInstance(),
i.getPermissionManagerServiceInternal(),
- domainVerificationService, backgroundHandler, lock),
+ domainVerificationService, backgroundHandler,
+ lock),
(i, pm) -> AppsFilterImpl.create(i,
i.getLocalService(PackageManagerInternal.class)),
(i, pm) -> (PlatformCompat) ServiceManager.getService("platform_compat"),
@@ -1560,7 +1590,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
ServiceManager.addService("package_native", pmn);
LocalManagerRegistry.addManager(PackageManagerLocal.class,
new PackageManagerLocalImpl(m));
- return Pair.create(m, iPackageManager);
+ return m;
}
/** Install/uninstall system packages for all users based on their user-type, as applicable. */
@@ -1638,6 +1668,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
mUserNeedsBadging = new UserNeedsBadgingCache(mUserManager);
mDomainVerificationManager = injector.getDomainVerificationManagerInternal();
mHandler = injector.getHandler();
+ mBackgroundHandler = injector.getBackgroundHandler();
mSharedLibraries = injector.getSharedLibrariesImpl();
mApexManager = testParams.apexManager;
@@ -1828,6 +1859,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
mMoveCallbacks = new MovePackageHelper.MoveCallbacks(FgThread.get().getLooper());
mViewCompiler = injector.getViewCompiler();
mSharedLibraries = mInjector.getSharedLibrariesImpl();
+ mBackgroundHandler = injector.getBackgroundHandler();
mContext.getSystemService(DisplayManager.class)
.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(mMetrics);
@@ -2902,9 +2934,9 @@ public class PackageManagerService implements PackageSender, TestUtilityService
mPackageUsage.writeNow(mSettings.getPackagesLocked());
if (mHandler.hasMessages(WRITE_SETTINGS)
- || mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)
+ || mBackgroundHandler.hasMessages(WRITE_DIRTY_PACKAGE_RESTRICTIONS)
|| mHandler.hasMessages(WRITE_PACKAGE_LIST)) {
- writeSettings();
+ writeSettings(/*sync=*/true);
}
}
}
@@ -3037,7 +3069,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
int userId) {
final PackageRemovedInfo info = new PackageRemovedInfo(this);
info.mRemovedPackage = packageName;
- info.mInstallerPackageName = packageState.getInstallSource().installerPackageName;
+ info.mInstallerPackageName = packageState.getInstallSource().mInstallerPackageName;
info.mRemovedUsers = new int[] {userId};
info.mBroadcastUsers = new int[] {userId};
info.mUid = UserHandle.getUid(userId, packageState.getAppId());
@@ -3968,7 +4000,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
synchronized (mDirtyUsers) {
mDirtyUsers.remove(userId);
if (mDirtyUsers.isEmpty()) {
- mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS);
+ mBackgroundHandler.removeMessages(WRITE_DIRTY_PACKAGE_RESTRICTIONS);
}
}
}
@@ -4461,7 +4493,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
if (wasNotLaunched) {
final String installerPackageName =
- packageState.getInstallSource().installerPackageName;
+ packageState.getInstallSource().mInstallerPackageName;
if (installerPackageName != null) {
notifyFirstLaunch(packageName, installerPackageName, userId);
}
@@ -5255,10 +5287,6 @@ public class PackageManagerService implements PackageSender, TestUtilityService
Map<String, String> classLoaderContextMap,
String loaderIsa) {
int callingUid = Binder.getCallingUid();
-
- // TODO(b/254043366): System server should not report its own dex load because there's
- // nothing ART can do with it.
-
Computer snapshot = snapshot();
// System server should be able to report dex load on behalf of other apps. E.g., it
@@ -5445,7 +5473,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
}
if (!Objects.equals(callerPackageName,
- packageState.getInstallSource().installerPackageName)) {
+ packageState.getInstallSource().mInstallerPackageName)) {
throw new IllegalArgumentException("Calling package " + callerPackageName
+ " is not installer for " + packageName);
}
@@ -5678,7 +5706,8 @@ public class PackageManagerService implements PackageSender, TestUtilityService
}
@Override
- public void setInstallerPackageName(String targetPackage, String installerPackageName) {
+ public void setInstallerPackageName(String targetPackage,
+ @Nullable String installerPackageName) {
final int callingUid = Binder.getCallingUid();
final int callingUserId = UserHandle.getUserId(callingUid);
final FunctionalUtils.ThrowingCheckedFunction<Computer, Boolean, RuntimeException>
@@ -5733,7 +5762,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
// Verify: if target already has an installer package, it must
// be signed with the same cert as the caller.
String targetInstallerPackageName =
- targetPackageState.getInstallSource().installerPackageName;
+ targetPackageState.getInstallSource().mInstallerPackageName;
PackageStateInternal targetInstallerPkgSetting = targetInstallerPackageName == null
? null : snapshot.getPackageStateInternal(targetInstallerPackageName);
@@ -5776,16 +5805,21 @@ public class PackageManagerService implements PackageSender, TestUtilityService
if (allowed) {
// TODO: Need to lock around here to handle mSettings.addInstallerPackageNames,
// should find an alternative which avoids any race conditions
+ final int installerPackageUid = installerPackageName == null
+ ? INVALID_UID : snapshotComputer().getPackageUid(installerPackageName,
+ 0 /* flags */, callingUserId);
PackageStateInternal targetPackageState;
synchronized (mLock) {
PackageStateMutator.Result result = commitPackageStateMutation(initialState,
- targetPackage, state -> state.setInstaller(installerPackageName));
+ targetPackage, state -> state.setInstaller(installerPackageName,
+ installerPackageUid));
if (result.isPackagesChanged() || result.isStateChanged()) {
synchronized (mPackageStateWriteLock) {
allowed = implementation.apply(snapshotComputer());
if (allowed) {
commitPackageStateMutation(null, targetPackage,
- state -> state.setInstaller(installerPackageName));
+ state -> state.setInstaller(installerPackageName,
+ installerPackageUid));
} else {
return;
}
@@ -6867,9 +6901,14 @@ public class PackageManagerService implements PackageSender, TestUtilityService
* TODO: In the meantime, can this be moved to a schedule call?
* TODO(b/182523293): This should be removed once we finish migration of permission storage.
*/
- void writeSettingsLPrTEMP() {
+ void writeSettingsLPrTEMP(boolean sync) {
mPermissionManager.writeLegacyPermissionsTEMP(mSettings.mPermissions);
- mSettings.writeLPr(mLiveComputer);
+ mSettings.writeLPr(mLiveComputer, sync);
+ }
+
+ // Default async version.
+ void writeSettingsLPrTEMP() {
+ writeSettingsLPrTEMP(/*sync=*/false);
}
@Override
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index 9f21f114560e..cc1306dbc2b3 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -88,7 +88,6 @@ import android.os.ServiceManager;
import android.os.ServiceSpecificException;
import android.os.ShellCommand;
import android.os.SystemClock;
-import android.os.SystemProperties;
import android.os.Trace;
import android.os.UserHandle;
import android.os.UserManager;
@@ -1787,13 +1786,11 @@ class PackageManagerShellCommand extends ShellCommand {
private int runCompile() throws RemoteException {
final PrintWriter pw = getOutPrintWriter();
- boolean checkProfiles = SystemProperties.getBoolean("dalvik.vm.usejitprofiles", false);
boolean forceCompilation = false;
boolean allPackages = false;
boolean clearProfileData = false;
String compilerFilter = null;
String compilationReason = null;
- String checkProfilesRaw = null;
boolean secondaryDex = false;
String split = null;
@@ -1816,7 +1813,9 @@ class PackageManagerShellCommand extends ShellCommand {
compilationReason = getNextArgRequired();
break;
case "--check-prof":
- checkProfilesRaw = getNextArgRequired();
+ getNextArgRequired();
+ pw.println("Warning: Ignoring obsolete flag --check-prof "
+ + "- it is unconditionally enabled now");
break;
case "--reset":
forceCompilation = true;
@@ -1835,17 +1834,6 @@ class PackageManagerShellCommand extends ShellCommand {
}
}
- if (checkProfilesRaw != null) {
- if ("true".equals(checkProfilesRaw)) {
- checkProfiles = true;
- } else if ("false".equals(checkProfilesRaw)) {
- checkProfiles = false;
- } else {
- pw.println("Invalid value for \"--check-prof\". Expected \"true\" or \"false\".");
- return 1;
- }
- }
-
final boolean compilerFilterGiven = compilerFilter != null;
final boolean compilationReasonGiven = compilationReason != null;
// Make sure exactly one of -m, or -r is given.
@@ -1922,11 +1910,10 @@ class PackageManagerShellCommand extends ShellCommand {
}
final boolean result = secondaryDex
- ? mInterface.performDexOptSecondary(packageName,
- targetCompilerFilter, forceCompilation)
- : mInterface.performDexOptMode(packageName,
- checkProfiles, targetCompilerFilter, forceCompilation,
- true /* bootComplete */, split);
+ ? mInterface.performDexOptSecondary(
+ packageName, targetCompilerFilter, forceCompilation)
+ : mInterface.performDexOptMode(packageName, true /* checkProfiles */,
+ targetCompilerFilter, forceCompilation, true /* bootComplete */, split);
if (!result) {
failedPackages.add(packageName);
}
diff --git a/services/core/java/com/android/server/pm/PackageMetrics.java b/services/core/java/com/android/server/pm/PackageMetrics.java
index 0574f737a54b..3dcf9260f829 100644
--- a/services/core/java/com/android/server/pm/PackageMetrics.java
+++ b/services/core/java/com/android/server/pm/PackageMetrics.java
@@ -16,8 +16,6 @@
package com.android.server.pm;
-import static android.os.Process.INVALID_UID;
-
import android.annotation.IntDef;
import android.content.pm.PackageManager;
import android.content.pm.parsing.ApkLiteParseUtils;
@@ -26,7 +24,6 @@ import android.util.SparseArray;
import com.android.internal.util.FrameworkStatsLog;
import com.android.server.LocalServices;
-import com.android.server.pm.pkg.PackageStateInternal;
import java.io.File;
import java.io.IOException;
@@ -68,32 +65,46 @@ final class PackageMetrics {
mInstallRequest = installRequest;
}
- public void onInstallSucceed(Computer snapshot) {
+ public void onInstallSucceed() {
// TODO(b/239722919): report to SecurityLog if on work profile or managed device
- reportInstallationStats(snapshot, true /* success */);
+ reportInstallationStats(true /* success */);
+ }
+
+ public void onInstallFailed() {
+ reportInstallationStats(false /* success */);
}
- private void reportInstallationStats(Computer snapshot, boolean success) {
+ private void reportInstallationStats(boolean success) {
UserManagerInternal userManagerInternal =
LocalServices.getService(UserManagerInternal.class);
- // TODO(b/249294752): do not log if adb
final long installDurationMillis =
System.currentTimeMillis() - mInstallStartTimestampMillis;
// write to stats
final Pair<int[], long[]> stepDurations = getInstallStepDurations();
final int[] newUsers = mInstallRequest.getNewUsers();
final int[] originalUsers = mInstallRequest.getOriginUsers();
- final String packageName = mInstallRequest.getName();
- final String installerPackageName = mInstallRequest.getInstallerPackageName();
- final int installerUid = installerPackageName == null ? INVALID_UID
- : snapshot.getPackageUid(installerPackageName, 0, 0);
- final PackageStateInternal ps = snapshot.getPackageStateInternal(packageName);
- final long versionCode = success ? 0 : ps.getVersionCode();
- final long apksSize = getApksSize(ps.getPath());
+ final String packageName;
+ // only reporting package name for failed non-adb installations
+ if (success || mInstallRequest.isInstallFromAdb()) {
+ packageName = null;
+ } else {
+ packageName = mInstallRequest.getName();
+ }
+
+ final int installerPackageUid = mInstallRequest.getInstallerPackageUid();
+
+ long versionCode = 0, apksSize = 0;
+ if (success) {
+ final PackageSetting ps = mInstallRequest.getScannedPackageSetting();
+ if (ps != null) {
+ versionCode = ps.getVersionCode();
+ apksSize = getApksSize(ps.getPath());
+ }
+ }
FrameworkStatsLog.write(FrameworkStatsLog.PACKAGE_INSTALLATION_SESSION_REPORTED,
mInstallRequest.getSessionId() /* session_id */,
- success ? null : packageName /* not report package_name on success */,
+ packageName /* package_name */,
mInstallRequest.getUid() /* uid */,
newUsers /* user_ids */,
userManagerInternal.getUserTypesForStatsd(newUsers) /* user_types */,
@@ -107,7 +118,7 @@ final class PackageMetrics {
stepDurations.second /* step_duration_millis */,
installDurationMillis /* total_duration_millis */,
mInstallRequest.getInstallFlags() /* install_flags */,
- installerUid /* installer_package_uid */,
+ installerPackageUid /* installer_package_uid */,
-1 /* original_installer_package_uid */,
mInstallRequest.getDataLoaderType() /* data_loader_type */,
mInstallRequest.getRequireUserAction() /* user_action_required_type */,
diff --git a/services/core/java/com/android/server/pm/PackageSessionVerifier.java b/services/core/java/com/android/server/pm/PackageSessionVerifier.java
index 28a021bf4c45..434a62da88c9 100644
--- a/services/core/java/com/android/server/pm/PackageSessionVerifier.java
+++ b/services/core/java/com/android/server/pm/PackageSessionVerifier.java
@@ -483,7 +483,7 @@ final class PackageSessionVerifier {
return;
}
final String packageName = session.getPackageName();
- final String installerPackageName = session.getInstallSource().installerPackageName;
+ final String installerPackageName = session.getInstallSource().mInstallerPackageName;
if (!isApexUpdateAllowed(packageName, installerPackageName)) {
throw new PackageManagerException(
PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE,
diff --git a/services/core/java/com/android/server/pm/PackageSetting.java b/services/core/java/com/android/server/pm/PackageSetting.java
index 8d6abe05db0e..6d90593c2f48 100644
--- a/services/core/java/com/android/server/pm/PackageSetting.java
+++ b/services/core/java/com/android/server/pm/PackageSetting.java
@@ -277,7 +277,7 @@ public class PackageSetting extends SettingBase implements PackageStateInternal
proto.write(PackageProto.UID, mAppId);
proto.write(PackageProto.VERSION_CODE, versionCode);
proto.write(PackageProto.UPDATE_TIME_MS, lastUpdateTime);
- proto.write(PackageProto.INSTALLER_NAME, installSource.installerPackageName);
+ proto.write(PackageProto.INSTALLER_NAME, installSource.mInstallerPackageName);
if (pkg != null) {
proto.write(PackageProto.VERSION_STRING, pkg.getVersionName());
@@ -297,9 +297,9 @@ public class PackageSetting extends SettingBase implements PackageStateInternal
long sourceToken = proto.start(PackageProto.INSTALL_SOURCE);
proto.write(PackageProto.InstallSourceProto.INITIATING_PACKAGE_NAME,
- installSource.initiatingPackageName);
+ installSource.mInitiatingPackageName);
proto.write(PackageProto.InstallSourceProto.ORIGINATING_PACKAGE_NAME,
- installSource.originatingPackageName);
+ installSource.mOriginatingPackageName);
proto.end(sourceToken);
}
proto.write(PackageProto.StatesProto.IS_LOADING, isLoading());
@@ -360,8 +360,10 @@ public class PackageSetting extends SettingBase implements PackageStateInternal
return this;
}
- public PackageSetting setInstallerPackageName(String packageName) {
- installSource = installSource.setInstallerPackage(packageName);
+ public PackageSetting setInstallerPackage(@Nullable String installerPackageName,
+ int installerPackageUid) {
+ installSource = installSource.setInstallerPackage(installerPackageName,
+ installerPackageUid);
onChanged();
return this;
}
@@ -372,7 +374,7 @@ public class PackageSetting extends SettingBase implements PackageStateInternal
return this;
}
- PackageSetting removeInstallerPackage(String packageName) {
+ PackageSetting removeInstallerPackage(@Nullable String packageName) {
installSource = installSource.removeInstallerPackage(packageName);
onChanged();
return this;
diff --git a/services/core/java/com/android/server/pm/RemovePackageHelper.java b/services/core/java/com/android/server/pm/RemovePackageHelper.java
index 7e936735ef7d..8c58397fb1a1 100644
--- a/services/core/java/com/android/server/pm/RemovePackageHelper.java
+++ b/services/core/java/com/android/server/pm/RemovePackageHelper.java
@@ -269,7 +269,7 @@ final class RemovePackageHelper {
final AndroidPackage deletedPkg = deletedPs.getPkg();
if (outInfo != null) {
outInfo.mRemovedPackage = packageName;
- outInfo.mInstallerPackageName = deletedPs.getInstallSource().installerPackageName;
+ outInfo.mInstallerPackageName = deletedPs.getInstallSource().mInstallerPackageName;
outInfo.mIsStaticSharedLib = deletedPkg != null
&& deletedPkg.getStaticSharedLibraryName() != null;
outInfo.populateUsers(deletedPs.queryInstalledUsers(
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index e33cc9ff0983..a40d40467735 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -29,6 +29,7 @@ import static android.os.Process.PACKAGE_INFO_GID;
import static android.os.Process.SYSTEM_UID;
import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
+import static com.android.server.pm.PackageManagerService.WRITE_USER_PACKAGE_RESTRICTIONS;
import static com.android.server.pm.SharedUidMigration.BEST_EFFORT;
import android.annotation.NonNull;
@@ -56,7 +57,6 @@ import android.net.Uri;
import android.os.Binder;
import android.os.Build;
import android.os.CreateAppDataArgs;
-import android.os.Environment;
import android.os.FileUtils;
import android.os.Handler;
import android.os.Message;
@@ -376,6 +376,13 @@ public final class Settings implements Watchable, Snappable {
/** The top level directory in configfs for sdcardfs to push the package->uid,userId mappings */
private final File mKernelMappingFilename;
+ // Lock for user package restrictions operations.
+ private final Object mPackageRestrictionsLock = new Object();
+
+ // Pending write operations.
+ @GuardedBy("mPackageRestrictionsLock")
+ private final SparseIntArray mPendingAsyncPackageRestrictionsWrites = new SparseIntArray();
+
/** Map from package name to settings */
@Watched
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
@@ -1476,31 +1483,46 @@ public final class Settings implements Watchable, Snappable {
return (userId == UserHandle.USER_ALL) ? null : mDefaultBrowserApp.removeReturnOld(userId);
}
- private File getUserPackagesStateFile(int userId) {
- // TODO: Implement a cleaner solution when adding tests.
+ private File getUserSystemDirectory(int userId) {
// This instead of Environment.getUserSystemDirectory(userId) to support testing.
- File userDir = new File(new File(mSystemDir, "users"), Integer.toString(userId));
- return new File(userDir, "package-restrictions.xml");
+ return new File(new File(mSystemDir, "users"), Integer.toString(userId));
}
- private File getUserRuntimePermissionsFile(int userId) {
- // TODO: Implement a cleaner solution when adding tests.
- // This instead of Environment.getUserSystemDirectory(userId) to support testing.
- File userDir = new File(new File(mSystemDir, "users"), Integer.toString(userId));
- return new File(userDir, RUNTIME_PERMISSIONS_FILE_NAME);
+ // The method itself does not have to be guarded, but the file does.
+ @GuardedBy("mPackageRestrictionsLock")
+ private File getUserPackagesStateFile(int userId) {
+ return new File(getUserSystemDirectory(userId), "package-restrictions.xml");
}
+ // The method itself does not have to be guarded, but the file does.
+ @GuardedBy("mPackageRestrictionsLock")
private File getUserPackagesStateBackupFile(int userId) {
- return new File(Environment.getUserSystemDirectory(userId),
- "package-restrictions-backup.xml");
+ return new File(getUserSystemDirectory(userId), "package-restrictions-backup.xml");
}
+ private File getUserRuntimePermissionsFile(int userId) {
+ return new File(getUserSystemDirectory(userId), RUNTIME_PERMISSIONS_FILE_NAME);
+ }
+
+ // Default version is writing restrictions asynchronously.
void writeAllUsersPackageRestrictionsLPr() {
+ writeAllUsersPackageRestrictionsLPr(/*sync=*/false);
+ }
+
+ void writeAllUsersPackageRestrictionsLPr(boolean sync) {
List<UserInfo> users = getAllUsers(UserManagerService.getInstance());
if (users == null) return;
+ if (sync) {
+ // Cancel all pending per-user writes.
+ synchronized (mPackageRestrictionsLock) {
+ mPendingAsyncPackageRestrictionsWrites.clear();
+ }
+ mHandler.removeMessages(WRITE_USER_PACKAGE_RESTRICTIONS);
+ }
+
for (UserInfo user : users) {
- writePackageRestrictionsLPr(user.id);
+ writePackageRestrictionsLPr(user.id, sync);
}
}
@@ -1691,63 +1713,75 @@ public final class Settings implements Watchable, Snappable {
Log.i(TAG, "Reading package restrictions for user=" + userId);
}
FileInputStream str = null;
- File userPackagesStateFile = getUserPackagesStateFile(userId);
- File backupFile = getUserPackagesStateBackupFile(userId);
- if (backupFile.exists()) {
- try {
- str = new FileInputStream(backupFile);
- mReadMessages.append("Reading from backup stopped packages file\n");
- PackageManagerService.reportSettingsProblem(Log.INFO,
- "Need to read from backup stopped packages file");
- if (userPackagesStateFile.exists()) {
- // If both the backup and normal file exist, we
- // ignore the normal one since it might have been
- // corrupted.
- Slog.w(PackageManagerService.TAG, "Cleaning up stopped packages file "
- + userPackagesStateFile);
- userPackagesStateFile.delete();
+
+ synchronized (mPackageRestrictionsLock) {
+ File userPackagesStateFile = getUserPackagesStateFile(userId);
+ File backupFile = getUserPackagesStateBackupFile(userId);
+ if (backupFile.exists()) {
+ try {
+ str = new FileInputStream(backupFile);
+ mReadMessages.append("Reading from backup stopped packages file\n");
+ PackageManagerService.reportSettingsProblem(Log.INFO,
+ "Need to read from backup stopped packages file");
+ if (userPackagesStateFile.exists()) {
+ // If both the backup and normal file exist, we
+ // ignore the normal one since it might have been
+ // corrupted.
+ Slog.w(PackageManagerService.TAG, "Cleaning up stopped packages file "
+ + userPackagesStateFile);
+ userPackagesStateFile.delete();
+ }
+ } catch (java.io.IOException e) {
+ // We'll try for the normal settings file.
+ }
+ }
+
+ if (str == null && userPackagesStateFile.exists()) {
+ try {
+ str = new FileInputStream(userPackagesStateFile);
+ if (DEBUG_MU) Log.i(TAG, "Reading " + userPackagesStateFile);
+ } catch (java.io.IOException e) {
+ mReadMessages.append("Error reading: " + e.toString());
+ PackageManagerService.reportSettingsProblem(Log.ERROR,
+ "Error reading settings: " + e);
+ Slog.wtf(TAG, "Error reading package manager stopped packages", e);
}
- } catch (java.io.IOException e) {
- // We'll try for the normal settings file.
}
}
- try {
- if (str == null) {
- if (!userPackagesStateFile.exists()) {
- mReadMessages.append("No stopped packages file found\n");
- PackageManagerService.reportSettingsProblem(Log.INFO,
- "No stopped packages file; "
+ if (str == null) {
+ mReadMessages.append("No stopped packages file found\n");
+ PackageManagerService.reportSettingsProblem(Log.INFO,
+ "No stopped packages file; "
+ "assuming all started");
- // At first boot, make sure no packages are stopped.
- // We usually want to have third party apps initialize
- // in the stopped state, but not at first boot. Also
- // consider all applications to be installed.
- for (PackageSetting pkg : mPackages.values()) {
- pkg.setUserState(userId, 0, COMPONENT_ENABLED_STATE_DEFAULT,
- true /*installed*/,
- false /*stopped*/,
- false /*notLaunched*/,
- false /*hidden*/,
- 0 /*distractionFlags*/,
- null /*suspendParams*/,
- false /*instantApp*/,
- false /*virtualPreload*/,
- null /*lastDisableAppCaller*/,
- null /*enabledComponents*/,
- null /*disabledComponents*/,
- PackageManager.INSTALL_REASON_UNKNOWN,
- PackageManager.UNINSTALL_REASON_UNKNOWN,
- null /*harmfulAppWarning*/,
- null /* splashScreenTheme*/,
- 0 /*firstInstallTime*/
- );
- }
- return;
- }
- str = new FileInputStream(userPackagesStateFile);
- if (DEBUG_MU) Log.i(TAG, "Reading " + userPackagesStateFile);
+ // At first boot, make sure no packages are stopped.
+ // We usually want to have third party apps initialize
+ // in the stopped state, but not at first boot. Also
+ // consider all applications to be installed.
+ for (PackageSetting pkg : mPackages.values()) {
+ pkg.setUserState(userId, 0, COMPONENT_ENABLED_STATE_DEFAULT,
+ true /*installed*/,
+ false /*stopped*/,
+ false /*notLaunched*/,
+ false /*hidden*/,
+ 0 /*distractionFlags*/,
+ null /*suspendParams*/,
+ false /*instantApp*/,
+ false /*virtualPreload*/,
+ null /*lastDisableAppCaller*/,
+ null /*enabledComponents*/,
+ null /*disabledComponents*/,
+ PackageManager.INSTALL_REASON_UNKNOWN,
+ PackageManager.UNINSTALL_REASON_UNKNOWN,
+ null /*harmfulAppWarning*/,
+ null /* splashScreenTheme*/,
+ 0 /*firstInstallTime*/
+ );
}
+ return;
+ }
+
+ try {
final TypedXmlPullParser parser = Xml.resolvePullParser(str);
int type;
@@ -2070,179 +2104,247 @@ public final class Settings implements Watchable, Snappable {
}
}
+ // Default version is writing restrictions asynchronously.
void writePackageRestrictionsLPr(int userId) {
+ writePackageRestrictionsLPr(userId, /*sync=*/false);
+ }
+
+ void writePackageRestrictionsLPr(int userId, boolean sync) {
invalidatePackageCache();
+ final long startTime = SystemClock.uptimeMillis();
+
+ if (sync) {
+ writePackageRestrictions(userId, startTime, sync);
+ } else {
+ if (DEBUG_MU) {
+ Log.i(TAG, "Scheduling deferred IO sync for user=" + userId);
+ }
+ synchronized (mPackageRestrictionsLock) {
+ int pending = mPendingAsyncPackageRestrictionsWrites.get(userId, 0) + 1;
+ mPendingAsyncPackageRestrictionsWrites.put(userId, pending);
+ }
+ Runnable r = () -> writePackageRestrictions(userId, startTime, sync);
+ mHandler.obtainMessage(WRITE_USER_PACKAGE_RESTRICTIONS, r).sendToTarget();
+ }
+ }
+
+ void writePackageRestrictions(Integer[] userIds) {
+ invalidatePackageCache();
+ final long startTime = SystemClock.uptimeMillis();
+ for (int userId : userIds) {
+ writePackageRestrictions(userId, startTime, /*sync=*/true);
+ }
+ }
+
+ void writePackageRestrictions(int userId, long startTime, boolean sync) {
if (DEBUG_MU) {
Log.i(TAG, "Writing package restrictions for user=" + userId);
}
- final long startTime = SystemClock.uptimeMillis();
- // Keep the old stopped packages around until we know the new ones have
- // been successfully written.
- File userPackagesStateFile = getUserPackagesStateFile(userId);
- File backupFile = getUserPackagesStateBackupFile(userId);
- new File(userPackagesStateFile.getParent()).mkdirs();
- if (userPackagesStateFile.exists()) {
- // Presence of backup settings file indicates that we failed
- // to persist packages earlier. So preserve the older
- // backup for future reference since the current packages
- // might have been corrupted.
- if (!backupFile.exists()) {
- if (!userPackagesStateFile.renameTo(backupFile)) {
- Slog.wtf(PackageManagerService.TAG,
- "Unable to backup user packages state file, "
- + "current changes will be lost at reboot");
+ final File userPackagesStateFile;
+ final File backupFile;
+ final FileOutputStream fstr;
+
+ synchronized (mPackageRestrictionsLock) {
+ if (!sync) {
+ int pending = mPendingAsyncPackageRestrictionsWrites.get(userId, 0) - 1;
+ if (pending < 0) {
+ Log.i(TAG, "Cancel writing package restrictions for user=" + userId);
return;
}
- } else {
- userPackagesStateFile.delete();
- Slog.w(PackageManagerService.TAG, "Preserving older stopped packages backup");
+ mPendingAsyncPackageRestrictionsWrites.put(userId, pending);
+ }
+
+ // Keep the old stopped packages around until we know the new ones have
+ // been successfully written.
+ userPackagesStateFile = getUserPackagesStateFile(userId);
+ backupFile = getUserPackagesStateBackupFile(userId);
+ new File(userPackagesStateFile.getParent()).mkdirs();
+ if (userPackagesStateFile.exists()) {
+ // Presence of backup settings file indicates that we failed
+ // to persist packages earlier. So preserve the older
+ // backup for future reference since the current packages
+ // might have been corrupted.
+ if (!backupFile.exists()) {
+ if (!userPackagesStateFile.renameTo(backupFile)) {
+ Slog.wtf(PackageManagerService.TAG,
+ "Unable to backup user packages state file, "
+ + "current changes will be lost at reboot");
+ return;
+ }
+ } else {
+ userPackagesStateFile.delete();
+ Slog.w(PackageManagerService.TAG, "Preserving older stopped packages backup");
+ }
+ }
+
+ try {
+ fstr = new FileOutputStream(userPackagesStateFile);
+ // File is created, set permissions.
+ FileUtils.setPermissions(userPackagesStateFile.toString(),
+ FileUtils.S_IRUSR | FileUtils.S_IWUSR
+ | FileUtils.S_IRGRP | FileUtils.S_IWGRP,
+ -1, -1);
+ } catch (java.io.IOException e) {
+ Slog.wtf(PackageManagerService.TAG,
+ "Unable to write package manager user packages state, "
+ + " current changes will be lost at reboot", e);
+ return;
}
}
try {
- final FileOutputStream fstr = new FileOutputStream(userPackagesStateFile);
- final TypedXmlSerializer serializer = Xml.resolveSerializer(fstr);
- serializer.startDocument(null, true);
- serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
+ synchronized (mLock) {
+ final TypedXmlSerializer serializer = Xml.resolveSerializer(fstr);
+ serializer.startDocument(null, true);
+ serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output",
+ true);
- serializer.startTag(null, TAG_PACKAGE_RESTRICTIONS);
+ serializer.startTag(null, TAG_PACKAGE_RESTRICTIONS);
- if (DEBUG_MU) {
- Slogf.i(TAG, "Writing %s (%d packages)", userPackagesStateFile,
- mPackages.values().size());
- }
- for (final PackageSetting pkg : mPackages.values()) {
- final PackageUserStateInternal ustate = pkg.readUserState(userId);
if (DEBUG_MU) {
- Log.v(TAG, " pkg=" + pkg.getPackageName()
- + ", installed=" + ustate.isInstalled()
- + ", state=" + ustate.getEnabledState());
- }
+ Slogf.i(TAG, "Writing %s (%d packages)", userPackagesStateFile,
+ mPackages.values().size());
+ }
+ for (final PackageSetting pkg : mPackages.values()) {
+ final PackageUserStateInternal ustate = pkg.readUserState(userId);
+ if (DEBUG_MU) {
+ Log.v(TAG, " pkg=" + pkg.getPackageName()
+ + ", installed=" + ustate.isInstalled()
+ + ", state=" + ustate.getEnabledState());
+ }
- serializer.startTag(null, TAG_PACKAGE);
- serializer.attribute(null, ATTR_NAME, pkg.getPackageName());
- if (ustate.getCeDataInode() != 0) {
- serializer.attributeLong(null, ATTR_CE_DATA_INODE, ustate.getCeDataInode());
- }
- if (!ustate.isInstalled()) {
- serializer.attributeBoolean(null, ATTR_INSTALLED, false);
- }
- if (ustate.isStopped()) {
- serializer.attributeBoolean(null, ATTR_STOPPED, true);
- }
- if (ustate.isNotLaunched()) {
- serializer.attributeBoolean(null, ATTR_NOT_LAUNCHED, true);
- }
- if (ustate.isHidden()) {
- serializer.attributeBoolean(null, ATTR_HIDDEN, true);
- }
- if (ustate.getDistractionFlags() != 0) {
- serializer.attributeInt(null, ATTR_DISTRACTION_FLAGS,
- ustate.getDistractionFlags());
- }
- if (ustate.isSuspended()) {
- serializer.attributeBoolean(null, ATTR_SUSPENDED, true);
- }
- if (ustate.isInstantApp()) {
- serializer.attributeBoolean(null, ATTR_INSTANT_APP, true);
- }
- if (ustate.isVirtualPreload()) {
- serializer.attributeBoolean(null, ATTR_VIRTUAL_PRELOAD, true);
- }
- if (ustate.getEnabledState() != COMPONENT_ENABLED_STATE_DEFAULT) {
- serializer.attributeInt(null, ATTR_ENABLED, ustate.getEnabledState());
- if (ustate.getLastDisableAppCaller() != null) {
- serializer.attribute(null, ATTR_ENABLED_CALLER,
- ustate.getLastDisableAppCaller());
+ serializer.startTag(null, TAG_PACKAGE);
+ serializer.attribute(null, ATTR_NAME, pkg.getPackageName());
+ if (ustate.getCeDataInode() != 0) {
+ serializer.attributeLong(null, ATTR_CE_DATA_INODE, ustate.getCeDataInode());
}
- }
- if (ustate.getInstallReason() != PackageManager.INSTALL_REASON_UNKNOWN) {
- serializer.attributeInt(null, ATTR_INSTALL_REASON,
- ustate.getInstallReason());
- }
- serializer.attributeLongHex(null, ATTR_FIRST_INSTALL_TIME,
- ustate.getFirstInstallTime());
- if (ustate.getUninstallReason() != PackageManager.UNINSTALL_REASON_UNKNOWN) {
- serializer.attributeInt(null, ATTR_UNINSTALL_REASON,
- ustate.getUninstallReason());
- }
- if (ustate.getHarmfulAppWarning() != null) {
- serializer.attribute(null, ATTR_HARMFUL_APP_WARNING,
- ustate.getHarmfulAppWarning());
- }
- if (ustate.getSplashScreenTheme() != null) {
- serializer.attribute(null, ATTR_SPLASH_SCREEN_THEME,
- ustate.getSplashScreenTheme());
- }
- if (ustate.isSuspended()) {
- for (int i = 0; i < ustate.getSuspendParams().size(); i++) {
- final String suspendingPackage = ustate.getSuspendParams().keyAt(i);
- serializer.startTag(null, TAG_SUSPEND_PARAMS);
- serializer.attribute(null, ATTR_SUSPENDING_PACKAGE, suspendingPackage);
- final SuspendParams params =
- ustate.getSuspendParams().valueAt(i);
- if (params != null) {
- params.saveToXml(serializer);
+ if (!ustate.isInstalled()) {
+ serializer.attributeBoolean(null, ATTR_INSTALLED, false);
+ }
+ if (ustate.isStopped()) {
+ serializer.attributeBoolean(null, ATTR_STOPPED, true);
+ }
+ if (ustate.isNotLaunched()) {
+ serializer.attributeBoolean(null, ATTR_NOT_LAUNCHED, true);
+ }
+ if (ustate.isHidden()) {
+ serializer.attributeBoolean(null, ATTR_HIDDEN, true);
+ }
+ if (ustate.getDistractionFlags() != 0) {
+ serializer.attributeInt(null, ATTR_DISTRACTION_FLAGS,
+ ustate.getDistractionFlags());
+ }
+ if (ustate.isSuspended()) {
+ serializer.attributeBoolean(null, ATTR_SUSPENDED, true);
+ }
+ if (ustate.isInstantApp()) {
+ serializer.attributeBoolean(null, ATTR_INSTANT_APP, true);
+ }
+ if (ustate.isVirtualPreload()) {
+ serializer.attributeBoolean(null, ATTR_VIRTUAL_PRELOAD, true);
+ }
+ if (ustate.getEnabledState() != COMPONENT_ENABLED_STATE_DEFAULT) {
+ serializer.attributeInt(null, ATTR_ENABLED, ustate.getEnabledState());
+ if (ustate.getLastDisableAppCaller() != null) {
+ serializer.attribute(null, ATTR_ENABLED_CALLER,
+ ustate.getLastDisableAppCaller());
}
- serializer.endTag(null, TAG_SUSPEND_PARAMS);
}
- }
- final ArraySet<String> enabledComponents = ustate.getEnabledComponents();
- if (enabledComponents != null && enabledComponents.size() > 0) {
- serializer.startTag(null, TAG_ENABLED_COMPONENTS);
- for (int i = 0; i < enabledComponents.size(); i++) {
- serializer.startTag(null, TAG_ITEM);
- serializer.attribute(null, ATTR_NAME,
- enabledComponents.valueAt(i));
- serializer.endTag(null, TAG_ITEM);
+ if (ustate.getInstallReason() != PackageManager.INSTALL_REASON_UNKNOWN) {
+ serializer.attributeInt(null, ATTR_INSTALL_REASON,
+ ustate.getInstallReason());
}
- serializer.endTag(null, TAG_ENABLED_COMPONENTS);
- }
- final ArraySet<String> disabledComponents = ustate.getDisabledComponents();
- if (disabledComponents != null && disabledComponents.size() > 0) {
- serializer.startTag(null, TAG_DISABLED_COMPONENTS);
- for (int i = 0; i < disabledComponents.size(); i++) {
- serializer.startTag(null, TAG_ITEM);
- serializer.attribute(null, ATTR_NAME,
- disabledComponents.valueAt(i));
- serializer.endTag(null, TAG_ITEM);
+ serializer.attributeLongHex(null, ATTR_FIRST_INSTALL_TIME,
+ ustate.getFirstInstallTime());
+ if (ustate.getUninstallReason() != PackageManager.UNINSTALL_REASON_UNKNOWN) {
+ serializer.attributeInt(null, ATTR_UNINSTALL_REASON,
+ ustate.getUninstallReason());
+ }
+ if (ustate.getHarmfulAppWarning() != null) {
+ serializer.attribute(null, ATTR_HARMFUL_APP_WARNING,
+ ustate.getHarmfulAppWarning());
+ }
+ if (ustate.getSplashScreenTheme() != null) {
+ serializer.attribute(null, ATTR_SPLASH_SCREEN_THEME,
+ ustate.getSplashScreenTheme());
+ }
+ if (ustate.isSuspended()) {
+ for (int i = 0; i < ustate.getSuspendParams().size(); i++) {
+ final String suspendingPackage = ustate.getSuspendParams().keyAt(i);
+ serializer.startTag(null, TAG_SUSPEND_PARAMS);
+ serializer.attribute(null, ATTR_SUSPENDING_PACKAGE, suspendingPackage);
+ final SuspendParams params =
+ ustate.getSuspendParams().valueAt(i);
+ if (params != null) {
+ params.saveToXml(serializer);
+ }
+ serializer.endTag(null, TAG_SUSPEND_PARAMS);
+ }
+ }
+ final ArraySet<String> enabledComponents = ustate.getEnabledComponents();
+ if (enabledComponents != null && enabledComponents.size() > 0) {
+ serializer.startTag(null, TAG_ENABLED_COMPONENTS);
+ for (int i = 0; i < enabledComponents.size(); i++) {
+ serializer.startTag(null, TAG_ITEM);
+ serializer.attribute(null, ATTR_NAME,
+ enabledComponents.valueAt(i));
+ serializer.endTag(null, TAG_ITEM);
+ }
+ serializer.endTag(null, TAG_ENABLED_COMPONENTS);
+ }
+ final ArraySet<String> disabledComponents = ustate.getDisabledComponents();
+ if (disabledComponents != null && disabledComponents.size() > 0) {
+ serializer.startTag(null, TAG_DISABLED_COMPONENTS);
+ for (int i = 0; i < disabledComponents.size(); i++) {
+ serializer.startTag(null, TAG_ITEM);
+ serializer.attribute(null, ATTR_NAME,
+ disabledComponents.valueAt(i));
+ serializer.endTag(null, TAG_ITEM);
+ }
+ serializer.endTag(null, TAG_DISABLED_COMPONENTS);
}
- serializer.endTag(null, TAG_DISABLED_COMPONENTS);
- }
- serializer.endTag(null, TAG_PACKAGE);
- }
+ serializer.endTag(null, TAG_PACKAGE);
+ }
- writePreferredActivitiesLPr(serializer, userId, true);
- writePersistentPreferredActivitiesLPr(serializer, userId);
- writeCrossProfileIntentFiltersLPr(serializer, userId);
- writeDefaultAppsLPr(serializer, userId);
- writeBlockUninstallPackagesLPr(serializer, userId);
+ writePreferredActivitiesLPr(serializer, userId, true);
+ writePersistentPreferredActivitiesLPr(serializer, userId);
+ writeCrossProfileIntentFiltersLPr(serializer, userId);
+ writeDefaultAppsLPr(serializer, userId);
+ writeBlockUninstallPackagesLPr(serializer, userId);
- serializer.endTag(null, TAG_PACKAGE_RESTRICTIONS);
+ serializer.endTag(null, TAG_PACKAGE_RESTRICTIONS);
- serializer.endDocument();
+ serializer.endDocument();
+ }
fstr.flush();
FileUtils.sync(fstr);
- fstr.close();
+ IoUtils.closeQuietly(fstr);
- // New settings successfully written, old ones are no longer
- // needed.
- backupFile.delete();
- FileUtils.setPermissions(userPackagesStateFile.toString(),
- FileUtils.S_IRUSR|FileUtils.S_IWUSR
- |FileUtils.S_IRGRP|FileUtils.S_IWGRP,
- -1, -1);
+ synchronized (mPackageRestrictionsLock) {
+ // File is created, set permissions.
+ FileUtils.setPermissions(userPackagesStateFile.toString(),
+ FileUtils.S_IRUSR | FileUtils.S_IWUSR
+ | FileUtils.S_IRGRP | FileUtils.S_IWGRP,
+ -1, -1);
+ // New settings successfully written, old ones are no longer needed.
+ backupFile.delete();
+ }
+
+ if (DEBUG_MU) {
+ Log.i(TAG, "New settings successfully written for user=" + userId + ": "
+ + userPackagesStateFile);
+ }
com.android.internal.logging.EventLogTags.writeCommitSysConfigFile(
"package-user-" + userId, SystemClock.uptimeMillis() - startTime);
// Done, all is good!
return;
- } catch(java.io.IOException e) {
+ } catch (java.io.IOException e) {
Slog.wtf(PackageManagerService.TAG,
"Unable to write package manager user packages state, "
+ " current changes will be lost at reboot", e);
@@ -2453,7 +2555,7 @@ public final class Settings implements Watchable, Snappable {
}
}
- void writeLPr(@NonNull Computer computer) {
+ void writeLPr(@NonNull Computer computer, boolean sync) {
//Debug.startMethodTracing("/data/system/packageprof", 8 * 1024 * 1024);
final long startTime = SystemClock.uptimeMillis();
@@ -2578,7 +2680,7 @@ public final class Settings implements Watchable, Snappable {
writeKernelMappingLPr();
writePackageListLPr();
- writeAllUsersPackageRestrictionsLPr();
+ writeAllUsersPackageRestrictionsLPr(sync);
writeAllRuntimePermissionsLPr();
com.android.internal.logging.EventLogTags.writeCommitSysConfigFile(
"package", SystemClock.uptimeMillis() - startTime);
@@ -2821,9 +2923,9 @@ public final class Settings implements Watchable, Snappable {
sb.append("@system");
} else if (pkg.isProduct()) {
sb.append("@product");
- } else if (pkg.getInstallSource().installerPackageName != null
- && !pkg.getInstallSource().installerPackageName.isEmpty()) {
- sb.append(pkg.getInstallSource().installerPackageName);
+ } else if (pkg.getInstallSource().mInstallerPackageName != null
+ && !pkg.getInstallSource().mInstallerPackageName.isEmpty()) {
+ sb.append(pkg.getInstallSource().mInstallerPackageName);
} else {
sb.append("@null");
}
@@ -2914,26 +3016,29 @@ public final class Settings implements Watchable, Snappable {
serializer.attributeInt(null, "sharedUserId", pkg.getAppId());
}
InstallSource installSource = pkg.getInstallSource();
- if (installSource.installerPackageName != null) {
- serializer.attribute(null, "installer", installSource.installerPackageName);
+ if (installSource.mInstallerPackageName != null) {
+ serializer.attribute(null, "installer", installSource.mInstallerPackageName);
+ }
+ if (installSource.mInstallerPackageUid != INVALID_UID) {
+ serializer.attributeInt(null, "installerUid", installSource.mInstallerPackageUid);
}
- if (installSource.installerAttributionTag != null) {
+ if (installSource.mInstallerAttributionTag != null) {
serializer.attribute(null, "installerAttributionTag",
- installSource.installerAttributionTag);
+ installSource.mInstallerAttributionTag);
}
serializer.attributeInt(null, "packageSource",
- installSource.packageSource);
- if (installSource.isOrphaned) {
+ installSource.mPackageSource);
+ if (installSource.mIsOrphaned) {
serializer.attributeBoolean(null, "isOrphaned", true);
}
- if (installSource.initiatingPackageName != null) {
- serializer.attribute(null, "installInitiator", installSource.initiatingPackageName);
+ if (installSource.mInitiatingPackageName != null) {
+ serializer.attribute(null, "installInitiator", installSource.mInitiatingPackageName);
}
- if (installSource.isInitiatingPackageUninstalled) {
+ if (installSource.mIsInitiatingPackageUninstalled) {
serializer.attributeBoolean(null, "installInitiatorUninstalled", true);
}
- if (installSource.originatingPackageName != null) {
- serializer.attribute(null, "installOriginator", installSource.originatingPackageName);
+ if (installSource.mOriginatingPackageName != null) {
+ serializer.attribute(null, "installOriginator", installSource.mOriginatingPackageName);
}
if (pkg.getVolumeUuid() != null) {
serializer.attribute(null, "volumeUuid", pkg.getVolumeUuid());
@@ -2962,8 +3067,8 @@ public final class Settings implements Watchable, Snappable {
pkg.getSignatures().writeXml(serializer, "sigs", mPastSignatures.untrackedStorage());
- if (installSource.initiatingPackageSignatures != null) {
- installSource.initiatingPackageSignatures.writeXml(
+ if (installSource.mInitiatingPackageSignatures != null) {
+ installSource.mInitiatingPackageSignatures.writeXml(
serializer, "install-initiator-sigs", mPastSignatures.untrackedStorage());
}
@@ -3213,7 +3318,7 @@ public final class Settings implements Watchable, Snappable {
mBackupStoppedPackagesFilename.delete();
mStoppedPackagesFilename.delete();
// Migrate to new file format
- writePackageRestrictionsLPr(UserHandle.USER_SYSTEM);
+ writePackageRestrictionsLPr(UserHandle.USER_SYSTEM, /*sync=*/true);
} else {
for (UserInfo user : users) {
readPackageRestrictionsLPr(user.id, originalFirstInstallTimes);
@@ -3707,6 +3812,7 @@ public final class Settings implements Watchable, Snappable {
String cpuAbiOverrideString = null;
String systemStr = null;
String installerPackageName = null;
+ int installerPackageUid = INVALID_UID;
String installerAttributionTag = null;
int packageSource = PackageInstaller.PACKAGE_SOURCE_UNSPECIFIED;
boolean isOrphaned = false;
@@ -3749,6 +3855,7 @@ public final class Settings implements Watchable, Snappable {
versionCode = parser.getAttributeLong(null, "version", 0);
installerPackageName = parser.getAttributeValue(null, "installer");
+ installerPackageUid = parser.getAttributeInt(null, "installerUid", INVALID_UID);
installerAttributionTag = parser.getAttributeValue(null, "installerAttributionTag");
packageSource = parser.getAttributeInt(null, "packageSource",
PackageInstaller.PACKAGE_SOURCE_UNSPECIFIED);
@@ -3891,8 +3998,8 @@ public final class Settings implements Watchable, Snappable {
if (packageSetting != null) {
InstallSource installSource = InstallSource.create(
installInitiatingPackageName, installOriginatingPackageName,
- installerPackageName, installerAttributionTag, packageSource, isOrphaned,
- installInitiatorUninstalled);
+ installerPackageName, installerPackageUid, installerAttributionTag,
+ packageSource, isOrphaned, installInitiatorUninstalled);
packageSetting.setInstallSource(installSource)
.setVolumeUuid(volumeUuid)
.setCategoryOverride(categoryHint)
@@ -4036,14 +4143,14 @@ public final class Settings implements Watchable, Snappable {
}
void addInstallerPackageNames(InstallSource installSource) {
- if (installSource.installerPackageName != null) {
- mInstallerPackages.add(installSource.installerPackageName);
+ if (installSource.mInstallerPackageName != null) {
+ mInstallerPackages.add(installSource.mInstallerPackageName);
}
- if (installSource.initiatingPackageName != null) {
- mInstallerPackages.add(installSource.initiatingPackageName);
+ if (installSource.mInitiatingPackageName != null) {
+ mInstallerPackages.add(installSource.mInitiatingPackageName);
}
- if (installSource.originatingPackageName != null) {
- mInstallerPackages.add(installSource.originatingPackageName);
+ if (installSource.mOriginatingPackageName != null) {
+ mInstallerPackages.add(installSource.mOriginatingPackageName);
}
}
@@ -4284,10 +4391,15 @@ public final class Settings implements Watchable, Snappable {
entry.getValue().removeUser(userId);
}
mPreferredActivities.remove(userId);
- File file = getUserPackagesStateFile(userId);
- file.delete();
- file = getUserPackagesStateBackupFile(userId);
- file.delete();
+
+ synchronized (mPackageRestrictionsLock) {
+ File file = getUserPackagesStateFile(userId);
+ file.delete();
+ file = getUserPackagesStateBackupFile(userId);
+ file.delete();
+ mPendingAsyncPackageRestrictionsWrites.delete(userId);
+ }
+
removeCrossProfileIntentFiltersLPw(userId);
mRuntimePermissionsPersistence.onUserRemoved(userId);
@@ -4332,7 +4444,7 @@ public final class Settings implements Watchable, Snappable {
if (mVerifierDeviceIdentity == null) {
mVerifierDeviceIdentity = VerifierDeviceIdentity.generate();
- writeLPr(computer);
+ writeLPr(computer, /*sync=*/false);
}
return mVerifierDeviceIdentity;
@@ -4552,12 +4664,13 @@ public final class Settings implements Watchable, Snappable {
pw.print(",");
pw.print(ps.getLastUpdateTime());
pw.print(",");
- pw.print(ps.getInstallSource().installerPackageName != null
- ? ps.getInstallSource().installerPackageName : "?");
- pw.print(ps.getInstallSource().installerAttributionTag != null
- ? "(" + ps.getInstallSource().installerAttributionTag + ")" : "");
+ pw.print(ps.getInstallSource().mInstallerPackageName != null
+ ? ps.getInstallSource().mInstallerPackageName : "?");
+ pw.print(ps.getInstallSource().mInstallerPackageUid);
+ pw.print(ps.getInstallSource().mInstallerAttributionTag != null
+ ? "(" + ps.getInstallSource().mInstallerAttributionTag + ")" : "");
pw.print(",");
- pw.print(ps.getInstallSource().packageSource);
+ pw.print(ps.getInstallSource().mPackageSource);
pw.println();
if (pkg != null) {
pw.print(checkinTag); pw.print("-"); pw.print("splt,");
@@ -4829,16 +4942,20 @@ public final class Settings implements Watchable, Snappable {
pw.print(prefix); pw.print(" lastUpdateTime=");
date.setTime(ps.getLastUpdateTime());
pw.println(sdf.format(date));
- if (ps.getInstallSource().installerPackageName != null) {
+ if (ps.getInstallSource().mInstallerPackageName != null) {
pw.print(prefix); pw.print(" installerPackageName=");
- pw.println(ps.getInstallSource().installerPackageName);
+ pw.println(ps.getInstallSource().mInstallerPackageName);
+ }
+ if (ps.getInstallSource().mInstallerPackageUid != INVALID_UID) {
+ pw.print(prefix); pw.print(" installerPackageUid=");
+ pw.println(ps.getInstallSource().mInstallerPackageUid);
}
- if (ps.getInstallSource().installerAttributionTag != null) {
+ if (ps.getInstallSource().mInstallerAttributionTag != null) {
pw.print(prefix); pw.print(" installerAttributionTag=");
- pw.println(ps.getInstallSource().installerAttributionTag);
+ pw.println(ps.getInstallSource().mInstallerAttributionTag);
}
pw.print(prefix); pw.print(" packageSource=");
- pw.println(ps.getInstallSource().packageSource);
+ pw.println(ps.getInstallSource().mPackageSource);
if (ps.isLoading()) {
pw.print(prefix); pw.println(" loadingProgress=" +
(int) (ps.getLoadingProgress() * 100) + "%");
diff --git a/services/core/java/com/android/server/pm/VerifyingSession.java b/services/core/java/com/android/server/pm/VerifyingSession.java
index 415ddd396ad9..6160519f4e77 100644
--- a/services/core/java/com/android/server/pm/VerifyingSession.java
+++ b/services/core/java/com/android/server/pm/VerifyingSession.java
@@ -764,7 +764,7 @@ final class VerifyingSession {
void populateInstallerExtras(Intent intent) {
intent.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
- mInstallSource.initiatingPackageName);
+ mInstallSource.mInitiatingPackageName);
if (mVerificationInfo != null) {
if (mVerificationInfo.mOriginatingUri != null) {
diff --git a/services/core/java/com/android/server/pm/dex/DexoptOptions.java b/services/core/java/com/android/server/pm/dex/DexoptOptions.java
index f5557c417f1b..411c19ff7310 100644
--- a/services/core/java/com/android/server/pm/dex/DexoptOptions.java
+++ b/services/core/java/com/android/server/pm/dex/DexoptOptions.java
@@ -18,6 +18,8 @@ package com.android.server.pm.dex;
import static com.android.server.pm.PackageManagerServiceCompilerMapping.getCompilerFilterForReason;
+import static dalvik.system.DexFile.isProfileGuidedCompilerFilter;
+
import android.annotation.Nullable;
import com.android.server.art.ReasonMapping;
@@ -26,8 +28,6 @@ import com.android.server.art.model.OptimizeParams;
import com.android.server.pm.DexOptHelper;
import com.android.server.pm.PackageManagerService;
-import dalvik.system.DexFile;
-
/**
* Options used for dexopt invocations.
*/
@@ -218,12 +218,11 @@ public final class DexoptOptions {
/*@OptimizeFlags*/ int flags = extraFlags;
if ((mFlags & DEXOPT_CHECK_FOR_PROFILES_UPDATES) == 0
- && DexFile.isProfileGuidedCompilerFilter(mCompilerFilter)) {
- // ART Service doesn't support bypassing this, so not setting this flag is not
- // supported.
- DexOptHelper.reportArtManagerFallback(mPackageName,
- "DEXOPT_CHECK_FOR_PROFILES_UPDATES not set with profile compiler filter");
- return null;
+ && isProfileGuidedCompilerFilter(mCompilerFilter)) {
+ // ART Service doesn't support bypassing the profile update check when profiles are
+ // used, so not setting this flag is not supported.
+ throw new IllegalArgumentException(
+ "DEXOPT_CHECK_FOR_PROFILES_UPDATES must be set with profile guided filter");
}
if ((mFlags & DEXOPT_FORCE) != 0) {
flags |= ArtFlags.FLAG_FORCE;
diff --git a/services/core/java/com/android/server/pm/dex/SystemServerDexLoadReporter.java b/services/core/java/com/android/server/pm/dex/SystemServerDexLoadReporter.java
deleted file mode 100644
index 807c82d887e3..000000000000
--- a/services/core/java/com/android/server/pm/dex/SystemServerDexLoadReporter.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.pm.dex;
-
-import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
-
-import android.content.pm.IPackageManager;
-import android.os.RemoteException;
-import android.util.Log;
-import android.util.Slog;
-
-import dalvik.system.BaseDexClassLoader;
-import dalvik.system.VMRuntime;
-
-import java.util.Map;
-
-/**
- * Reports dex file use to the package manager on behalf of system server.
- */
-public class SystemServerDexLoadReporter implements BaseDexClassLoader.Reporter {
- private static final String TAG = "SystemServerDexLoadReporter";
-
- private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-
- private final IPackageManager mPackageManager;
-
- private SystemServerDexLoadReporter(IPackageManager pm) {
- mPackageManager = pm;
- }
-
- @Override
- public void report(Map<String, String> classLoaderContextMap) {
- if (DEBUG) {
- Slog.i(TAG, "Reporting " + classLoaderContextMap);
- }
- if (classLoaderContextMap.isEmpty()) {
- Slog.wtf(TAG, "Bad call to DexLoadReporter: empty classLoaderContextMap");
- return;
- }
-
- try {
- mPackageManager.notifyDexLoad(
- PLATFORM_PACKAGE_NAME,
- classLoaderContextMap,
- VMRuntime.getRuntime().vmInstructionSet());
- } catch (RemoteException ignored) {
- // We're in system server, it can't happen.
- }
- }
-
- /**
- * Configures system server dex file reporting.
- * <p>The method will install a reporter in the BaseDexClassLoader and also
- * force the reporting of any dex files already loaded by the system server.
- */
- public static void configureSystemServerDexReporter(IPackageManager pm) {
- Slog.i(TAG, "Configuring system server dex reporter");
-
- SystemServerDexLoadReporter reporter = new SystemServerDexLoadReporter(pm);
- BaseDexClassLoader.setReporter(reporter);
- ClassLoader currrentClassLoader = reporter.getClass().getClassLoader();
- if (currrentClassLoader instanceof BaseDexClassLoader) {
- ((BaseDexClassLoader) currrentClassLoader).reportClassLoaderChain();
- } else {
- Slog.wtf(TAG, "System server class loader is not a BaseDexClassLoader. type="
- + currrentClassLoader.getClass().getName());
- }
- }
-}
diff --git a/services/core/java/com/android/server/pm/pkg/mutate/PackageStateMutator.java b/services/core/java/com/android/server/pm/pkg/mutate/PackageStateMutator.java
index 951ddfa62118..e736f433c11c 100644
--- a/services/core/java/com/android/server/pm/pkg/mutate/PackageStateMutator.java
+++ b/services/core/java/com/android/server/pm/pkg/mutate/PackageStateMutator.java
@@ -263,9 +263,10 @@ public class PackageStateMutator {
@NonNull
@Override
- public PackageStateWrite setInstaller(@NonNull String installerPackageName) {
+ public PackageStateWrite setInstaller(@Nullable String installerPackageName,
+ int installerPackageUid) {
if (mState != null) {
- mState.setInstallerPackageName(installerPackageName);
+ mState.setInstallerPackage(installerPackageName, installerPackageUid);
}
return this;
}
diff --git a/services/core/java/com/android/server/pm/pkg/mutate/PackageStateWrite.java b/services/core/java/com/android/server/pm/pkg/mutate/PackageStateWrite.java
index 1ac0b059d496..dc9cd3b6ceb7 100644
--- a/services/core/java/com/android/server/pm/pkg/mutate/PackageStateWrite.java
+++ b/services/core/java/com/android/server/pm/pkg/mutate/PackageStateWrite.java
@@ -56,5 +56,5 @@ public interface PackageStateWrite {
PackageStateWrite setOverrideSeInfo(@Nullable String newSeInfo);
@NonNull
- PackageStateWrite setInstaller(@NonNull String installerPackageName);
+ PackageStateWrite setInstaller(@Nullable String installerPackageName, int installerPackageUid);
}
diff --git a/services/core/java/com/android/server/policy/DeviceStateProviderImpl.java b/services/core/java/com/android/server/policy/DeviceStateProviderImpl.java
index b1dee4925765..d2e0502ad70c 100644
--- a/services/core/java/com/android/server/policy/DeviceStateProviderImpl.java
+++ b/services/core/java/com/android/server/policy/DeviceStateProviderImpl.java
@@ -395,6 +395,10 @@ public final class DeviceStateProviderImpl implements DeviceStateProvider,
break;
}
}
+ if (newState == INVALID_DEVICE_STATE) {
+ Slog.e(TAG, "No declared device states match any of the required conditions.");
+ dumpSensorValues();
+ }
if (newState != INVALID_DEVICE_STATE && newState != mLastReportedState) {
mLastReportedState = newState;
@@ -592,6 +596,19 @@ public final class DeviceStateProviderImpl implements DeviceStateProvider,
return null;
}
+ @GuardedBy("mLock")
+ private void dumpSensorValues() {
+ Slog.i(TAG, "Sensor values:");
+ for (Sensor sensor : mLatestSensorEvent.keySet()) {
+ SensorEvent sensorEvent = mLatestSensorEvent.get(sensor);
+ if (sensorEvent != null) {
+ Slog.i(TAG, sensor.getName() + ": " + Arrays.toString(sensorEvent.values));
+ } else {
+ Slog.i(TAG, sensor.getName() + ": null");
+ }
+ }
+ }
+
/**
* Tries to parse the provided file into a {@link DeviceStateConfig} object. Returns
* {@code null} if the file could not be successfully parsed.
diff --git a/services/core/java/com/android/server/security/FileIntegrityService.java b/services/core/java/com/android/server/security/FileIntegrityService.java
index 466ac74a8322..5ae697315ed1 100644
--- a/services/core/java/com/android/server/security/FileIntegrityService.java
+++ b/services/core/java/com/android/server/security/FileIntegrityService.java
@@ -23,27 +23,37 @@ import android.content.Context;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.os.Binder;
+import android.os.Build;
import android.os.Environment;
import android.os.IBinder;
+import android.os.ParcelFileDescriptor;
+import android.os.ResultReceiver;
+import android.os.ShellCallback;
+import android.os.ShellCommand;
import android.os.UserHandle;
import android.security.IFileIntegrityService;
import android.util.Slog;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.security.VerityUtils;
import com.android.server.LocalServices;
import com.android.server.SystemService;
import java.io.ByteArrayInputStream;
import java.io.File;
+import java.io.FileDescriptor;
import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
import java.nio.file.Files;
import java.nio.file.Path;
+import java.nio.file.Paths;
import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
-import java.util.Collection;
/**
* A {@link SystemService} that provides file integrity related operations.
@@ -52,9 +62,19 @@ import java.util.Collection;
public class FileIntegrityService extends SystemService {
private static final String TAG = "FileIntegrityService";
+ /** The maximum size of signature file. This is just to avoid potential abuse. */
+ private static final int MAX_SIGNATURE_FILE_SIZE_BYTES = 8192;
+
private static CertificateFactory sCertFactory;
- private Collection<X509Certificate> mTrustedCertificates = new ArrayList<X509Certificate>();
+ @GuardedBy("mTrustedCertificates")
+ private final ArrayList<X509Certificate> mTrustedCertificates =
+ new ArrayList<X509Certificate>();
+
+ /** Gets the instance of the service */
+ public static FileIntegrityService getService() {
+ return LocalServices.getService(FileIntegrityService.class);
+ }
private final IBinder mService = new IFileIntegrityService.Stub() {
@Override
@@ -75,13 +95,23 @@ public class FileIntegrityService extends SystemService {
Slog.w(TAG, "Received a null certificate");
return false;
}
- return mTrustedCertificates.contains(toCertificate(certificateBytes));
+ synchronized (mTrustedCertificates) {
+ return mTrustedCertificates.contains(toCertificate(certificateBytes));
+ }
} catch (CertificateException e) {
Slog.e(TAG, "Failed to convert the certificate: " + e);
return false;
}
}
+ @Override
+ public void onShellCommand(FileDescriptor in, FileDescriptor out,
+ FileDescriptor err, String[] args, ShellCallback callback,
+ ResultReceiver resultReceiver) {
+ new FileIntegrityServiceShellCommand()
+ .exec(this, in, out, err, args, callback, resultReceiver);
+ }
+
private void checkCallerPermission(String packageName) {
final int callingUid = Binder.getCallingUid();
final int callingUserId = UserHandle.getUserId(callingUid);
@@ -116,6 +146,7 @@ public class FileIntegrityService extends SystemService {
} catch (CertificateException e) {
Slog.wtf(TAG, "Cannot get an instance of X.509 certificate factory");
}
+ LocalServices.addService(FileIntegrityService.class, this);
}
@Override
@@ -124,6 +155,34 @@ public class FileIntegrityService extends SystemService {
publishBinderService(Context.FILE_INTEGRITY_SERVICE, mService);
}
+ /**
+ * Returns whether the signature over the file's fs-verity digest can be verified by one of the
+ * known certiticates.
+ */
+ public boolean verifyPkcs7DetachedSignature(String signaturePath, String filePath)
+ throws IOException {
+ if (Files.size(Paths.get(signaturePath)) > MAX_SIGNATURE_FILE_SIZE_BYTES) {
+ throw new SecurityException("Signature file is unexpectedly large: "
+ + signaturePath);
+ }
+ byte[] signatureBytes = Files.readAllBytes(Paths.get(signaturePath));
+ byte[] digest = VerityUtils.getFsverityDigest(filePath);
+ synchronized (mTrustedCertificates) {
+ for (var cert : mTrustedCertificates) {
+ try {
+ byte[] derEncoded = cert.getEncoded();
+ if (VerityUtils.verifyPkcs7DetachedSignature(signatureBytes, digest,
+ new ByteArrayInputStream(derEncoded))) {
+ return true;
+ }
+ } catch (CertificateEncodingException e) {
+ Slog.w(TAG, "Ignoring ill-formed certificate: " + e);
+ }
+ }
+ }
+ return false;
+ }
+
private void loadAllCertificates() {
// A better alternative to load certificates would be to read from .fs-verity kernel
// keyring, which fsverity_init loads to during earlier boot time from the same sources
@@ -148,10 +207,6 @@ public class FileIntegrityService extends SystemService {
for (File cert : files) {
byte[] certificateBytes = Files.readAllBytes(cert.toPath());
- if (certificateBytes == null) {
- Slog.w(TAG, "The certificate file is empty, ignoring " + cert);
- continue;
- }
collectCertificate(certificateBytes);
}
} catch (IOException e) {
@@ -165,7 +220,9 @@ public class FileIntegrityService extends SystemService {
*/
private void collectCertificate(@NonNull byte[] bytes) {
try {
- mTrustedCertificates.add(toCertificate(bytes));
+ synchronized (mTrustedCertificates) {
+ mTrustedCertificates.add(toCertificate(bytes));
+ }
} catch (CertificateException e) {
Slog.e(TAG, "Invalid certificate, ignored: " + e);
}
@@ -184,4 +241,71 @@ public class FileIntegrityService extends SystemService {
}
return (X509Certificate) certificate;
}
+
+
+ private class FileIntegrityServiceShellCommand extends ShellCommand {
+ @Override
+ public int onCommand(String cmd) {
+ if (!Build.IS_DEBUGGABLE) {
+ return -1;
+ }
+ if (cmd == null) {
+ return handleDefaultCommands(cmd);
+ }
+ final PrintWriter pw = getOutPrintWriter();
+ switch (cmd) {
+ case "append-cert":
+ String nextArg = getNextArg();
+ if (nextArg == null) {
+ pw.println("Invalid argument");
+ pw.println("");
+ onHelp();
+ return -1;
+ }
+ ParcelFileDescriptor pfd = openFileForSystem(nextArg, "r");
+ if (pfd == null) {
+ pw.println("Cannot open the file");
+ return -1;
+ }
+ InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(pfd);
+ try {
+ collectCertificate(is.readAllBytes());
+ } catch (IOException e) {
+ pw.println("Failed to add certificate: " + e);
+ return -1;
+ }
+ pw.println("Certificate is added successfully");
+ return 0;
+
+ case "remove-last-cert":
+ synchronized (mTrustedCertificates) {
+ if (mTrustedCertificates.size() == 0) {
+ pw.println("Certificate list is already empty");
+ return -1;
+ }
+ mTrustedCertificates.remove(mTrustedCertificates.size() - 1);
+ }
+ pw.println("Certificate is removed successfully");
+ return 0;
+ default:
+ pw.println("Unknown action");
+ pw.println("");
+ onHelp();
+ }
+ return -1;
+ }
+
+ @Override
+ public void onHelp() {
+ final PrintWriter pw = getOutPrintWriter();
+ pw.println("File integrity service commands:");
+ pw.println(" help");
+ pw.println(" Print this help text.");
+ pw.println(" append-cert path/to/cert.der");
+ pw.println(" Add the DER-encoded certificate (only in debug builds)");
+ pw.println(" remove-last-cert");
+ pw.println(" Remove the last certificate in the key list (only in debug builds)");
+ pw.println("");
+ }
+ }
}
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
index 43ffa812b329..434cd78f137b 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
@@ -198,4 +198,11 @@ public interface StatusBarManagerInternal {
* (IUdfpsRefreshRateRequestCallback)
*/
void setUdfpsRefreshRateCallback(IUdfpsRefreshRateRequestCallback callback);
+
+ /**
+ * Shows the rear display educational dialog
+ *
+ * @see com.android.internal.statusbar.IStatusBar#showRearDisplayDialog
+ */
+ void showRearDisplayDialog(int currentBaseState);
}
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index 50eab256c411..006d88887a87 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -16,6 +16,7 @@
package com.android.server.statusbar;
+import static android.Manifest.permission.CONTROL_DEVICE_STATE;
import static android.Manifest.permission.INTERACT_ACROSS_USERS;
import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
import static android.app.StatusBarManager.DISABLE2_GLOBAL_ACTIONS;
@@ -31,6 +32,7 @@ import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVE
import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
import android.app.ActivityThread;
@@ -715,6 +717,15 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
} catch (RemoteException ex) { }
}
}
+
+ @Override
+ public void showRearDisplayDialog(int currentBaseState) {
+ if (mBar != null) {
+ try {
+ mBar.showRearDisplayDialog(currentBaseState);
+ } catch (RemoteException ex) { }
+ }
+ }
};
private final GlobalActionsProvider mGlobalActionsProvider = new GlobalActionsProvider() {
@@ -1318,6 +1329,11 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
"StatusBarManagerService");
}
+ @RequiresPermission(android.Manifest.permission.CONTROL_DEVICE_STATE)
+ private void enforceControlDeviceStatePermission() {
+ mContext.enforceCallingOrSelfPermission(CONTROL_DEVICE_STATE, "StatusBarManagerService");
+ }
+
private boolean doesCallerHoldInteractAcrossUserPermission() {
return mContext.checkCallingPermission(INTERACT_ACROSS_USERS_FULL) == PERMISSION_GRANTED
|| mContext.checkCallingPermission(INTERACT_ACROSS_USERS) == PERMISSION_GRANTED;
@@ -2201,6 +2217,19 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
}
}
+ @RequiresPermission(android.Manifest.permission.CONTROL_DEVICE_STATE)
+ @Override
+ public void showRearDisplayDialog(int currentState) {
+ enforceControlDeviceStatePermission();
+ if (mBar != null) {
+ try {
+ mBar.showRearDisplayDialog(currentState);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "showRearDisplayDialog", e);
+ }
+ }
+ }
+
/** @hide */
public void passThroughShellCommand(String[] args, FileDescriptor fd) {
enforceStatusBarOrShell();
diff --git a/services/core/java/com/android/server/timedetector/ServerFlags.java b/services/core/java/com/android/server/timedetector/ServerFlags.java
index e9827ce33739..678222980ea4 100644
--- a/services/core/java/com/android/server/timedetector/ServerFlags.java
+++ b/services/core/java/com/android/server/timedetector/ServerFlags.java
@@ -35,7 +35,9 @@ import java.lang.annotation.Target;
import java.time.DateTimeException;
import java.time.Duration;
import java.time.Instant;
+import java.util.ArrayList;
import java.util.HashSet;
+import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
@@ -211,7 +213,11 @@ public final class ServerFlags {
}
private void handlePropertiesChanged(@NonNull DeviceConfig.Properties properties) {
+ // Copy the listeners to notify under the "mListeners" lock but don't hold the lock while
+ // delivering the notifications to avoid deadlocks.
+ List<StateChangeListener> listenersToNotify;
synchronized (mListeners) {
+ listenersToNotify = new ArrayList<>(mListeners.size());
for (Map.Entry<StateChangeListener, HashSet<String>> listenerEntry
: mListeners.entrySet()) {
// It's unclear which set of the following two Sets is going to be larger in the
@@ -225,10 +231,14 @@ public final class ServerFlags {
HashSet<String> monitoredKeys = listenerEntry.getValue();
Iterable<String> modifiedKeys = properties.getKeyset();
if (containsAny(monitoredKeys, modifiedKeys)) {
- listenerEntry.getKey().onChange();
+ listenersToNotify.add(listenerEntry.getKey());
}
}
}
+
+ for (StateChangeListener listener : listenersToNotify) {
+ listener.onChange();
+ }
}
private static boolean containsAny(
diff --git a/services/core/java/com/android/server/timedetector/ServiceConfigAccessorImpl.java b/services/core/java/com/android/server/timedetector/ServiceConfigAccessorImpl.java
index 4ef713c9b645..dc2a97466dea 100644
--- a/services/core/java/com/android/server/timedetector/ServiceConfigAccessorImpl.java
+++ b/services/core/java/com/android/server/timedetector/ServiceConfigAccessorImpl.java
@@ -166,8 +166,14 @@ final class ServiceConfigAccessorImpl implements ServiceConfigAccessor {
}
}
- private synchronized void handleConfigurationInternalChangeOnMainThread() {
- for (StateChangeListener changeListener : mConfigurationInternalListeners) {
+ private void handleConfigurationInternalChangeOnMainThread() {
+ // Copy the listeners holding the "this" lock but don't hold the lock while delivering the
+ // notifications to avoid deadlocks.
+ List<StateChangeListener> configurationInternalListeners;
+ synchronized (this) {
+ configurationInternalListeners = new ArrayList<>(this.mConfigurationInternalListeners);
+ }
+ for (StateChangeListener changeListener : configurationInternalListeners) {
changeListener.onChange();
}
}
diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorService.java b/services/core/java/com/android/server/timedetector/TimeDetectorService.java
index 64adbb680653..9d098c6fc94b 100644
--- a/services/core/java/com/android/server/timedetector/TimeDetectorService.java
+++ b/services/core/java/com/android/server/timedetector/TimeDetectorService.java
@@ -266,6 +266,8 @@ public final class TimeDetectorService extends ITimeDetectorService.Stub
for (int listenerIndex = 0; listenerIndex < listenerCount; listenerIndex++) {
ITimeDetectorListener listener = mListeners.valueAt(listenerIndex);
try {
+ // No need to surrender the mListeners lock while doing this:
+ // ITimeDetectorListener is declared "oneway".
listener.onChange();
} catch (RemoteException e) {
Slog.w(TAG, "Unable to notify listener=" + listener, e);
diff --git a/services/core/java/com/android/server/timezonedetector/DeviceActivityMonitorImpl.java b/services/core/java/com/android/server/timezonedetector/DeviceActivityMonitorImpl.java
index 8c9bd3b9d0d7..6d2e7239bd05 100644
--- a/services/core/java/com/android/server/timezonedetector/DeviceActivityMonitorImpl.java
+++ b/services/core/java/com/android/server/timezonedetector/DeviceActivityMonitorImpl.java
@@ -77,12 +77,18 @@ class DeviceActivityMonitorImpl implements DeviceActivityMonitor {
mListeners.add(listener);
}
- private synchronized void notifyFlightComplete() {
+ private void notifyFlightComplete() {
if (DBG) {
Slog.d(LOG_TAG, "notifyFlightComplete");
}
- for (Listener listener : mListeners) {
+ // Copy the listeners holding the "this" lock but don't hold the lock while delivering the
+ // notifications to avoid deadlocks.
+ List<Listener> listeners;
+ synchronized (this) {
+ listeners = new ArrayList<>(mListeners);
+ }
+ for (Listener listener : listeners) {
listener.onFlightComplete();
}
}
diff --git a/services/core/java/com/android/server/timezonedetector/ServiceConfigAccessorImpl.java b/services/core/java/com/android/server/timezonedetector/ServiceConfigAccessorImpl.java
index dfb961938273..295c5c8ad373 100644
--- a/services/core/java/com/android/server/timezonedetector/ServiceConfigAccessorImpl.java
+++ b/services/core/java/com/android/server/timezonedetector/ServiceConfigAccessorImpl.java
@@ -205,8 +205,14 @@ public final class ServiceConfigAccessorImpl implements ServiceConfigAccessor {
}
}
- private synchronized void handleConfigurationInternalChangeOnMainThread() {
- for (StateChangeListener changeListener : mConfigurationInternalListeners) {
+ private void handleConfigurationInternalChangeOnMainThread() {
+ // Copy the listeners holding the "this" lock but don't hold the lock while delivering the
+ // notifications to avoid deadlocks.
+ List<StateChangeListener> configurationInternalListeners;
+ synchronized (this) {
+ configurationInternalListeners = new ArrayList<>(this.mConfigurationInternalListeners);
+ }
+ for (StateChangeListener changeListener : configurationInternalListeners) {
changeListener.onChange();
}
}
diff --git a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java
index eecf0f74bff6..3424251ea57f 100644
--- a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java
+++ b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java
@@ -351,6 +351,7 @@ public final class TimeZoneDetectorStrategyImpl implements TimeZoneDetectorStrat
@GuardedBy("this")
private void notifyStateChangeListenersAsynchronously() {
for (StateChangeListener listener : mStateChangeListeners) {
+ // This is queuing asynchronous notification, so no need to surrender the "this" lock.
mStateChangeHandler.post(listener::onChange);
}
}
diff --git a/services/core/java/com/android/server/vcn/TelephonySubscriptionTracker.java b/services/core/java/com/android/server/vcn/TelephonySubscriptionTracker.java
index 5c305c6902af..ca4a32f553ae 100644
--- a/services/core/java/com/android/server/vcn/TelephonySubscriptionTracker.java
+++ b/services/core/java/com/android/server/vcn/TelephonySubscriptionTracker.java
@@ -390,8 +390,13 @@ public class TelephonySubscriptionTracker extends BroadcastReceiver {
Objects.requireNonNull(privilegedPackages, "privilegedPackages was null");
Objects.requireNonNull(subIdToCarrierConfigMap, "subIdToCarrierConfigMap was null");
- mSubIdToInfoMap = Collections.unmodifiableMap(subIdToInfoMap);
- mSubIdToCarrierConfigMap = Collections.unmodifiableMap(subIdToCarrierConfigMap);
+ mSubIdToInfoMap =
+ Collections.unmodifiableMap(
+ new HashMap<Integer, SubscriptionInfo>(subIdToInfoMap));
+ mSubIdToCarrierConfigMap =
+ Collections.unmodifiableMap(
+ new HashMap<Integer, PersistableBundleWrapper>(
+ subIdToCarrierConfigMap));
final Map<ParcelUuid, Set<String>> unmodifiableInnerSets = new ArrayMap<>();
for (Entry<ParcelUuid, Set<String>> entry : privilegedPackages.entrySet()) {
diff --git a/services/core/java/com/android/server/vcn/util/PersistableBundleUtils.java b/services/core/java/com/android/server/vcn/util/PersistableBundleUtils.java
index 999d4064c951..d22ec0ad456d 100644
--- a/services/core/java/com/android/server/vcn/util/PersistableBundleUtils.java
+++ b/services/core/java/com/android/server/vcn/util/PersistableBundleUtils.java
@@ -544,6 +544,20 @@ public class PersistableBundleUtils {
return mBundle.getInt(key, defaultValue);
}
+ /**
+ * Returns the value associated with the given key, or null if no mapping of the desired
+ * type exists for the given key or a null value is explicitly associated with the key.
+ *
+ * @param key a String, or null
+ * @param defaultValue the value to return if key does not exist
+ * @return an int[] value, or null
+ */
+ @Nullable
+ public int[] getIntArray(@Nullable String key, @Nullable int[] defaultValue) {
+ final int[] value = mBundle.getIntArray(key);
+ return value == null ? defaultValue : value;
+ }
+
@Override
public int hashCode() {
return getHashCode(mBundle);
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index c875f4af9c8b..5d084616bfea 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -270,11 +270,12 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
+ " sys=" + sysWallpaperChanged
+ " lock=" + lockWallpaperChanged
+ " imagePending=" + wallpaper.imageWallpaperPending
- + " whichPending=0x" + Integer.toHexString(wallpaper.whichPending)
+ + " mWhich=0x" + Integer.toHexString(wallpaper.mWhich)
+ " written=" + written);
}
if (moved && lockWallpaperChanged) {
+ // TODO(b/253507223) Start lock screen WallpaperService
// We just migrated sys -> lock to preserve imagery for an impending
// new system-only wallpaper. Tell keyguard about it and make sure it
// has the right SELinux label.
@@ -329,8 +330,10 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
false, wallpaper, callback);
notifyColorsWhich |= FLAG_SYSTEM;
}
+ // TODO(b/253507223) Start lock screen WallpaperService if only lock
+ // screen wp changed
if (lockWallpaperChanged
- || (wallpaper.whichPending & FLAG_LOCK) != 0) {
+ || (wallpaper.mWhich & FLAG_LOCK) != 0) {
if (DEBUG) {
Slog.i(TAG, "Lock-relevant wallpaper changed");
}
@@ -609,7 +612,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
if (DEBUG) {
Slog.v(TAG, "Generating crop for new wallpaper(s): 0x"
- + Integer.toHexString(wallpaper.whichPending)
+ + Integer.toHexString(wallpaper.mWhich)
+ " to " + wallpaper.cropFile.getName()
+ " crop=(" + cropHint.width() + 'x' + cropHint.height()
+ ") dim=(" + wpData.mWidth + 'x' + wpData.mHeight + ')');
@@ -922,10 +925,9 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
boolean imageWallpaperPending;
/**
- * Which new wallpapers are being written; mirrors the 'which'
- * selector bit field to setWallpaper().
+ * Which wallpaper is set. Flag values are from {@link SetWallpaperFlags}.
*/
- int whichPending;
+ int mWhich;
/**
* Callback once the set + crop is finished
@@ -1166,7 +1168,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
try {
connection.mService.attach(connection, mToken, TYPE_WALLPAPER, false,
wpdData.mWidth, wpdData.mHeight,
- wpdData.mPadding, mDisplayId, FLAG_SYSTEM | FLAG_LOCK);
+ wpdData.mPadding, mDisplayId, mWallpaper.mWhich);
} catch (RemoteException e) {
Slog.w(TAG, "Failed attaching wallpaper on display", e);
if (wallpaper != null && !wallpaper.wallpaperUpdating
@@ -2415,13 +2417,19 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
@Override
public WallpaperInfo getWallpaperInfo(int userId) {
+ return getWallpaperInfoWithFlags(FLAG_SYSTEM, userId);
+ }
+
+ @Override
+ public WallpaperInfo getWallpaperInfoWithFlags(@SetWallpaperFlags int which, int userId) {
final boolean allow =
hasPermission(READ_WALLPAPER_INTERNAL) || hasPermission(QUERY_ALL_PACKAGES);
if (allow) {
userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
Binder.getCallingUid(), userId, false, true, "getWallpaperInfo", null);
synchronized (mLock) {
- WallpaperData wallpaper = mWallpaperMap.get(userId);
+ WallpaperData wallpaper = (which == FLAG_LOCK) ? mLockWallpaperMap.get(userId)
+ : mWallpaperMap.get(userId);
if (wallpaper != null && wallpaper.connection != null) {
return wallpaper.connection.mInfo;
}
@@ -2870,7 +2878,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
ParcelFileDescriptor pfd = updateWallpaperBitmapLocked(name, wallpaper, extras);
if (pfd != null) {
wallpaper.imageWallpaperPending = true;
- wallpaper.whichPending = which;
+ wallpaper.mWhich = which;
wallpaper.setComplete = completion;
wallpaper.fromForegroundApp = fromForegroundApp;
wallpaper.cropHint.set(cropHint);
@@ -2901,6 +2909,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
lockWP.allowBackup = sysWP.allowBackup;
lockWP.primaryColors = sysWP.primaryColors;
lockWP.mWallpaperDimAmount = sysWP.mWallpaperDimAmount;
+ lockWP.mWhich = FLAG_LOCK;
// Migrate the bitmap files outright; no need to copy
try {
@@ -2953,25 +2962,27 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
@Override
public void setWallpaperComponentChecked(ComponentName name, String callingPackage,
- int userId) {
+ @SetWallpaperFlags int which, int userId) {
if (isWallpaperSupported(callingPackage) && isSetWallpaperAllowed(callingPackage)) {
- setWallpaperComponent(name, userId);
+ setWallpaperComponent(name, which, userId);
}
}
// ToDo: Remove this version of the function
@Override
public void setWallpaperComponent(ComponentName name) {
- setWallpaperComponent(name, UserHandle.getCallingUserId());
+ setWallpaperComponent(name, UserHandle.getCallingUserId(), FLAG_SYSTEM);
}
- private void setWallpaperComponent(ComponentName name, int userId) {
+ private void setWallpaperComponent(ComponentName name, @SetWallpaperFlags int which,
+ int userId) {
userId = ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId,
false /* all */, true /* full */, "changing live wallpaper", null /* pkg */);
checkPermission(android.Manifest.permission.SET_WALLPAPER_COMPONENT);
- int which = FLAG_SYSTEM;
+ // TODO(b/253507223) Use passed destination and properly start lock screen LWP
+ int legacyWhich = FLAG_SYSTEM;
boolean shouldNotifyColors = false;
WallpaperData wallpaper;
@@ -2999,11 +3010,12 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
// New live wallpaper is also a lock wallpaper if nothing is set
if (mLockWallpaperMap.get(userId) == null) {
- which |= FLAG_LOCK;
+ legacyWhich |= FLAG_LOCK;
}
try {
wallpaper.imageWallpaperPending = false;
+ wallpaper.mWhich = which;
boolean same = changingToSame(name, wallpaper);
if (bindWallpaperComponentLocked(name, false, true, wallpaper, null)) {
if (!same) {
@@ -3032,7 +3044,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
}
if (shouldNotifyColors) {
- notifyWallpaperColorsChanged(wallpaper, which);
+ notifyWallpaperColorsChanged(wallpaper, legacyWhich);
notifyWallpaperColorsChanged(mFallbackWallpaper, FLAG_SYSTEM);
}
}
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 3ec24d5d4d7d..97aee0bd0bad 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -2745,12 +2745,6 @@ class ActivityStarter {
newParent = candidateTf;
}
}
- if (newParent.asTask() == null) {
- // only collect task-fragments.
- // TODO(b/258095975): we probably shouldn't ever collect the parent here since it isn't
- // changing. The logic that changes it should collect it.
- newParent.mTransitionController.collect(newParent);
- }
if (mStartActivity.getTaskFragment() == null
|| mStartActivity.getTaskFragment() == newParent) {
newParent.addChild(mStartActivity, POSITION_TOP);
diff --git a/services/core/java/com/android/server/wm/AppTransitionController.java b/services/core/java/com/android/server/wm/AppTransitionController.java
index 5380de760a82..fca974325b3b 100644
--- a/services/core/java/com/android/server/wm/AppTransitionController.java
+++ b/services/core/java/com/android/server/wm/AppTransitionController.java
@@ -1212,13 +1212,23 @@ public class AppTransitionController {
"Delaying app transition for screen rotation animation to finish");
return false;
}
+ final boolean isRecentsInOpening = mDisplayContent.mOpeningApps.stream().anyMatch(
+ ConfigurationContainer::isActivityTypeRecents);
for (int i = 0; i < apps.size(); i++) {
WindowContainer wc = apps.valueAt(i);
final ActivityRecord activity = getAppFromContainer(wc);
if (activity == null) {
continue;
}
- if (activity.isAnimating(PARENTS, ANIMATION_TYPE_RECENTS)) {
+ // In order to avoid visual clutter caused by a conflict between app transition
+ // animation and recents animation, app transition is delayed until recents finishes.
+ // One exceptional case. When 3P launcher is used and a user taps a task screenshot in
+ // task switcher (isRecentsInOpening=true), app transition must start even though
+ // recents is running. Otherwise app transition is blocked until timeout (b/232984498).
+ // When 1P launcher is used, this animation is controlled by the launcher outside of
+ // the app transition, so delaying app transition doesn't cause visible delay. After
+ // recents finishes, app transition is handled just to commit visibility on apps.
+ if (!isRecentsInOpening && activity.isAnimating(PARENTS, ANIMATION_TYPE_RECENTS)) {
ProtoLog.v(WM_DEBUG_APP_TRANSITIONS,
"Delaying app transition for recents animation to finish");
return false;
diff --git a/services/core/java/com/android/server/wm/BackNavigationController.java b/services/core/java/com/android/server/wm/BackNavigationController.java
index f5da4c80ba97..3bb02382b57c 100644
--- a/services/core/java/com/android/server/wm/BackNavigationController.java
+++ b/services/core/java/com/android/server/wm/BackNavigationController.java
@@ -24,6 +24,9 @@ import static android.view.WindowManager.TRANSIT_CLOSE;
import static android.view.WindowManager.TRANSIT_TO_BACK;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_BACK_PREVIEW;
+import static com.android.server.wm.BackNavigationProto.ANIMATION_IN_PROGRESS;
+import static com.android.server.wm.BackNavigationProto.LAST_BACK_TYPE;
+import static com.android.server.wm.BackNavigationProto.SHOW_WALLPAPER;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -37,6 +40,7 @@ import android.os.RemoteException;
import android.os.SystemProperties;
import android.util.ArraySet;
import android.util.Slog;
+import android.util.proto.ProtoOutputStream;
import android.view.IWindowFocusObserver;
import android.view.RemoteAnimationTarget;
import android.view.SurfaceControl;
@@ -60,6 +64,7 @@ class BackNavigationController {
private WindowManagerService mWindowManagerService;
private IWindowFocusObserver mFocusObserver;
private boolean mBackAnimationInProgress;
+ private @BackNavigationInfo.BackTargetType int mLastBackType;
private boolean mShowWallpaper;
private Runnable mPendingAnimation;
@@ -215,7 +220,7 @@ class BackNavigationController {
infoBuilder.setOnBackNavigationDone(new RemoteCallback(result ->
onBackNavigationDone(result, finalFocusedWindow,
BackNavigationInfo.TYPE_CALLBACK)));
-
+ mLastBackType = backType;
return infoBuilder.setType(backType).build();
}
@@ -301,7 +306,7 @@ class BackNavigationController {
result, finalFocusedWindow, finalBackType));
infoBuilder.setOnBackNavigationDone(onBackNavigationDone);
}
-
+ mLastBackType = backType;
return infoBuilder.build();
}
@@ -836,4 +841,13 @@ class BackNavigationController {
&& w.mAttrs.type == TYPE_BASE_APPLICATION && w.mActivityRecord != null
&& mAnimationTargets.isTarget(w.mActivityRecord, true /* open */);
}
+
+ // Called from WindowManagerService to write to a protocol buffer output stream.
+ void dumpDebug(ProtoOutputStream proto, long fieldId) {
+ final long token = proto.start(fieldId);
+ proto.write(ANIMATION_IN_PROGRESS, mBackAnimationInProgress);
+ proto.write(LAST_BACK_TYPE, mLastBackType);
+ proto.write(SHOW_WALLPAPER, mShowWallpaper);
+ proto.end(token);
+ }
}
diff --git a/services/core/java/com/android/server/wm/LaunchParamsUtil.java b/services/core/java/com/android/server/wm/LaunchParamsUtil.java
index 65298c886404..cd071af6c60e 100644
--- a/services/core/java/com/android/server/wm/LaunchParamsUtil.java
+++ b/services/core/java/com/android/server/wm/LaunchParamsUtil.java
@@ -46,6 +46,8 @@ class LaunchParamsUtil {
private static final int DISPLAY_EDGE_OFFSET_DP = 27;
+ private static final Rect TMP_STABLE_BOUNDS = new Rect();
+
private LaunchParamsUtil() {}
/**
@@ -130,18 +132,42 @@ class LaunchParamsUtil {
return new Size(adjWidth, adjHeight);
}
- static void adjustBoundsToFitInDisplayArea(@NonNull Rect stableBounds, int layoutDirection,
+ static void adjustBoundsToFitInDisplayArea(@NonNull TaskDisplayArea displayArea,
+ int layoutDirection,
@NonNull ActivityInfo.WindowLayout layout,
@NonNull Rect inOutBounds) {
+ // Give a small margin between the window bounds and the display bounds.
+ final Rect stableBounds = TMP_STABLE_BOUNDS;
+ displayArea.getStableRect(stableBounds);
+ final float density = (float) displayArea.getConfiguration().densityDpi / DENSITY_DEFAULT;
+ final int displayEdgeOffset = (int) (DISPLAY_EDGE_OFFSET_DP * density + 0.5f);
+ stableBounds.inset(displayEdgeOffset, displayEdgeOffset);
+
if (stableBounds.width() < inOutBounds.width()
|| stableBounds.height() < inOutBounds.height()) {
- // There is no way for us to fit the bounds in the displayArea without changing width
- // or height. Just move the start to align with the displayArea.
- final int left = layoutDirection == View.LAYOUT_DIRECTION_RTL
- ? stableBounds.right - inOutBounds.right + inOutBounds.left
- : stableBounds.left;
- inOutBounds.offsetTo(left, stableBounds.top);
- return;
+ final float heightShrinkRatio = stableBounds.width() / (float) inOutBounds.width();
+ final float widthShrinkRatio =
+ stableBounds.height() / (float) inOutBounds.height();
+ final float shrinkRatio = Math.min(heightShrinkRatio, widthShrinkRatio);
+ // Minimum layout requirements.
+ final int layoutMinWidth = (layout == null) ? -1 : layout.minWidth;
+ final int layoutMinHeight = (layout == null) ? -1 : layout.minHeight;
+ int adjustedWidth = Math.max(layoutMinWidth, (int) (inOutBounds.width() * shrinkRatio));
+ int adjustedHeight = Math.max(layoutMinHeight,
+ (int) (inOutBounds.height() * shrinkRatio));
+ if (stableBounds.width() < adjustedWidth
+ || stableBounds.height() < adjustedHeight) {
+ // There is no way for us to fit the bounds in the displayArea without breaking min
+ // size constraints. Set the min size to make visible as much content as possible.
+ final int left = layoutDirection == View.LAYOUT_DIRECTION_RTL
+ ? stableBounds.right - adjustedWidth
+ : stableBounds.left;
+ inOutBounds.set(left, stableBounds.top, left + adjustedWidth,
+ stableBounds.top + adjustedHeight);
+ return;
+ }
+ inOutBounds.set(inOutBounds.left, inOutBounds.top,
+ inOutBounds.left + adjustedWidth, inOutBounds.top + adjustedHeight);
}
final int dx;
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index b290bec8c4e0..4e7fe0e71420 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -21,9 +21,6 @@ import static android.app.ActivityTaskManager.INVALID_TASK_ID;
import static android.app.ActivityTaskManager.RESIZE_MODE_FORCED;
import static android.app.ActivityTaskManager.RESIZE_MODE_SYSTEM_SCREEN_ROTATION;
import static android.app.ITaskStackListener.FORCED_RESIZEABLE_REASON_SPLIT_SCREEN;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
@@ -3108,20 +3105,6 @@ class Task extends TaskFragment {
}
@Override
- int getOrientation(int candidate) {
- return canSpecifyOrientation() ? super.getOrientation(candidate) : SCREEN_ORIENTATION_UNSET;
- }
-
- private boolean canSpecifyOrientation() {
- final int windowingMode = getWindowingMode();
- final int activityType = getActivityType();
- return windowingMode == WINDOWING_MODE_FULLSCREEN
- || activityType == ACTIVITY_TYPE_HOME
- || activityType == ACTIVITY_TYPE_RECENTS
- || activityType == ACTIVITY_TYPE_ASSISTANT;
- }
-
- @Override
void forAllLeafTasks(Consumer<Task> callback, boolean traverseTopToBottom) {
final int count = mChildren.size();
boolean isLeafTask = true;
@@ -5167,7 +5150,16 @@ class Task extends TaskFragment {
final Task task = taskTop.getTask();
// If ActivityOptions are moved out and need to be aborted or moved to taskTop.
- final ActivityOptions topOptions = sResetTargetTaskHelper.process(task, forceReset);
+ final ActivityOptions topOptions;
+
+ // Set the task to be reused, so the TaskFragment#mClearedTaskForReuse can be set if the
+ // embedded activities are finished while reset task.
+ mReuseTask = true;
+ try {
+ topOptions = sResetTargetTaskHelper.process(task, forceReset);
+ } finally {
+ mReuseTask = false;
+ }
if (mChildren.contains(task)) {
final ActivityRecord newTop = task.getTopNonFinishingActivity();
diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java
index 6ff91af527ed..f3ed937ce924 100644
--- a/services/core/java/com/android/server/wm/TaskDisplayArea.java
+++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java
@@ -27,7 +27,6 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.content.Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
-import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ORIENTATION;
@@ -649,17 +648,6 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> {
}, SCREEN_ORIENTATION_UNSET);
}
- // Apps and their containers are not allowed to specify an orientation of non floating
- // visible tasks created by organizer and that has an adjacent task.
- final Task nonFloatingTopTask =
- getTask(t -> !t.getWindowConfiguration().tasksAreFloating());
- if (nonFloatingTopTask != null) {
- final Task task = nonFloatingTopTask.getCreatedByOrganizerTask();
- if (task != null && task.getAdjacentTaskFragment() != null && task.isVisible()) {
- return SCREEN_ORIENTATION_UNSPECIFIED;
- }
- }
-
final int orientation = super.getOrientation(candidate);
if (orientation != SCREEN_ORIENTATION_UNSET
&& orientation != SCREEN_ORIENTATION_BEHIND) {
@@ -929,6 +917,7 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> {
// Update windowing mode if necessary, e.g. launch into a different windowing mode.
if (windowingMode != WINDOWING_MODE_UNDEFINED && candidateTask.isRootTask()
&& candidateTask.getWindowingMode() != windowingMode) {
+ candidateTask.mTransitionController.collect(candidateTask);
candidateTask.setWindowingMode(windowingMode);
}
return candidateTask.getRootTask();
diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java
index f0e3644a3ff5..91cb037a386e 100644
--- a/services/core/java/com/android/server/wm/TaskFragment.java
+++ b/services/core/java/com/android/server/wm/TaskFragment.java
@@ -17,7 +17,9 @@
package com.android.server.wm;
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.ROTATION_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
@@ -27,6 +29,8 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.content.pm.ActivityInfo.FLAG_ALLOW_UNTRUSTED_ACTIVITY_EMBEDDING;
import static android.content.pm.ActivityInfo.FLAG_RESUME_WHILE_PAUSING;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
import static android.content.res.Configuration.ORIENTATION_UNDEFINED;
@@ -76,6 +80,7 @@ import android.app.servertransaction.ClientTransaction;
import android.app.servertransaction.NewIntentItem;
import android.app.servertransaction.PauseActivityItem;
import android.app.servertransaction.ResumeActivityItem;
+import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.graphics.Point;
import android.graphics.Rect;
@@ -1809,6 +1814,51 @@ class TaskFragment extends WindowContainer<WindowContainer> {
}
}
+ @ActivityInfo.ScreenOrientation
+ @Override
+ int getOrientation(@ActivityInfo.ScreenOrientation int candidate) {
+ if (shouldReportOrientationUnspecified()) {
+ return SCREEN_ORIENTATION_UNSPECIFIED;
+ }
+ if (canSpecifyOrientation()) {
+ return super.getOrientation(candidate);
+ }
+ return SCREEN_ORIENTATION_UNSET;
+ }
+
+ /**
+ * Whether or not to allow this container to specify an app requested orientation.
+ *
+ * This is different from {@link #providesOrientation()} that
+ * 1. The container may still provide an orientation even if it can't specify the app requested
+ * one, such as {@link #shouldReportOrientationUnspecified()}
+ * 2. Even if the container can specify an app requested orientation, it may not be used by the
+ * parent container if it is {@link ActivityInfo#SCREEN_ORIENTATION_UNSPECIFIED}.
+ */
+ boolean canSpecifyOrientation() {
+ final int windowingMode = getWindowingMode();
+ final int activityType = getActivityType();
+ return windowingMode == WINDOWING_MODE_FULLSCREEN
+ || activityType == ACTIVITY_TYPE_HOME
+ || activityType == ACTIVITY_TYPE_RECENTS
+ || activityType == ACTIVITY_TYPE_ASSISTANT;
+ }
+
+ /**
+ * Whether or not the parent container should use the orientation provided by this container
+ * even if it is {@link ActivityInfo#SCREEN_ORIENTATION_UNSPECIFIED}.
+ */
+ @Override
+ boolean providesOrientation() {
+ return super.providesOrientation() || shouldReportOrientationUnspecified();
+ }
+
+ private boolean shouldReportOrientationUnspecified() {
+ // Apps and their containers are not allowed to specify orientation from adjacent
+ // TaskFragment.
+ return getAdjacentTaskFragment() != null && isVisibleRequested();
+ }
+
@Override
void forAllTaskFragments(Consumer<TaskFragment> callback, boolean traverseTopToBottom) {
super.forAllTaskFragments(callback, traverseTopToBottom);
diff --git a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java
index fdbed2a6f745..6d149da99cb0 100644
--- a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java
+++ b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java
@@ -278,29 +278,31 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier {
// is set with the suggestedDisplayArea. If it is set, but the eventual TaskDisplayArea is
// different, we should recalcuating the bounds.
boolean hasInitialBoundsForSuggestedDisplayAreaInFreeformMode = false;
- if (suggestedDisplayArea.inFreeformWindowingMode()) {
- if (launchMode == WINDOWING_MODE_PINNED) {
- if (DEBUG) appendLog("picture-in-picture");
- } else if (!root.isResizeable()) {
- if (shouldLaunchUnresizableAppInFreeform(root, suggestedDisplayArea, options)) {
- launchMode = WINDOWING_MODE_FREEFORM;
- if (outParams.mBounds.isEmpty()) {
- getTaskBounds(root, suggestedDisplayArea, layout, launchMode,
- hasInitialBounds, outParams.mBounds);
- hasInitialBoundsForSuggestedDisplayAreaInFreeformMode = true;
- }
- if (DEBUG) appendLog("unresizable-freeform");
- } else {
- launchMode = WINDOWING_MODE_FULLSCREEN;
- outParams.mBounds.setEmpty();
- if (DEBUG) appendLog("unresizable-forced-maximize");
+ // shouldSetAsOverrideWindowingMode is set if the task needs to retain the launchMode
+ // regardless of the windowing mode of the parent.
+ boolean shouldSetAsOverrideWindowingMode = false;
+ if (launchMode == WINDOWING_MODE_PINNED) {
+ if (DEBUG) appendLog("picture-in-picture");
+ } else if (!root.isResizeable()) {
+ if (shouldLaunchUnresizableAppInFreeformInFreeformMode(root, suggestedDisplayArea,
+ options)) {
+ launchMode = WINDOWING_MODE_UNDEFINED;
+ if (outParams.mBounds.isEmpty()) {
+ getTaskBounds(root, suggestedDisplayArea, layout, launchMode, hasInitialBounds,
+ outParams.mBounds);
+ hasInitialBoundsForSuggestedDisplayAreaInFreeformMode = true;
}
+ if (DEBUG) appendLog("unresizable-freeform");
+ } else {
+ launchMode = WINDOWING_MODE_FULLSCREEN;
+ outParams.mBounds.setEmpty();
+ shouldSetAsOverrideWindowingMode = true;
+ if (DEBUG) appendLog("unresizable-forced-maximize");
}
- } else {
- if (DEBUG) appendLog("non-freeform-task-display-area");
}
// If launch mode matches display windowing mode, let it inherit from display.
outParams.mWindowingMode = launchMode == suggestedDisplayArea.getWindowingMode()
+ && !shouldSetAsOverrideWindowingMode
? WINDOWING_MODE_UNDEFINED : launchMode;
if (phase == PHASE_WINDOWING_MODE) {
@@ -667,7 +669,7 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier {
inOutBounds.offset(xOffset, yOffset);
}
- private boolean shouldLaunchUnresizableAppInFreeform(ActivityRecord activity,
+ private boolean shouldLaunchUnresizableAppInFreeformInFreeformMode(ActivityRecord activity,
TaskDisplayArea displayArea, @Nullable ActivityOptions options) {
if (options != null && options.getLaunchWindowingMode() == WINDOWING_MODE_FULLSCREEN) {
// Do not launch the activity in freeform if it explicitly requested fullscreen mode.
@@ -680,8 +682,7 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier {
final int displayOrientation = orientationFromBounds(displayArea.getBounds());
final int activityOrientation = resolveOrientation(activity, displayArea,
displayArea.getBounds());
- if (displayArea.getWindowingMode() == WINDOWING_MODE_FREEFORM
- && displayOrientation != activityOrientation) {
+ if (displayOrientation != activityOrientation) {
return true;
}
@@ -785,9 +786,10 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier {
// to the center of suggested bounds (or the displayArea if no suggested bounds). The
// default size might be too big to center to source activity bounds in displayArea, so
// we may need to move it back to the displayArea.
+ adjustBoundsToFitInDisplayArea(displayArea, layout, mTmpBounds);
+ inOutBounds.setEmpty();
LaunchParamsUtil.centerBounds(displayArea, mTmpBounds.width(), mTmpBounds.height(),
inOutBounds);
- adjustBoundsToFitInDisplayArea(displayArea, layout, inOutBounds);
if (DEBUG) appendLog("freeform-size-mismatch=" + inOutBounds);
}
@@ -838,8 +840,7 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier {
@NonNull Rect inOutBounds) {
final int layoutDirection = mSupervisor.mRootWindowContainer.getConfiguration()
.getLayoutDirection();
- displayArea.getStableRect(mTmpStableBounds);
- LaunchParamsUtil.adjustBoundsToFitInDisplayArea(mTmpStableBounds, layoutDirection, layout,
+ LaunchParamsUtil.adjustBoundsToFitInDisplayArea(displayArea, layoutDirection, layout,
inOutBounds);
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 1289634d0a1d..42cd8c11fec2 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -140,6 +140,7 @@ import static com.android.server.wm.WindowManagerDebugConfig.SHOW_STACK_CRAWLS;
import static com.android.server.wm.WindowManagerDebugConfig.SHOW_VERBOSE_TRANSACTIONS;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
+import static com.android.server.wm.WindowManagerServiceDumpProto.BACK_NAVIGATION;
import static com.android.server.wm.WindowManagerServiceDumpProto.DISPLAY_FROZEN;
import static com.android.server.wm.WindowManagerServiceDumpProto.FOCUSED_APP;
import static com.android.server.wm.WindowManagerServiceDumpProto.FOCUSED_DISPLAY_ID;
@@ -6554,6 +6555,9 @@ public class WindowManagerService extends IWindowManager.Stub
// Once we move the window layout to the client side, this can be false when we are waiting
// for the frames.
proto.write(WINDOW_FRAMES_VALID, true);
+
+ // Write the BackNavigationController's state into the protocol buffer
+ mAtmService.mBackNavigationController.dumpDebug(proto, BACK_NAVIGATION);
}
private void dumpWindowsLocked(PrintWriter pw, boolean dumpAll,
diff --git a/services/credentials/java/com/android/server/credentials/CreateRequestSession.java b/services/credentials/java/com/android/server/credentials/CreateRequestSession.java
index 06d8e6280bef..3d337b896bb7 100644
--- a/services/credentials/java/com/android/server/credentials/CreateRequestSession.java
+++ b/services/credentials/java/com/android/server/credentials/CreateRequestSession.java
@@ -72,9 +72,15 @@ public final class CreateRequestSession extends RequestSession<CreateCredentialR
@Override
protected void launchUiWithProviderData(ArrayList<ProviderData> providerDataList) {
- mHandler.post(() -> mCredentialManagerUi.show(RequestInfo.newCreateRequestInfo(
- mRequestId, mClientRequest, mIsFirstUiTurn, mClientCallingPackage),
- providerDataList));
+ try {
+ mClientCallback.onPendingIntent(mCredentialManagerUi.createPendingIntent(
+ RequestInfo.newCreateRequestInfo(
+ mRequestId, mClientRequest, mIsFirstUiTurn, mClientCallingPackage),
+ providerDataList));
+ } catch (RemoteException e) {
+ Log.i(TAG, "Issue with invoking pending intent: " + e.getMessage());
+ // TODO: Propagate failure
+ }
}
private void respondToClientAndFinish(CreateCredentialResponse response) {
diff --git a/services/credentials/java/com/android/server/credentials/CredentialManagerUi.java b/services/credentials/java/com/android/server/credentials/CredentialManagerUi.java
index e889594ff857..33c5ec908838 100644
--- a/services/credentials/java/com/android/server/credentials/CredentialManagerUi.java
+++ b/services/credentials/java/com/android/server/credentials/CredentialManagerUi.java
@@ -16,6 +16,7 @@
package com.android.server.credentials;
import android.annotation.NonNull;
+import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.credentials.ui.IntentFactory;
@@ -30,6 +31,7 @@ import android.util.Log;
import android.util.Slog;
import java.util.ArrayList;
+import java.util.UUID;
/** Initiates the Credential Manager UI and receives results. */
public class CredentialManagerUi {
@@ -79,14 +81,20 @@ public class CredentialManagerUi {
}
/**
- * Surfaces the Credential Manager bottom sheet UI.
+ * Creates a {@link PendingIntent} to be used to invoke the credential manager selector UI,
+ * by the calling app process.
+ * @param requestInfo the information about the request
* @param providerDataList the list of provider data from remote providers
*/
- public void show(RequestInfo requestInfo, ArrayList<ProviderData> providerDataList) {
- Log.i(TAG, "In show");
+ public PendingIntent createPendingIntent(
+ RequestInfo requestInfo, ArrayList<ProviderData> providerDataList) {
+ Log.i(TAG, "In createPendingIntent");
Intent intent = IntentFactory.newIntent(requestInfo, providerDataList, new ArrayList<>(),
- mResultReceiver);
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- mContext.startActivity(intent);
+ mResultReceiver)
+ .setAction(UUID.randomUUID().toString());
+ //TODO: Create unique pending intent using request code and cancel any pre-existing pending
+ // intents
+ return PendingIntent.getActivity(
+ mContext, /*requestCode=*/0, intent, PendingIntent.FLAG_IMMUTABLE);
}
}
diff --git a/services/credentials/java/com/android/server/credentials/GetRequestSession.java b/services/credentials/java/com/android/server/credentials/GetRequestSession.java
index 8a698cab92a1..c092b3af9699 100644
--- a/services/credentials/java/com/android/server/credentials/GetRequestSession.java
+++ b/services/credentials/java/com/android/server/credentials/GetRequestSession.java
@@ -68,9 +68,15 @@ public final class GetRequestSession extends RequestSession<GetCredentialRequest
@Override
protected void launchUiWithProviderData(ArrayList<ProviderData> providerDataList) {
- mHandler.post(() -> mCredentialManagerUi.show(RequestInfo.newGetRequestInfo(
- mRequestId, null, mIsFirstUiTurn, ""),
- providerDataList));
+ try {
+ mClientCallback.onPendingIntent(mCredentialManagerUi.createPendingIntent(
+ RequestInfo.newGetRequestInfo(
+ mRequestId, null, mIsFirstUiTurn, ""),
+ providerDataList));
+ } catch (RemoteException e) {
+ Log.i(TAG, "Issue with invoking pending intent: " + e.getMessage());
+ // TODO: Propagate failure
+ }
}
@Override // from provider session
diff --git a/services/credentials/java/com/android/server/credentials/ProviderCreateSession.java b/services/credentials/java/com/android/server/credentials/ProviderCreateSession.java
index bf37bd2097e2..6bb8c60ec06f 100644
--- a/services/credentials/java/com/android/server/credentials/ProviderCreateSession.java
+++ b/services/credentials/java/com/android/server/credentials/ProviderCreateSession.java
@@ -210,7 +210,7 @@ public final class ProviderCreateSession extends ProviderSession<
private Intent setUpFillInIntent(PendingIntent pendingIntent) {
Intent intent = pendingIntent.getIntent();
intent.putExtra(CredentialProviderService.EXTRA_CREATE_CREDENTIAL_REQUEST_PARAMS,
- mCompleteRequest.getData());
+ mCompleteRequest);
return intent;
}
diff --git a/services/devicepolicy/Android.bp b/services/devicepolicy/Android.bp
index 3a9853d66d10..d4d17ec23d06 100644
--- a/services/devicepolicy/Android.bp
+++ b/services/devicepolicy/Android.bp
@@ -22,5 +22,6 @@ java_library_static {
libs: [
"services.core",
"app-compat-annotations",
+ "service-permission.stubs.system_server",
],
}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/BooleanPolicySerializer.java b/services/devicepolicy/java/com/android/server/devicepolicy/BooleanPolicySerializer.java
new file mode 100644
index 000000000000..8a8485ad5771
--- /dev/null
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/BooleanPolicySerializer.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.devicepolicy;
+
+import com.android.modules.utils.TypedXmlPullParser;
+import com.android.modules.utils.TypedXmlSerializer;
+
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+
+final class BooleanPolicySerializer extends PolicySerializer<Boolean> {
+
+ @Override
+ void saveToXml(TypedXmlSerializer serializer, String attributeName, Boolean value)
+ throws IOException {
+ serializer.attributeBoolean(/* namespace= */ null, attributeName, value);
+ }
+
+ @Override
+ Boolean readFromXml(TypedXmlPullParser parser, String attributeName)
+ throws XmlPullParserException {
+ return parser.getAttributeBoolean(/* namespace= */ null, attributeName);
+ }
+}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java
new file mode 100644
index 000000000000..15c8c2705e6c
--- /dev/null
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java
@@ -0,0 +1,461 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.devicepolicy;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.os.Environment;
+import android.os.UserHandle;
+import android.util.AtomicFile;
+import android.util.Log;
+import android.util.SparseArray;
+import android.util.Xml;
+
+import com.android.internal.util.XmlUtils;
+import com.android.modules.utils.TypedXmlPullParser;
+import com.android.modules.utils.TypedXmlSerializer;
+
+import libcore.io.IoUtils;
+
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * Class responsible for setting, resolving, and enforcing policies set by multiple management
+ * admins on the device.
+ */
+final class DevicePolicyEngine {
+ static final String TAG = "DevicePolicyEngine";
+
+ private final Context mContext;
+ // TODO(b/256849338): add more granular locks
+ private final Object mLock = new Object();
+
+ /**
+ * Map of <userId, Map<policyKey, policyState>>
+ */
+ private final SparseArray<Map<String, PolicyState<?>>> mUserPolicies;
+
+ /**
+ * Map of <policyKey, policyState>
+ */
+ private final Map<String, PolicyState<?>> mGlobalPolicies;
+
+ DevicePolicyEngine(@NonNull Context context) {
+ mContext = Objects.requireNonNull(context);
+ mUserPolicies = new SparseArray<>();
+ mGlobalPolicies = new HashMap<>();
+ }
+
+ // TODO: add more documentation on broadcasts/callbacks to use to get current enforced values
+ /**
+ * Set the policy for the provided {@code policyDefinition}
+ * (see {@link PolicyDefinition}) and {@code enforcingAdmin} to the provided {@code value}.
+ * Returns {@code true} if the enforced policy has been changed.
+ *
+ */
+ <V> boolean setLocalPolicy(
+ @NonNull PolicyDefinition<V> policyDefinition,
+ @NonNull EnforcingAdmin enforcingAdmin,
+ @NonNull V value,
+ int userId) {
+
+ Objects.requireNonNull(policyDefinition);
+ Objects.requireNonNull(enforcingAdmin);
+ Objects.requireNonNull(value);
+
+ synchronized (mLock) {
+ PolicyState<V> policyState = getLocalPolicyStateLocked(policyDefinition, userId);
+
+ boolean policyChanged = policyState.setPolicy(enforcingAdmin, value);
+
+ if (policyChanged) {
+ enforcePolicy(policyDefinition, policyState.getCurrentResolvedPolicy(), userId);
+ }
+ return policyChanged;
+ }
+ }
+
+ // TODO: add more documentation on broadcasts/callbacks to use to get current enforced values
+ /**
+ * Set the policy for the provided {@code policyDefinition}
+ * (see {@link PolicyDefinition}) and {@code enforcingAdmin} to the provided {@code value}.
+ * Returns {@code true} if the enforced policy has been changed.
+ *
+ */
+ <V> boolean setGlobalPolicy(
+ @NonNull PolicyDefinition<V> policyDefinition,
+ @NonNull EnforcingAdmin enforcingAdmin,
+ @NonNull V value) {
+
+ Objects.requireNonNull(policyDefinition);
+ Objects.requireNonNull(enforcingAdmin);
+ Objects.requireNonNull(value);
+
+ synchronized (mLock) {
+ PolicyState<V> policyState = getGlobalPolicyStateLocked(policyDefinition);
+
+ boolean policyChanged = policyState.setPolicy(enforcingAdmin, value);
+
+ if (policyChanged) {
+ enforcePolicy(policyDefinition, policyState.getCurrentResolvedPolicy(),
+ UserHandle.USER_ALL);
+ }
+ return policyChanged;
+ }
+ }
+
+
+ // TODO: add more documentation on broadcasts/callbacks to use to get current enforced values
+ /**
+ * Removes any previously set policy for the provided {@code policyDefinition}
+ * (see {@link PolicyDefinition}) and {@code enforcingAdmin}.
+ * Returns {@code true} if the enforced policy has been changed.
+ *
+ */
+ <V> boolean removeLocalPolicy(
+ @NonNull PolicyDefinition<V> policyDefinition,
+ @NonNull EnforcingAdmin enforcingAdmin,
+ int userId) {
+
+ Objects.requireNonNull(policyDefinition);
+ Objects.requireNonNull(enforcingAdmin);
+
+ synchronized (mLock) {
+ PolicyState<V> policyState = getLocalPolicyStateLocked(policyDefinition, userId);
+ boolean policyChanged = policyState.removePolicy(enforcingAdmin);
+
+ if (policyChanged) {
+ enforcePolicy(policyDefinition, policyState.getCurrentResolvedPolicy(), userId);
+ }
+ write();
+ return policyChanged;
+ }
+ }
+
+ // TODO: add more documentation on broadcasts/callbacks to use to get current enforced values
+ /**
+ * Removes any previously set policy for the provided {@code policyDefinition}
+ * (see {@link PolicyDefinition}) and {@code enforcingAdmin}.
+ * Returns {@code true} if the enforced policy has been changed.
+ *
+ */
+ <V> boolean removeGlobalPolicy(
+ @NonNull PolicyDefinition<V> policyDefinition,
+ @NonNull EnforcingAdmin enforcingAdmin) {
+
+ Objects.requireNonNull(policyDefinition);
+ Objects.requireNonNull(enforcingAdmin);
+
+ synchronized (mLock) {
+ PolicyState<V> policyState = getGlobalPolicyStateLocked(policyDefinition);
+ boolean policyChanged = policyState.removePolicy(enforcingAdmin);
+
+ if (policyChanged) {
+ enforcePolicy(policyDefinition, policyState.getCurrentResolvedPolicy(),
+ UserHandle.USER_ALL);
+ }
+ write();
+ return policyChanged;
+ }
+ }
+
+ /**
+ * Retrieves policies set by all admins for the provided {@code policyDefinition}.
+ *
+ */
+ <V> PolicyState<V> getLocalPolicy(@NonNull PolicyDefinition<V> policyDefinition, int userId) {
+ Objects.requireNonNull(policyDefinition);
+
+ synchronized (mLock) {
+ return getLocalPolicyStateLocked(policyDefinition, userId);
+ }
+ }
+
+ /**
+ * Retrieves policies set by all admins for the provided {@code policyDefinition}.
+ *
+ */
+ <V> PolicyState<V> getGlobalPolicy(@NonNull PolicyDefinition<V> policyDefinition) {
+ Objects.requireNonNull(policyDefinition);
+
+ synchronized (mLock) {
+ return getGlobalPolicyStateLocked(policyDefinition);
+ }
+ }
+
+ @NonNull
+ private <V> PolicyState<V> getLocalPolicyStateLocked(
+ PolicyDefinition<V> policyDefinition, int userId) {
+
+ if (policyDefinition.isGlobalOnlyPolicy()) {
+ throw new IllegalArgumentException("Can't set global policy "
+ + policyDefinition.getPolicyKey() + " locally.");
+ }
+
+ if (!mUserPolicies.contains(userId)) {
+ mUserPolicies.put(userId, new HashMap<>());
+ }
+ if (!mUserPolicies.get(userId).containsKey(policyDefinition.getPolicyKey())) {
+ mUserPolicies.get(userId).put(
+ policyDefinition.getPolicyKey(), new PolicyState<>(policyDefinition));
+ }
+ return getPolicyState(mUserPolicies.get(userId), policyDefinition);
+ }
+
+ @NonNull
+ private <V> PolicyState<V> getGlobalPolicyStateLocked(PolicyDefinition<V> policyDefinition) {
+
+ if (policyDefinition.isLocalOnlyPolicy()) {
+ throw new IllegalArgumentException("Can't set local policy "
+ + policyDefinition.getPolicyKey() + " globally.");
+ }
+
+ if (!mGlobalPolicies.containsKey(policyDefinition.getPolicyKey())) {
+ mGlobalPolicies.put(
+ policyDefinition.getPolicyKey(), new PolicyState<>(policyDefinition));
+ }
+ return getPolicyState(mGlobalPolicies, policyDefinition);
+ }
+
+ private static <V> PolicyState<V> getPolicyState(
+ Map<String, PolicyState<?>> policies, PolicyDefinition<V> policyDefinition) {
+ try {
+ // This will not throw an exception because policyDefinition is of type V, so unless
+ // we've created two policies with the same key but different types - we can only have
+ // stored a PolicyState of the right type.
+ PolicyState<V> policyState = (PolicyState<V>) policies.get(
+ policyDefinition.getPolicyKey());
+ return policyState;
+ } catch (ClassCastException exception) {
+ // TODO: handle exception properly
+ throw new IllegalArgumentException();
+ }
+ }
+
+ private <V> void enforcePolicy(
+ PolicyDefinition<V> policyDefinition, @Nullable V policyValue, int userId) {
+ // TODO: null policyValue means remove any enforced policies, ensure callbacks handle this
+ // properly
+ policyDefinition.enforcePolicy(policyValue, mContext, userId);
+ // TODO: send broadcast or call callback to notify admins of policy change
+ // TODO: notify calling admin of result (e.g. success, runtime failure, policy set by
+ // a different admin)
+ }
+
+ private void write() {
+ Log.d(TAG, "Writing device policies to file.");
+ new DevicePoliciesReaderWriter().writeToFileLocked();
+ }
+
+ // TODO(b/256852787): trigger resolving logic after loading policies as roles are recalculated
+ // and could result in a different enforced policy
+ void load() {
+ Log.d(TAG, "Reading device policies from file.");
+ synchronized (mLock) {
+ clear();
+ new DevicePoliciesReaderWriter().readFromFileLocked();
+ }
+ }
+
+ private void clear() {
+ synchronized (mLock) {
+ mGlobalPolicies.clear();
+ mUserPolicies.clear();
+ }
+ }
+
+ private class DevicePoliciesReaderWriter {
+ private static final String DEVICE_POLICIES_XML = "device_policies.xml";
+ private static final String TAG_USER_POLICY_ENTRY = "user-policy-entry";
+ private static final String TAG_DEVICE_POLICY_ENTRY = "device-policy-entry";
+ private static final String TAG_ADMINS_POLICY_ENTRY = "admins-policy-entry";
+ private static final String ATTR_USER_ID = "user-id";
+ private static final String ATTR_POLICY_ID = "policy-id";
+
+ private final File mFile;
+
+ private DevicePoliciesReaderWriter() {
+ mFile = new File(Environment.getDataSystemDirectory(), DEVICE_POLICIES_XML);
+ }
+
+ void writeToFileLocked() {
+ Log.d(TAG, "Writing to " + mFile);
+
+ AtomicFile f = new AtomicFile(mFile);
+ FileOutputStream outputStream = null;
+ try {
+ outputStream = f.startWrite();
+ TypedXmlSerializer out = Xml.resolveSerializer(outputStream);
+
+ out.startDocument(null, true);
+
+ // Actual content
+ writeInner(out);
+
+ out.endDocument();
+ out.flush();
+
+ // Commit the content.
+ f.finishWrite(outputStream);
+ outputStream = null;
+
+ } catch (IOException e) {
+ Log.e(TAG, "Exception when writing", e);
+ if (outputStream != null) {
+ f.failWrite(outputStream);
+ }
+ }
+ }
+
+ // TODO(b/256846294): Add versioning to read/write
+ void writeInner(TypedXmlSerializer serializer) throws IOException {
+ writeUserPoliciesInner(serializer);
+ writeDevicePoliciesInner(serializer);
+ }
+
+ private void writeUserPoliciesInner(TypedXmlSerializer serializer) throws IOException {
+ if (mUserPolicies != null) {
+ for (int i = 0; i < mUserPolicies.size(); i++) {
+ int userId = mUserPolicies.keyAt(i);
+ for (Map.Entry<String, PolicyState<?>> policy : mUserPolicies.get(
+ userId).entrySet()) {
+ serializer.startTag(/* namespace= */ null, TAG_USER_POLICY_ENTRY);
+
+ serializer.attributeInt(/* namespace= */ null, ATTR_USER_ID, userId);
+ serializer.attribute(
+ /* namespace= */ null, ATTR_POLICY_ID, policy.getKey());
+
+ serializer.startTag(/* namespace= */ null, TAG_ADMINS_POLICY_ENTRY);
+ policy.getValue().saveToXml(serializer);
+ serializer.endTag(/* namespace= */ null, TAG_ADMINS_POLICY_ENTRY);
+
+ serializer.endTag(/* namespace= */ null, TAG_USER_POLICY_ENTRY);
+ }
+ }
+ }
+ }
+
+ private void writeDevicePoliciesInner(TypedXmlSerializer serializer) throws IOException {
+ if (mGlobalPolicies != null) {
+ for (Map.Entry<String, PolicyState<?>> policy : mGlobalPolicies.entrySet()) {
+ serializer.startTag(/* namespace= */ null, TAG_DEVICE_POLICY_ENTRY);
+
+ serializer.attribute(/* namespace= */ null, ATTR_POLICY_ID, policy.getKey());
+
+ serializer.startTag(/* namespace= */ null, TAG_ADMINS_POLICY_ENTRY);
+ policy.getValue().saveToXml(serializer);
+ serializer.endTag(/* namespace= */ null, TAG_ADMINS_POLICY_ENTRY);
+
+ serializer.endTag(/* namespace= */ null, TAG_DEVICE_POLICY_ENTRY);
+ }
+ }
+ }
+
+ void readFromFileLocked() {
+ if (!mFile.exists()) {
+ Log.d(TAG, "" + mFile + " doesn't exist");
+ return;
+ }
+
+ Log.d(TAG, "Reading from " + mFile);
+ AtomicFile f = new AtomicFile(mFile);
+ InputStream input = null;
+ try {
+ input = f.openRead();
+ TypedXmlPullParser parser = Xml.resolvePullParser(input);
+
+ readInner(parser);
+
+ } catch (XmlPullParserException | IOException | ClassNotFoundException e) {
+ Log.e(TAG, "Error parsing resources file", e);
+ } finally {
+ IoUtils.closeQuietly(input);
+ }
+ }
+
+ private void readInner(TypedXmlPullParser parser)
+ throws IOException, XmlPullParserException, ClassNotFoundException {
+ int outerDepth = parser.getDepth();
+ while (XmlUtils.nextElementWithin(parser, outerDepth)) {
+ String tag = parser.getName();
+ switch (tag) {
+ case TAG_USER_POLICY_ENTRY:
+ readUserPoliciesInner(parser);
+ break;
+ case TAG_DEVICE_POLICY_ENTRY:
+ readDevicePoliciesInner(parser);
+ break;
+ default:
+ Log.e(TAG, "Unknown tag " + tag);
+ }
+ }
+ }
+
+ private void readUserPoliciesInner(TypedXmlPullParser parser)
+ throws XmlPullParserException, IOException {
+ int userId = parser.getAttributeInt(/* namespace= */ null, ATTR_USER_ID);
+ String policyKey = parser.getAttributeValue(
+ /* namespace= */ null, ATTR_POLICY_ID);
+ if (!mUserPolicies.contains(userId)) {
+ mUserPolicies.put(userId, new HashMap<>());
+ }
+ PolicyState<?> adminsPolicy = parseAdminsPolicy(parser);
+ if (adminsPolicy != null) {
+ mUserPolicies.get(userId).put(policyKey, adminsPolicy);
+ } else {
+ Log.e(TAG, "Error parsing file, " + policyKey + "doesn't have an "
+ + "AdminsPolicy.");
+ }
+ }
+
+ private void readDevicePoliciesInner(TypedXmlPullParser parser)
+ throws IOException, XmlPullParserException {
+ String policyKey = parser.getAttributeValue(/* namespace= */ null, ATTR_POLICY_ID);
+ PolicyState<?> adminsPolicy = parseAdminsPolicy(parser);
+ if (adminsPolicy != null) {
+ mGlobalPolicies.put(policyKey, adminsPolicy);
+ } else {
+ Log.e(TAG, "Error parsing file, " + policyKey + "doesn't have an "
+ + "AdminsPolicy.");
+ }
+ }
+
+ @Nullable
+ private PolicyState<?> parseAdminsPolicy(TypedXmlPullParser parser)
+ throws XmlPullParserException, IOException {
+ int outerDepth = parser.getDepth();
+ while (XmlUtils.nextElementWithin(parser, outerDepth)) {
+ String tag = parser.getName();
+ if (tag.equals(TAG_ADMINS_POLICY_ENTRY)) {
+ return PolicyState.readFromXml(parser);
+ }
+ Log.e(TAG, "Unknown tag " + tag);
+ }
+ Log.e(TAG, "Error parsing file, AdminsPolicy not found");
+ return null;
+ }
+ }
+}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 53ded6961a25..61d93c7ce655 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -335,6 +335,7 @@ import android.util.IndentingPrintWriter;
import android.util.IntArray;
import android.util.Log;
import android.util.Pair;
+import android.util.Slog;
import android.util.SparseArray;
import android.util.Xml;
import android.view.IWindowManager;
@@ -2901,60 +2902,60 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
policy.validatePasswordOwner();
updateMaximumTimeToLockLocked(userHandle);
- updateLockTaskPackagesLocked(policy.mLockTaskPackages, userHandle);
+ updateLockTaskPackagesLocked(mContext, policy.mLockTaskPackages, userHandle);
updateLockTaskFeaturesLocked(policy.mLockTaskFeatures, userHandle);
if (policy.mStatusBarDisabled) {
setStatusBarDisabledInternal(policy.mStatusBarDisabled, userHandle);
}
}
- private void updateLockTaskPackagesLocked(List<String> packages, int userId) {
- String[] packagesArray = null;
-
- if (!packages.isEmpty()) {
- // When adding packages, we need to include the exempt apps so they can still be
- // launched (ideally we should use a different AM API as these apps don't need to use
- // lock-task mode).
- // They're not added when the packages is empty though, as in that case we're disabling
- // lock-task mode.
- List<String> exemptApps = listPolicyExemptAppsUnchecked();
- if (!exemptApps.isEmpty()) {
- // TODO(b/175377361): add unit test to verify it (cannot be CTS because the policy-
- // -exempt apps are provided by OEM and the test would have no control over it) once
- // tests are migrated to the new infra-structure
- HashSet<String> updatedPackages = new HashSet<>(packages);
- updatedPackages.addAll(exemptApps);
- if (VERBOSE_LOG) {
- Slogf.v(LOG_TAG, "added %d policy-exempt apps to %d lock task packages. Final "
- + "list: %s", exemptApps.size(), packages.size(), updatedPackages);
+ static void updateLockTaskPackagesLocked(Context context, List<String> packages, int userId) {
+ Binder.withCleanCallingIdentity(() -> {
+
+ String[] packagesArray = null;
+ if (!packages.isEmpty()) {
+ // When adding packages, we need to include the exempt apps so they can still be
+ // launched (ideally we should use a different AM API as these apps don't need to
+ // use lock-task mode).
+ // They're not added when the packages is empty though, as in that case we're
+ // disabling lock-task mode.
+ List<String> exemptApps = listPolicyExemptAppsUnchecked(context);
+ if (!exemptApps.isEmpty()) {
+ // TODO(b/175377361): add unit test to verify it (cannot be CTS because the
+ // policy-exempt apps are provided by OEM and the test would have no control
+ // over it) once tests are migrated to the new infra-structure
+ HashSet<String> updatedPackages = new HashSet<>(packages);
+ updatedPackages.addAll(exemptApps);
+ if (VERBOSE_LOG) {
+ Slogf.v(LOG_TAG, "added %d policy-exempt apps to %d lock task "
+ + "packages. Final list: %s",
+ exemptApps.size(), packages.size(), updatedPackages);
+ }
+ packagesArray = updatedPackages.toArray(new String[updatedPackages.size()]);
}
- packagesArray = updatedPackages.toArray(new String[updatedPackages.size()]);
}
- }
-
- if (packagesArray == null) {
- packagesArray = packages.toArray(new String[packages.size()]);
- }
- long ident = mInjector.binderClearCallingIdentity();
- try {
- mInjector.getIActivityManager().updateLockTaskPackages(userId, packagesArray);
- } catch (RemoteException e) {
- // Not gonna happen.
- } finally {
- mInjector.binderRestoreCallingIdentity(ident);
- }
+ if (packagesArray == null) {
+ packagesArray = packages.toArray(new String[packages.size()]);
+ }
+ try {
+ ActivityManager.getService().updateLockTaskPackages(userId, packagesArray);
+ } catch (RemoteException e) {
+ // Shouldn't happen.
+ Slog.wtf(LOG_TAG, "Remote Exception: ", e);
+ }
+ });
}
- private void updateLockTaskFeaturesLocked(int flags, int userId) {
- long ident = mInjector.binderClearCallingIdentity();
- try {
- mInjector.getIActivityTaskManager().updateLockTaskFeatures(userId, flags);
- } catch (RemoteException e) {
- // Not gonna happen.
- } finally {
- mInjector.binderRestoreCallingIdentity(ident);
- }
+ static void updateLockTaskFeaturesLocked(int flags, int userId) {
+ Binder.withCleanCallingIdentity(() -> {
+ try {
+ ActivityTaskManager.getService().updateLockTaskFeatures(userId, flags);
+ } catch (RemoteException e) {
+ // Shouldn't happen.
+ Slog.wtf(LOG_TAG, "Remote Exception: ", e);
+ }
+ });
}
static void validateQualityConstant(int quality) {
@@ -9005,7 +9006,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
policy.mUserProvisioningState = DevicePolicyManager.STATE_USER_UNMANAGED;
policy.mAffiliationIds.clear();
policy.mLockTaskPackages.clear();
- updateLockTaskPackagesLocked(policy.mLockTaskPackages, userId);
+ updateLockTaskPackagesLocked(mContext, policy.mLockTaskPackages, userId);
policy.mLockTaskFeatures = DevicePolicyManager.LOCK_TASK_FEATURE_NONE;
saveSettingsLocked(userId);
@@ -11281,7 +11282,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
private String[] populateNonExemptAndExemptFromPolicyApps(String[] packageNames,
Set<String> outputExemptApps) {
Preconditions.checkArgument(outputExemptApps.isEmpty(), "outputExemptApps is not empty");
- List<String> exemptAppsList = listPolicyExemptAppsUnchecked();
+ List<String> exemptAppsList = listPolicyExemptAppsUnchecked(mContext);
if (exemptAppsList.isEmpty()) {
return packageNames;
}
@@ -11394,16 +11395,16 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
hasCallingOrSelfPermission(permission.MANAGE_DEVICE_ADMINS)
|| isDefaultDeviceOwner(caller) || isProfileOwner(caller));
- return listPolicyExemptAppsUnchecked();
+ return listPolicyExemptAppsUnchecked(mContext);
}
- private List<String> listPolicyExemptAppsUnchecked() {
+ private static List<String> listPolicyExemptAppsUnchecked(Context context) {
// TODO(b/181238156): decide whether it should only list the apps set by the resources,
// or also the "critical" apps defined by PersonalAppsSuspensionHelper (like SMS app).
// If it's the latter, refactor PersonalAppsSuspensionHelper so it (or a superclass) takes
// the resources on constructor.
- String[] core = mContext.getResources().getStringArray(R.array.policy_exempt_apps);
- String[] vendor = mContext.getResources().getStringArray(R.array.vendor_policy_exempt_apps);
+ String[] core = context.getResources().getStringArray(R.array.policy_exempt_apps);
+ String[] vendor = context.getResources().getStringArray(R.array.vendor_policy_exempt_apps);
int size = core.length + vendor.length;
Set<String> apps = new ArraySet<>(size);
@@ -11580,7 +11581,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
&& (isProfileOwner(caller) || isDefaultDeviceOwner(caller)))
|| (caller.hasPackage() && isCallerDelegate(caller, DELEGATION_PACKAGE_ACCESS)));
- List<String> exemptApps = listPolicyExemptAppsUnchecked();
+ List<String> exemptApps = listPolicyExemptAppsUnchecked(mContext);
if (exemptApps.contains(packageName)) {
Slogf.d(LOG_TAG, "setApplicationHidden(): ignoring %s as it's on policy-exempt list",
packageName);
@@ -12255,7 +12256,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
// Store the settings persistently.
saveSettingsLocked(userHandle);
- updateLockTaskPackagesLocked(packages, userHandle);
+ updateLockTaskPackagesLocked(mContext, packages, userHandle);
}
@Override
@@ -12274,7 +12275,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
@Override
public boolean isLockTaskPermitted(String pkg) {
// Check policy-exempt apps first, as it doesn't require the lock
- if (listPolicyExemptAppsUnchecked().contains(pkg)) {
+ if (listPolicyExemptAppsUnchecked(mContext).contains(pkg)) {
if (VERBOSE_LOG) {
Slogf.v(LOG_TAG, "isLockTaskPermitted(%s): returning true for policy-exempt app",
pkg);
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/EnforcingAdmin.java b/services/devicepolicy/java/com/android/server/devicepolicy/EnforcingAdmin.java
new file mode 100644
index 000000000000..9261d59ce1e3
--- /dev/null
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/EnforcingAdmin.java
@@ -0,0 +1,219 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.devicepolicy;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.ComponentName;
+
+import com.android.modules.utils.TypedXmlPullParser;
+import com.android.modules.utils.TypedXmlSerializer;
+import com.android.role.RoleManagerLocal;
+import com.android.server.LocalManagerRegistry;
+
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * {@code EnforcingAdmins} can have the following authority types:
+ *
+ * <ul>
+ * <li> {@link #DPC_AUTHORITY} meaning it's an enterprise admin (e.g. PO, DO, COPE)
+ * <li> {@link #DEVICE_ADMIN_AUTHORITY} which is a legacy non enterprise admin
+ * <li> Or a role authority, in which case {@link #mAuthorities} contains a list of all roles
+ * held by the given {@code packageName}
+ * </ul>
+ *
+ */
+final class EnforcingAdmin {
+ static final String ROLE_AUTHORITY_PREFIX = "role:";
+ static final String DPC_AUTHORITY = "enterprise";
+ static final String DEVICE_ADMIN_AUTHORITY = "device_admin";
+ static final String DEFAULT_AUTHORITY = "default";
+
+ private static final String ATTR_PACKAGE_NAME = "package-name";
+ private static final String ATTR_CLASS_NAME = "class-name";
+ private static final String ATTR_AUTHORITIES = "authorities";
+ private static final String ATTR_AUTHORITIES_SEPARATOR = ";";
+ private static final String ATTR_USER_ID = "user-id";
+ private static final String ATTR_IS_ROLE = "is-role";
+
+ private final String mPackageName;
+ // This is needed for DPCs and active admins
+ private final ComponentName mComponentName;
+ private Set<String> mAuthorities;
+ private final int mUserId;
+ private final boolean mIsRoleAuthority;
+
+ static EnforcingAdmin createEnforcingAdmin(@NonNull String packageName, int userId) {
+ Objects.requireNonNull(packageName);
+ return new EnforcingAdmin(packageName, userId);
+ }
+
+ static EnforcingAdmin createEnterpriseEnforcingAdmin(@NonNull ComponentName componentName) {
+ Objects.requireNonNull(componentName);
+ return new EnforcingAdmin(
+ componentName.getPackageName(), componentName, Set.of(DPC_AUTHORITY));
+ }
+
+ static EnforcingAdmin createDeviceAdminEnforcingAdmin(ComponentName componentName) {
+ Objects.requireNonNull(componentName);
+ return new EnforcingAdmin(
+ componentName.getPackageName(), componentName, Set.of(DEVICE_ADMIN_AUTHORITY));
+ }
+
+ static String getRoleAuthorityOf(String roleName) {
+ return ROLE_AUTHORITY_PREFIX + roleName;
+ }
+
+ private EnforcingAdmin(
+ String packageName, ComponentName componentName, Set<String> authorities) {
+ Objects.requireNonNull(packageName);
+ Objects.requireNonNull(componentName);
+ Objects.requireNonNull(authorities);
+
+ // Role authorities should not be using this constructor
+ mIsRoleAuthority = false;
+ mPackageName = packageName;
+ mComponentName = componentName;
+ mAuthorities = new HashSet<>(authorities);
+ mUserId = -1; // not needed for non role authorities
+ }
+
+ private EnforcingAdmin(String packageName, int userId) {
+ Objects.requireNonNull(packageName);
+
+ // Only role authorities use this constructor.
+ mIsRoleAuthority = true;
+ mPackageName = packageName;
+ mUserId = userId;
+ mComponentName = null;
+ // authorities will be loaded when needed
+ mAuthorities = null;
+ }
+
+ private static Set<String> getRoleAuthoritiesOrDefault(String packageName, int userId) {
+ Set<String> roles = getRoles(packageName, userId);
+ Set<String> authorities = new HashSet<>();
+ for (String role : roles) {
+ authorities.add(ROLE_AUTHORITY_PREFIX + role);
+ }
+ return authorities.isEmpty() ? Set.of(DEFAULT_AUTHORITY) : authorities;
+ }
+
+ // TODO(b/259042794): move this logic to RoleManagerLocal
+ private static Set<String> getRoles(String packageName, int userId) {
+ RoleManagerLocal roleManagerLocal = LocalManagerRegistry.getManager(
+ RoleManagerLocal.class);
+ Set<String> roles = new HashSet<>();
+ Map<String, Set<String>> rolesAndHolders = roleManagerLocal.getRolesAndHolders(userId);
+ for (String role : rolesAndHolders.keySet()) {
+ if (rolesAndHolders.get(role).contains(packageName)) {
+ roles.add(role);
+ }
+ }
+ return roles;
+ }
+
+ private Set<String> getAuthorities() {
+ if (mAuthorities == null) {
+ mAuthorities = getRoleAuthoritiesOrDefault(mPackageName, mUserId);
+ }
+ return mAuthorities;
+ }
+
+ boolean hasAuthority(String authority) {
+ return getAuthorities().contains(authority);
+ }
+
+ /**
+ * For two EnforcingAdmins to be equal they must:
+ *
+ * <ul>
+ * <li> have the same package names and component names and either
+ * <li> have exactly the same authorities ({@link #DPC_AUTHORITY} or
+ * {@link #DEVICE_ADMIN_AUTHORITY}), or have any role or default authorities.
+ * </ul>
+ *
+ * <p>EnforcingAdmins are considered equal if they have any role authority as they can have
+ * roles granted/revoked between calls.
+ */
+ @Override
+ public boolean equals(@Nullable Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ EnforcingAdmin other = (EnforcingAdmin) o;
+ return Objects.equals(mPackageName, other.mPackageName)
+ && Objects.equals(mComponentName, other.mComponentName)
+ && Objects.equals(mIsRoleAuthority, other.mIsRoleAuthority)
+ && hasMatchingAuthorities(this, other);
+ }
+
+ private static boolean hasMatchingAuthorities(EnforcingAdmin admin1, EnforcingAdmin admin2) {
+ if (admin1.mIsRoleAuthority && admin2.mIsRoleAuthority) {
+ return true;
+ }
+ return admin1.getAuthorities().equals(admin2.getAuthorities());
+ }
+
+ @Override
+ public int hashCode() {
+ if (mIsRoleAuthority) {
+ // TODO(b/256854977): should we add UserId?
+ return Objects.hash(mPackageName);
+ } else {
+ return Objects.hash(mComponentName, getAuthorities());
+ }
+ }
+
+ void saveToXml(TypedXmlSerializer serializer) throws IOException {
+ serializer.attribute(/* namespace= */ null, ATTR_PACKAGE_NAME, mPackageName);
+ serializer.attributeBoolean(/* namespace= */ null, ATTR_IS_ROLE, mIsRoleAuthority);
+ if (mIsRoleAuthority) {
+ serializer.attributeInt(/* namespace= */ null, ATTR_USER_ID, mUserId);
+ } else {
+ serializer.attribute(
+ /* namespace= */ null, ATTR_CLASS_NAME, mComponentName.getClassName());
+ serializer.attribute(
+ /* namespace= */ null,
+ ATTR_AUTHORITIES,
+ String.join(ATTR_AUTHORITIES_SEPARATOR, getAuthorities()));
+ }
+ }
+
+ static EnforcingAdmin readFromXml(TypedXmlPullParser parser)
+ throws XmlPullParserException {
+ String packageName = parser.getAttributeValue(/* namespace= */ null, ATTR_PACKAGE_NAME);
+ boolean isRoleAuthority = parser.getAttributeBoolean(/* namespace= */ null, ATTR_IS_ROLE);
+ String authoritiesStr = parser.getAttributeValue(/* namespace= */ null, ATTR_AUTHORITIES);
+
+ if (isRoleAuthority) {
+ int userId = parser.getAttributeInt(/* namespace= */ null, ATTR_USER_ID);
+ return new EnforcingAdmin(packageName, userId);
+ } else {
+ String className = parser.getAttributeValue(/* namespace= */ null, ATTR_CLASS_NAME);
+ ComponentName componentName = new ComponentName(packageName, className);
+ Set<String> authorities = Set.of(authoritiesStr.split(ATTR_AUTHORITIES_SEPARATOR));
+ return new EnforcingAdmin(packageName, componentName, authorities);
+ }
+ }
+}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/IntegerPolicySerializer.java b/services/devicepolicy/java/com/android/server/devicepolicy/IntegerPolicySerializer.java
new file mode 100644
index 000000000000..3152f0ba1f26
--- /dev/null
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/IntegerPolicySerializer.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.devicepolicy;
+
+import com.android.modules.utils.TypedXmlPullParser;
+import com.android.modules.utils.TypedXmlSerializer;
+
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+
+final class IntegerPolicySerializer extends PolicySerializer<Integer> {
+
+ @Override
+ void saveToXml(TypedXmlSerializer serializer, String attributeName, Integer value)
+ throws IOException {
+ serializer.attributeInt(/* namespace= */ null, attributeName, value);
+ }
+
+ @Override
+ Integer readFromXml(TypedXmlPullParser parser, String attributeName)
+ throws XmlPullParserException {
+ return parser.getAttributeInt(/* namespace= */ null, attributeName);
+ }
+}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/IntegerUnion.java b/services/devicepolicy/java/com/android/server/devicepolicy/IntegerUnion.java
new file mode 100644
index 000000000000..00bc261be9d0
--- /dev/null
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/IntegerUnion.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.devicepolicy;
+
+import android.annotation.NonNull;
+
+import java.util.LinkedHashMap;
+import java.util.Objects;
+
+final class IntegerUnion extends ResolutionMechanism<Integer> {
+
+ @Override
+ Integer resolve(@NonNull LinkedHashMap<EnforcingAdmin, Integer> adminPolicies) {
+ Objects.requireNonNull(adminPolicies);
+ if (adminPolicies.isEmpty()) {
+ return null;
+ }
+
+ Integer unionOfPolicies = 0;
+ for (Integer policy : adminPolicies.values()) {
+ unionOfPolicies |= policy;
+ }
+ return unionOfPolicies;
+ }
+}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/LockTaskPolicy.java b/services/devicepolicy/java/com/android/server/devicepolicy/LockTaskPolicy.java
new file mode 100644
index 000000000000..9360fd790ab1
--- /dev/null
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/LockTaskPolicy.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.devicepolicy;
+
+import android.annotation.Nullable;
+
+import com.android.modules.utils.TypedXmlPullParser;
+import com.android.modules.utils.TypedXmlSerializer;
+
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.util.Objects;
+import java.util.Set;
+
+final class LockTaskPolicy {
+ private Set<String> mPackages;
+ private int mFlags;
+
+ LockTaskPolicy(@Nullable Set<String> packages, int flags) {
+ mPackages = packages;
+ mFlags = flags;
+ }
+
+ @Nullable
+ Set<String> getPackages() {
+ return mPackages;
+ }
+
+ int getFlags() {
+ return mFlags;
+ }
+
+ void setPackages(Set<String> packages) {
+ mPackages = packages;
+ }
+
+ void setFlags(int flags) {
+ mFlags = flags;
+ }
+
+ @Override
+ public boolean equals(@Nullable Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ LockTaskPolicy other = (LockTaskPolicy) o;
+ return Objects.equals(mPackages, other.mPackages)
+ && mFlags == other.mFlags;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mPackages, mFlags);
+ }
+
+ static final class LockTaskPolicySerializer extends PolicySerializer<LockTaskPolicy> {
+
+ private static final String ATTR_PACKAGES = ":packages";
+ private static final String ATTR_PACKAGES_SEPARATOR = ";";
+ private static final String ATTR_FLAGS = ":flags";
+
+ @Override
+ void saveToXml(
+ TypedXmlSerializer serializer, String attributeNamePrefix, LockTaskPolicy value)
+ throws IOException {
+ if (value.mPackages != null) {
+ serializer.attribute(
+ /* namespace= */ null,
+ attributeNamePrefix + ATTR_PACKAGES,
+ String.join(ATTR_PACKAGES_SEPARATOR, value.mPackages));
+ }
+ serializer.attributeInt(
+ /* namespace= */ null,
+ attributeNamePrefix + ATTR_FLAGS,
+ value.mFlags);
+ }
+
+ @Override
+ LockTaskPolicy readFromXml(TypedXmlPullParser parser, String attributeNamePrefix)
+ throws XmlPullParserException {
+ String packagesStr = parser.getAttributeValue(
+ /* namespace= */ null,
+ attributeNamePrefix + ATTR_PACKAGES);
+ Set<String> packages = packagesStr == null
+ ? null
+ : Set.of(packagesStr.split(ATTR_PACKAGES_SEPARATOR));
+ int flags = parser.getAttributeInt(
+ /* namespace= */ null,
+ attributeNamePrefix + ATTR_FLAGS);
+ return new LockTaskPolicy(packages, flags);
+ }
+ }
+}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/MostRestrictive.java b/services/devicepolicy/java/com/android/server/devicepolicy/MostRestrictive.java
new file mode 100644
index 000000000000..9a24dcf2395c
--- /dev/null
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/MostRestrictive.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.devicepolicy;
+
+import android.annotation.NonNull;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+final class MostRestrictive<V> extends ResolutionMechanism<V> {
+
+ private List<V> mMostToLeastRestrictive;
+
+ MostRestrictive(@NonNull List<V> mostToLeastRestrictive) {
+ mMostToLeastRestrictive = mostToLeastRestrictive;
+ }
+
+ @Override
+ V resolve(@NonNull LinkedHashMap<EnforcingAdmin, V> adminPolicies) {
+ if (adminPolicies.isEmpty()) {
+ return null;
+ }
+ for (V value : mMostToLeastRestrictive) {
+ if (adminPolicies.containsValue(value)) {
+ return value;
+ }
+ }
+ // Return first set policy if none can be found in known values
+ Map.Entry<EnforcingAdmin, V> policy = adminPolicies.entrySet().stream().findFirst().get();
+ return policy.getValue();
+ }
+}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java
new file mode 100644
index 000000000000..3a18cb9c244f
--- /dev/null
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.devicepolicy;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.admin.DevicePolicyManager;
+import android.content.Context;
+
+import com.android.internal.util.function.QuadFunction;
+import com.android.modules.utils.TypedXmlPullParser;
+import com.android.modules.utils.TypedXmlSerializer;
+
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+final class PolicyDefinition<V> {
+ private static final int POLICY_FLAG_NONE = 0;
+
+ // Only use this flag if a policy can not be applied locally.
+ private static final int POLICY_FLAG_GLOBAL_ONLY_POLICY = 1;
+
+ // Only use this flag if a policy can not be applied globally.
+ private static final int POLICY_FLAG_LOCAL_ONLY_POLICY = 1 << 1;
+
+ private static final MostRestrictive<Boolean> FALSE_MORE_RESTRICTIVE = new MostRestrictive<>(
+ List.of(false, true));
+
+ private static final String ATTR_POLICY_KEY = "policy-key";
+ private static final String ATTR_POLICY_DEFINITION_KEY = "policy-type-key";
+ private static final String ATTR_CALLBACK_ARGS = "callback-args";
+ private static final String ATTR_CALLBACK_ARGS_SEPARATOR = ";";
+
+
+ static PolicyDefinition<Boolean> AUTO_TIMEZONE = new PolicyDefinition<>(
+ DevicePolicyManager.AUTO_TIMEZONE_POLICY,
+ // auto timezone is enabled by default, hence disabling it is more restrictive.
+ FALSE_MORE_RESTRICTIVE,
+ POLICY_FLAG_GLOBAL_ONLY_POLICY,
+ (Boolean value, Context context, Integer userId, String[] args) ->
+ PolicyEnforcerCallbacks.setAutoTimezoneEnabled(value, context),
+ new BooleanPolicySerializer());
+
+ // This is saved in the static map sPolicyDefinitions so that we're able to reconstruct the
+ // actual permission grant policy with the correct arguments (packageName and permission name)
+ // when reading the policies from xml.
+ private static final PolicyDefinition<Integer> PERMISSION_GRANT_NO_ARGS =
+ new PolicyDefinition<>(DevicePolicyManager.PERMISSION_GRANT_POLICY_KEY,
+ // TODO: is this really the best mechanism, what makes denied more
+ // restrictive than
+ // granted?
+ new MostRestrictive<>(
+ List.of(DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED,
+ DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED,
+ DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT)),
+ POLICY_FLAG_LOCAL_ONLY_POLICY,
+ PolicyEnforcerCallbacks::setPermissionGrantState,
+ new IntegerPolicySerializer());
+
+ static PolicyDefinition<Integer> PERMISSION_GRANT(
+ @NonNull String packageName, @NonNull String permission) {
+ return PERMISSION_GRANT_NO_ARGS.setArgs(
+ DevicePolicyManager.PERMISSION_GRANT_POLICY(packageName, permission),
+ new String[]{packageName, permission});
+ }
+
+ static PolicyDefinition<LockTaskPolicy> LOCK_TASK = new PolicyDefinition<>(
+ DevicePolicyManager.LOCK_TASK_POLICY,
+ new TopPriority<>(List.of(
+ // TODO(b/258166155): add correct device lock role name
+ EnforcingAdmin.getRoleAuthorityOf("DeviceLock"),
+ EnforcingAdmin.DPC_AUTHORITY)),
+ POLICY_FLAG_LOCAL_ONLY_POLICY,
+ (LockTaskPolicy value, Context context, Integer userId, String[] args) ->
+ PolicyEnforcerCallbacks.setLockTask(value, context, userId),
+ new LockTaskPolicy.LockTaskPolicySerializer());
+
+ private static Map<String, PolicyDefinition<?>> sPolicyDefinitions = Map.of(
+ DevicePolicyManager.AUTO_TIMEZONE_POLICY, AUTO_TIMEZONE,
+ DevicePolicyManager.PERMISSION_GRANT_POLICY_KEY, PERMISSION_GRANT_NO_ARGS
+ );
+
+
+ private final String mPolicyKey;
+ private final String mPolicyDefinitionKey;
+ private final ResolutionMechanism<V> mResolutionMechanism;
+ private final int mPolicyFlags;
+ // A function that accepts policy to apple, context, userId, callback arguments, and returns
+ // true if the policy has been enforced successfully.
+ private final QuadFunction<V, Context, Integer, String[], Boolean> mPolicyEnforcerCallback;
+ private final String[] mCallbackArgs;
+ private final PolicySerializer<V> mPolicySerializer;
+
+ private PolicyDefinition<V> setArgs(String key, String[] callbackArgs) {
+ return new PolicyDefinition<>(key, mPolicyDefinitionKey, mResolutionMechanism,
+ mPolicyFlags, mPolicyEnforcerCallback, mPolicySerializer, callbackArgs);
+ }
+
+ String getPolicyKey() {
+ return mPolicyKey;
+ }
+
+ /**
+ * Returns {@code true} if the policy is a global policy by nature and can't be applied locally.
+ */
+ boolean isGlobalOnlyPolicy() {
+ return (mPolicyFlags & POLICY_FLAG_GLOBAL_ONLY_POLICY) != 0;
+ }
+
+ /**
+ * Returns {@code true} if the policy is a local policy by nature and can't be applied globally.
+ */
+ boolean isLocalOnlyPolicy() {
+ return (mPolicyFlags & POLICY_FLAG_LOCAL_ONLY_POLICY) != 0;
+ }
+
+ @Nullable
+ V resolvePolicy(LinkedHashMap<EnforcingAdmin, V> adminsPolicy) {
+ return mResolutionMechanism.resolve(adminsPolicy);
+ }
+
+ boolean enforcePolicy(@Nullable V value, Context context, int userId) {
+ return mPolicyEnforcerCallback.apply(value, context, userId, mCallbackArgs);
+ }
+
+ /**
+ * Callers must ensure that {@code policyType} have implemented an appropriate
+ * {@link Object#equals} implementation.
+ */
+ private PolicyDefinition(
+ String key,
+ ResolutionMechanism<V> resolutionMechanism,
+ QuadFunction<V, Context, Integer, String[], Boolean> policyEnforcerCallback,
+ PolicySerializer<V> policySerializer) {
+ this(key, resolutionMechanism, POLICY_FLAG_NONE, policyEnforcerCallback, policySerializer);
+ }
+
+ /**
+ * Callers must ensure that {@code policyType} have implemented an appropriate
+ * {@link Object#equals} implementation.
+ */
+ private PolicyDefinition(
+ String key,
+ ResolutionMechanism<V> resolutionMechanism,
+ int policyFlags,
+ QuadFunction<V, Context, Integer, String[], Boolean> policyEnforcerCallback,
+ PolicySerializer<V> policySerializer) {
+ this(key, key, resolutionMechanism, policyFlags, policyEnforcerCallback,
+ policySerializer, /* callbackArs= */ null);
+ }
+
+ /**
+ * Callers must ensure that {@code policyType} have implemented an appropriate
+ * {@link Object#equals} implementation.
+ */
+ private PolicyDefinition(
+ String policyKey,
+ String policyDefinitionKey,
+ ResolutionMechanism<V> resolutionMechanism,
+ int policyFlags,
+ QuadFunction<V, Context, Integer, String[], Boolean> policyEnforcerCallback,
+ PolicySerializer<V> policySerializer,
+ String[] callbackArgs) {
+ mPolicyKey = policyKey;
+ mPolicyDefinitionKey = policyDefinitionKey;
+ mResolutionMechanism = resolutionMechanism;
+ mPolicyFlags = policyFlags;
+ mPolicyEnforcerCallback = policyEnforcerCallback;
+ mPolicySerializer = policySerializer;
+ mCallbackArgs = callbackArgs;
+
+ // TODO: maybe use this instead of manually adding to the map
+// sPolicyDefinitions.put(policyDefinitionKey, this);
+ }
+
+ void saveToXml(TypedXmlSerializer serializer) throws IOException {
+ serializer.attribute(/* namespace= */ null, ATTR_POLICY_KEY, mPolicyKey);
+ serializer.attribute(
+ /* namespace= */ null, ATTR_POLICY_DEFINITION_KEY, mPolicyDefinitionKey);
+ if (mCallbackArgs != null) {
+ serializer.attribute(/* namespace= */ null, ATTR_CALLBACK_ARGS,
+ String.join(ATTR_CALLBACK_ARGS_SEPARATOR, mCallbackArgs));
+ }
+ }
+
+ static <V> PolicyDefinition<V> readFromXml(TypedXmlPullParser parser) {
+ String policyKey = parser.getAttributeValue(/* namespace= */ null, ATTR_POLICY_KEY);
+ String policyDefinitionKey = parser.getAttributeValue(
+ /* namespace= */ null, ATTR_POLICY_DEFINITION_KEY);
+ String callbackArgsStr = parser.getAttributeValue(
+ /* namespace= */ null, ATTR_CALLBACK_ARGS);
+ String[] callbackArgs = callbackArgsStr == null
+ ? null
+ : callbackArgsStr.split(ATTR_CALLBACK_ARGS_SEPARATOR);
+
+ // TODO: can we avoid casting?
+ if (callbackArgs == null) {
+ return (PolicyDefinition<V>) sPolicyDefinitions.get(policyDefinitionKey);
+ } else {
+ return (PolicyDefinition<V>) sPolicyDefinitions.get(policyDefinitionKey).setArgs(
+ policyKey, callbackArgs);
+ }
+ }
+
+ void savePolicyValueToXml(TypedXmlSerializer serializer, String attributeName, V value)
+ throws IOException {
+ mPolicySerializer.saveToXml(serializer, attributeName, value);
+ }
+
+ V readPolicyValueFromXml(TypedXmlPullParser parser, String attributeName)
+ throws XmlPullParserException {
+ return mPolicySerializer.readFromXml(parser, attributeName);
+ }
+}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java
new file mode 100644
index 000000000000..b645b979ef0c
--- /dev/null
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.devicepolicy;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.admin.DevicePolicyManager;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.os.Binder;
+import android.os.UserHandle;
+import android.permission.AdminPermissionControlParams;
+import android.permission.PermissionControllerManager;
+import android.provider.Settings;
+
+import com.android.server.utils.Slogf;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+
+final class PolicyEnforcerCallbacks {
+
+ private static final String LOG_TAG = "PolicyEnforcerCallbacks";
+
+ static boolean setAutoTimezoneEnabled(@Nullable Boolean enabled, @NonNull Context context) {
+ return Binder.withCleanCallingIdentity(() -> {
+ Objects.requireNonNull(context);
+
+ int value = enabled != null && enabled ? 1 : 0;
+ return Settings.Global.putInt(
+ context.getContentResolver(), Settings.Global.AUTO_TIME_ZONE,
+ value);
+ });
+ }
+
+ static boolean setPermissionGrantState(
+ @Nullable Integer grantState, @NonNull Context context, int userId,
+ @NonNull String[] args) {
+ Binder.withCleanCallingIdentity(() -> {
+ if (args == null || args.length < 2) {
+ throw new IllegalArgumentException("Package name and permission name must be "
+ + "provided as arguments");
+ }
+ String packageName = args[0];
+ String permissionName = args[1];
+ Objects.requireNonNull(packageName);
+ Objects.requireNonNull(permissionName);
+ Objects.requireNonNull(context);
+
+ int value = grantState == null
+ ? DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT
+ : grantState;
+
+ BlockingCallback callback = new BlockingCallback();
+ // TODO: remove canAdminGrantSensorPermissions once we expose a new method in
+ // permissionController that doesn't need it.
+ AdminPermissionControlParams permissionParams = new AdminPermissionControlParams(
+ packageName, permissionName, value,
+ /* canAdminGrantSensorPermissions= */ true);
+ getPermissionControllerManager(context, UserHandle.of(userId))
+ // TODO: remove callingPackage param and stop passing context.getPackageName()
+ .setRuntimePermissionGrantStateByDeviceAdmin(context.getPackageName(),
+ permissionParams, context.getMainExecutor(), callback::trigger);
+ try {
+ return callback.await(20_000, TimeUnit.MILLISECONDS);
+ } catch (Exception e) {
+ // TODO: add logging
+ return false;
+ }
+ });
+ return true;
+ }
+
+ @NonNull
+ private static PermissionControllerManager getPermissionControllerManager(
+ Context context, UserHandle user) {
+ if (user.equals(context.getUser())) {
+ return context.getSystemService(PermissionControllerManager.class);
+ } else {
+ try {
+ return context.createPackageContextAsUser(context.getPackageName(), /* flags= */ 0,
+ user).getSystemService(PermissionControllerManager.class);
+ } catch (PackageManager.NameNotFoundException notPossible) {
+ // not possible
+ throw new IllegalStateException(notPossible);
+ }
+ }
+ }
+
+ static boolean setLockTask(
+ @Nullable LockTaskPolicy policy, @NonNull Context context, int userId) {
+ DevicePolicyManagerService.updateLockTaskPackagesLocked(
+ context, List.copyOf(policy.getPackages()), userId);
+ DevicePolicyManagerService.updateLockTaskFeaturesLocked(policy.getFlags(), userId);
+ return true;
+ }
+
+ private static class BlockingCallback {
+ private final CountDownLatch mLatch = new CountDownLatch(1);
+ private final AtomicReference<Boolean> mValue = new AtomicReference<>();
+ public void trigger(Boolean value) {
+ mValue.set(value);
+ mLatch.countDown();
+ }
+
+ public Boolean await(long timeout, TimeUnit unit) throws InterruptedException {
+ if (!mLatch.await(timeout, unit)) {
+ Slogf.e(LOG_TAG, "Callback was not received");
+ }
+ return mValue.get();
+ }
+ }
+}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PolicySerializer.java b/services/devicepolicy/java/com/android/server/devicepolicy/PolicySerializer.java
new file mode 100644
index 000000000000..b3259d34bd3f
--- /dev/null
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/PolicySerializer.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.devicepolicy;
+
+import com.android.modules.utils.TypedXmlPullParser;
+import com.android.modules.utils.TypedXmlSerializer;
+
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+
+abstract class PolicySerializer<V> {
+ abstract void saveToXml(TypedXmlSerializer serializer, String attributeName, V value)
+ throws IOException;
+ abstract V readFromXml(TypedXmlPullParser parser, String attributeName)
+ throws XmlPullParserException;
+}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyState.java b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyState.java
new file mode 100644
index 000000000000..aad82cdf3254
--- /dev/null
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyState.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.devicepolicy;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.util.Log;
+
+import com.android.internal.util.XmlUtils;
+import com.android.modules.utils.TypedXmlPullParser;
+import com.android.modules.utils.TypedXmlSerializer;
+
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.util.LinkedHashMap;
+import java.util.Objects;
+
+/**
+ * Class containing all values set for a certain policy by different admins.
+ */
+final class PolicyState<V> {
+ private static final String TAG_ADMIN_POLICY_ENTRY = "admin-policy-entry";
+ private static final String TAG_ENFORCING_ADMIN_ENTRY = "enforcing-admin-entry";
+ private static final String ATTR_POLICY_VALUE = "policy-value";
+ private static final String ATTR_RESOLVED_POLICY = "resolved-policy";
+
+ private final PolicyDefinition<V> mPolicyDefinition;
+ private final LinkedHashMap<EnforcingAdmin, V> mAdminsPolicy = new LinkedHashMap<>();
+ private V mCurrentResolvedPolicy;
+
+ PolicyState(@NonNull PolicyDefinition<V> policyDefinition) {
+ mPolicyDefinition = Objects.requireNonNull(policyDefinition);
+ }
+
+ private PolicyState(
+ @NonNull PolicyDefinition<V> policyDefinition,
+ @NonNull LinkedHashMap<EnforcingAdmin, V> adminsPolicy,
+ V currentEnforcedPolicy) {
+ Objects.requireNonNull(policyDefinition);
+ Objects.requireNonNull(adminsPolicy);
+
+ mPolicyDefinition = policyDefinition;
+ mAdminsPolicy.putAll(adminsPolicy);
+ mCurrentResolvedPolicy = currentEnforcedPolicy;
+ }
+
+ /**
+ * Returns {@code true} if the resolved policy has changed, {@code false} otherwise.
+ */
+ boolean setPolicy(@NonNull EnforcingAdmin admin, @NonNull V value) {
+ mAdminsPolicy.put(Objects.requireNonNull(admin), Objects.requireNonNull(value));
+
+ return resolvePolicy();
+ }
+
+ boolean removePolicy(@NonNull EnforcingAdmin admin) {
+ Objects.requireNonNull(admin);
+
+ if (mAdminsPolicy.remove(admin) == null) {
+ return false;
+ }
+
+ return resolvePolicy();
+ }
+
+ private boolean resolvePolicy() {
+ V resolvedPolicy = mPolicyDefinition.resolvePolicy(mAdminsPolicy);
+ boolean policyChanged = Objects.equals(resolvedPolicy, mCurrentResolvedPolicy);
+ mCurrentResolvedPolicy = resolvedPolicy;
+
+ return policyChanged;
+ }
+
+ @Nullable
+ V getCurrentResolvedPolicy() {
+ return mCurrentResolvedPolicy;
+ }
+
+ void saveToXml(TypedXmlSerializer serializer) throws IOException {
+ mPolicyDefinition.saveToXml(serializer);
+
+ mPolicyDefinition.savePolicyValueToXml(
+ serializer, ATTR_RESOLVED_POLICY, mCurrentResolvedPolicy);
+
+ for (EnforcingAdmin admin : mAdminsPolicy.keySet()) {
+ serializer.startTag(/* namespace= */ null, TAG_ADMIN_POLICY_ENTRY);
+
+ mPolicyDefinition.savePolicyValueToXml(
+ serializer, ATTR_POLICY_VALUE, mAdminsPolicy.get(admin));
+
+ serializer.startTag(/* namespace= */ null, TAG_ENFORCING_ADMIN_ENTRY);
+ admin.saveToXml(serializer);
+ serializer.endTag(/* namespace= */ null, TAG_ENFORCING_ADMIN_ENTRY);
+
+ serializer.endTag(/* namespace= */ null, TAG_ADMIN_POLICY_ENTRY);
+ }
+ }
+
+ static <V> PolicyState<V> readFromXml(TypedXmlPullParser parser)
+ throws IOException, XmlPullParserException {
+ PolicyDefinition<V> policyDefinition = PolicyDefinition.readFromXml(parser);
+ LinkedHashMap<EnforcingAdmin, V> adminsPolicy = new LinkedHashMap<>();
+ V currentResolvedPolicy = policyDefinition.readPolicyValueFromXml(
+ parser, ATTR_RESOLVED_POLICY);
+ int outerDepth = parser.getDepth();
+ while (XmlUtils.nextElementWithin(parser, outerDepth)) {
+ String tag = parser.getName();
+ if (TAG_ADMIN_POLICY_ENTRY.equals(tag)) {
+ V value = policyDefinition.readPolicyValueFromXml(
+ parser, ATTR_POLICY_VALUE);
+ EnforcingAdmin admin;
+ int adminPolicyDepth = parser.getDepth();
+ if (XmlUtils.nextElementWithin(parser, adminPolicyDepth)
+ && parser.getName().equals(TAG_ENFORCING_ADMIN_ENTRY)) {
+ admin = EnforcingAdmin.readFromXml(parser);
+ adminsPolicy.put(admin, value);
+ }
+ } else {
+ Log.e(DevicePolicyEngine.TAG, "Unknown tag: " + tag);
+ }
+ }
+ return new PolicyState<V>(policyDefinition, adminsPolicy, currentResolvedPolicy);
+ }
+}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/ResolutionMechanism.java b/services/devicepolicy/java/com/android/server/devicepolicy/ResolutionMechanism.java
new file mode 100644
index 000000000000..7b720bcd12e6
--- /dev/null
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/ResolutionMechanism.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.devicepolicy;
+
+import android.annotation.Nullable;
+
+import java.util.LinkedHashMap;
+
+abstract class ResolutionMechanism<V> {
+ @Nullable
+ abstract V resolve(LinkedHashMap<EnforcingAdmin, V> adminPolicies);
+}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/SetUnion.java b/services/devicepolicy/java/com/android/server/devicepolicy/SetUnion.java
new file mode 100644
index 000000000000..8a932c397745
--- /dev/null
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/SetUnion.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.devicepolicy;
+
+import android.annotation.NonNull;
+
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.Objects;
+import java.util.Set;
+
+final class SetUnion<V> extends ResolutionMechanism<Set<V>> {
+
+ @Override
+ Set<V> resolve(@NonNull LinkedHashMap<EnforcingAdmin, Set<V>> adminPolicies) {
+ Objects.requireNonNull(adminPolicies);
+ if (adminPolicies.isEmpty()) {
+ return null;
+ }
+ Set<V> unionOfPolicies = new HashSet<>();
+ for (Set<V> policy : adminPolicies.values()) {
+ unionOfPolicies.addAll(policy);
+ }
+ return unionOfPolicies;
+ }
+}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/TopPriority.java b/services/devicepolicy/java/com/android/server/devicepolicy/TopPriority.java
new file mode 100644
index 000000000000..4467b22c2116
--- /dev/null
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/TopPriority.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.devicepolicy;
+
+import android.annotation.NonNull;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+
+final class TopPriority<V> extends ResolutionMechanism<V> {
+
+ private final List<String> mHighestToLowestPriorityAuthorities;
+
+ TopPriority(@NonNull List<String> highestToLowestPriorityAuthorities) {
+ Objects.requireNonNull(highestToLowestPriorityAuthorities);
+ mHighestToLowestPriorityAuthorities = highestToLowestPriorityAuthorities;
+ }
+
+ @Override
+ V resolve(@NonNull LinkedHashMap<EnforcingAdmin, V> adminPolicies) {
+ if (adminPolicies.isEmpty()) {
+ return null;
+ }
+ for (String authority : mHighestToLowestPriorityAuthorities) {
+ Optional<EnforcingAdmin> admin = adminPolicies.keySet().stream()
+ .filter(a -> a.hasAuthority(authority)).findFirst();
+ if (admin.isPresent()) {
+ return adminPolicies.get(admin.get());
+ }
+ }
+ // Return first set policy if no known authority is found
+ Map.Entry<EnforcingAdmin, V> policy = adminPolicies.entrySet().stream().findFirst().get();
+ return policy.getValue();
+ }
+}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 9089bf7e3009..c346b2f52dc2 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -41,7 +41,6 @@ import android.app.usage.UsageStatsManagerInternal;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
-import android.content.pm.IPackageManager;
import android.content.pm.PackageItemInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
@@ -55,6 +54,7 @@ import android.hardware.display.DisplayManagerInternal;
import android.net.ConnectivityManager;
import android.net.ConnectivityModuleConnector;
import android.net.NetworkStackClient;
+import android.os.ArtModuleServiceManager;
import android.os.BaseBundle;
import android.os.Binder;
import android.os.Build;
@@ -108,6 +108,7 @@ import com.android.server.am.ActivityManagerService;
import com.android.server.ambientcontext.AmbientContextManagerService;
import com.android.server.appbinding.AppBindingService;
import com.android.server.art.ArtManagerLocal;
+import com.android.server.art.ArtModuleServiceInitializer;
import com.android.server.attention.AttentionManagerService;
import com.android.server.audio.AudioService;
import com.android.server.biometrics.AuthService;
@@ -166,7 +167,6 @@ import com.android.server.pm.PackageManagerService;
import com.android.server.pm.ShortcutService;
import com.android.server.pm.UserManagerService;
import com.android.server.pm.dex.OdsignStatsLogger;
-import com.android.server.pm.dex.SystemServerDexLoadReporter;
import com.android.server.pm.verify.domain.DomainVerificationService;
import com.android.server.policy.AppOpsPolicy;
import com.android.server.policy.PermissionPolicyService;
@@ -1208,24 +1208,16 @@ public final class SystemServer implements Dumpable {
mSystemServiceManager.startService(domainVerificationService);
t.traceEnd();
- IPackageManager iPackageManager;
t.traceBegin("StartPackageManagerService");
try {
Watchdog.getInstance().pauseWatchingCurrentThread("packagemanagermain");
- Pair<PackageManagerService, IPackageManager> pmsPair = PackageManagerService.main(
+ mPackageManagerService = PackageManagerService.main(
mSystemContext, installer, domainVerificationService,
mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF);
- mPackageManagerService = pmsPair.first;
- iPackageManager = pmsPair.second;
} finally {
Watchdog.getInstance().resumeWatchingCurrentThread("packagemanagermain");
}
- // Now that the package manager has started, register the dex load reporter to capture any
- // dex files loaded by system server.
- // These dex files will be optimized by the BackgroundDexOptService.
- SystemServerDexLoadReporter.configureSystemServerDexReporter(iPackageManager);
-
mFirstBoot = mPackageManagerService.isFirstBoot();
mPackageManager = mSystemContext.getPackageManager();
t.traceEnd();
@@ -2723,6 +2715,7 @@ public final class SystemServer implements Dumpable {
t.traceEnd();
t.traceBegin("ArtManagerLocal");
+ ArtModuleServiceInitializer.setArtModuleServiceManager(new ArtModuleServiceManager());
LocalManagerRegistry.addManager(ArtManagerLocal.class, new ArtManagerLocal(context));
t.traceEnd();
diff --git a/services/permission/java/com/android/server/permission/access/AccessCheckingService.kt b/services/permission/java/com/android/server/permission/access/AccessCheckingService.kt
new file mode 100644
index 000000000000..c6ccc0fb1cff
--- /dev/null
+++ b/services/permission/java/com/android/server/permission/access/AccessCheckingService.kt
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.permission.access
+
+import com.android.internal.annotations.Keep
+import com.android.server.permission.access.external.PackageState
+
+@Keep
+class AccessCheckingService {
+ @Volatile
+ private lateinit var state: AccessState
+ private val stateLock = Any()
+
+ private val policy = AccessPolicy()
+
+ private val persistence = AccessPersistence(policy)
+
+ fun init() {
+ val state = AccessState()
+ state.systemState.userIds.apply {
+ // TODO: Get and add all user IDs.
+ // TODO: Maybe get and add all packages?
+ }
+ persistence.read(state)
+ this.state = state
+ }
+
+ fun getDecision(subject: AccessUri, `object`: AccessUri): Int =
+ policy.getDecision(subject, `object`, state)
+
+ fun setDecision(subject: AccessUri, `object`: AccessUri, decision: Int) {
+ mutateState { oldState, newState ->
+ policy.setDecision(subject, `object`, decision, oldState, newState)
+ }
+ }
+
+ fun onUserAdded(userId: Int) {
+ mutateState { oldState, newState ->
+ policy.onUserAdded(userId, oldState, newState)
+ }
+ }
+
+ fun onUserRemoved(userId: Int) {
+ mutateState { oldState, newState ->
+ policy.onUserRemoved(userId, oldState, newState)
+ }
+ }
+
+ fun onPackageAdded(packageState: PackageState) {
+ mutateState { oldState, newState ->
+ policy.onPackageAdded(packageState, oldState, newState)
+ }
+ }
+
+ fun onPackageRemoved(packageState: PackageState) {
+ mutateState { oldState, newState ->
+ policy.onPackageRemoved(packageState, oldState, newState)
+ }
+ }
+
+ // TODO: Replace (oldState, newState) with Kotlin context receiver once it's stabilized.
+ private inline fun mutateState(action: (oldState: AccessState, newState: AccessState) -> Unit) {
+ synchronized(stateLock) {
+ val oldState = state
+ val newState = oldState.copy()
+ action(oldState, newState)
+ persistence.write(newState)
+ state = newState
+ }
+ }
+}
diff --git a/services/permission/java/com/android/server/permission/access/AccessPersistence.kt b/services/permission/java/com/android/server/permission/access/AccessPersistence.kt
new file mode 100644
index 000000000000..0efc1bd00de2
--- /dev/null
+++ b/services/permission/java/com/android/server/permission/access/AccessPersistence.kt
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.permission.access
+
+import android.util.AtomicFile
+import android.util.Log
+import com.android.modules.utils.BinaryXmlPullParser
+import com.android.modules.utils.BinaryXmlSerializer
+import com.android.server.permission.access.collection.* // ktlint-disable no-wildcard-imports
+import com.android.server.permission.access.util.PermissionApex
+import com.android.server.permission.access.util.parseBinaryXml
+import com.android.server.permission.access.util.read
+import com.android.server.permission.access.util.serializeBinaryXml
+import com.android.server.permission.access.util.writeInlined
+import java.io.File
+import java.io.FileNotFoundException
+
+class AccessPersistence(
+ private val policy: AccessPolicy
+) {
+ fun read(state: AccessState) {
+ readSystemState(state.systemState)
+ val userStates = state.userStates
+ state.systemState.userIds.forEachIndexed { _, userId ->
+ readUserState(userId, userStates[userId])
+ }
+ }
+
+ private fun readSystemState(systemState: SystemState) {
+ systemFile.parse {
+ // This is the canonical way to call an extension function in a different class.
+ // TODO(b/259469752): Use context receiver for this when it becomes stable.
+ with(policy) { this@parse.parseSystemState(systemState) }
+ }
+ }
+
+ private fun readUserState(userId: Int, userState: UserState) {
+ getUserFile(userId).parse {
+ with(policy) { this@parse.parseUserState(userId, userState) }
+ }
+ }
+
+ private inline fun File.parse(block: BinaryXmlPullParser.() -> Unit) {
+ try {
+ AtomicFile(this).read { it.parseBinaryXml(block) }
+ } catch (e: FileNotFoundException) {
+ Log.i(LOG_TAG, "$this not found")
+ } catch (e: Exception) {
+ throw IllegalStateException("Failed to read $this", e)
+ }
+ }
+
+ fun write(state: AccessState) {
+ writeState(state.systemState, ::writeSystemState)
+ state.userStates.forEachIndexed { _, userId, userState ->
+ writeState(userState) { writeUserState(userId, it) }
+ }
+ }
+
+ private inline fun <T : WritableState> writeState(state: T, write: (T) -> Unit) {
+ when (val writeMode = state.writeMode) {
+ WriteMode.NONE -> {}
+ WriteMode.SYNC -> write(state)
+ WriteMode.ASYNC -> TODO()
+ else -> error(writeMode)
+ }
+ }
+
+ private fun writeSystemState(systemState: SystemState) {
+ systemFile.serialize {
+ with(policy) { this@serialize.serializeSystemState(systemState) }
+ }
+ }
+
+ private fun writeUserState(userId: Int, userState: UserState) {
+ getUserFile(userId).serialize {
+ with(policy) { this@serialize.serializeUserState(userId, userState) }
+ }
+ }
+
+ private inline fun File.serialize(block: BinaryXmlSerializer.() -> Unit) {
+ try {
+ AtomicFile(this).writeInlined { it.serializeBinaryXml(block) }
+ } catch (e: Exception) {
+ Log.e(LOG_TAG, "Failed to serialize $this", e)
+ }
+ }
+
+ private val systemFile: File
+ get() = File(PermissionApex.systemDataDirectory, FILE_NAME)
+
+ private fun getUserFile(userId: Int): File =
+ File(PermissionApex.getUserDataDirectory(userId), FILE_NAME)
+
+ companion object {
+ private val LOG_TAG = AccessPersistence::class.java.simpleName
+
+ private const val FILE_NAME = "access.abx"
+ }
+}
diff --git a/services/permission/java/com/android/server/permission/access/AccessPolicy.kt b/services/permission/java/com/android/server/permission/access/AccessPolicy.kt
new file mode 100644
index 000000000000..4e53ce06f3eb
--- /dev/null
+++ b/services/permission/java/com/android/server/permission/access/AccessPolicy.kt
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.permission.access
+
+import android.util.Log
+import com.android.modules.utils.BinaryXmlPullParser
+import com.android.modules.utils.BinaryXmlSerializer
+import com.android.server.permission.access.appop.PackageAppOpPolicy
+import com.android.server.permission.access.appop.UidAppOpPolicy
+import com.android.server.permission.access.collection.* // ktlint-disable no-wildcard-imports
+import com.android.server.permission.access.external.PackageState
+import com.android.server.permission.access.permission.UidPermissionPolicy
+import com.android.server.permission.access.util.forEachTag
+import com.android.server.permission.access.util.tag
+import com.android.server.permission.access.util.tagName
+
+class AccessPolicy private constructor(
+ private val schemePolicies: IndexedMap<String, IndexedMap<String, SchemePolicy>>
+) {
+ constructor() : this(
+ IndexedMap<String, IndexedMap<String, SchemePolicy>>().apply {
+ fun addPolicy(policy: SchemePolicy) =
+ getOrPut(policy.subjectScheme) { IndexedMap() }.put(policy.objectScheme, policy)
+ addPolicy(UidPermissionPolicy())
+ addPolicy(UidAppOpPolicy())
+ addPolicy(PackageAppOpPolicy())
+ }
+ )
+
+ fun getDecision(subject: AccessUri, `object`: AccessUri, state: AccessState): Int =
+ getSchemePolicy(subject, `object`).getDecision(subject, `object`, state)
+
+ fun setDecision(
+ subject: AccessUri,
+ `object`: AccessUri,
+ decision: Int,
+ oldState: AccessState,
+ newState: AccessState
+ ) {
+ getSchemePolicy(subject, `object`)
+ .setDecision(subject, `object`, decision, oldState, newState)
+ }
+
+ private fun getSchemePolicy(subject: AccessUri, `object`: AccessUri): SchemePolicy =
+ checkNotNull(schemePolicies[subject.scheme]?.get(`object`.scheme)) {
+ "Scheme policy for subject=$subject object=$`object` does not exist"
+ }
+
+ fun onUserAdded(userId: Int, oldState: AccessState, newState: AccessState) {
+ newState.systemState.userIds += userId
+ newState.userStates[userId] = UserState()
+ forEachSchemePolicy { it.onUserAdded(userId, oldState, newState) }
+ }
+
+ fun onUserRemoved(userId: Int, oldState: AccessState, newState: AccessState) {
+ newState.systemState.userIds -= userId
+ newState.userStates -= userId
+ forEachSchemePolicy { it.onUserRemoved(userId, oldState, newState) }
+ }
+
+ fun onPackageAdded(packageState: PackageState, oldState: AccessState, newState: AccessState) {
+ var isAppIdAdded = false
+ newState.systemState.apply {
+ packageStates[packageState.packageName] = packageState
+ appIds.getOrPut(packageState.appId) {
+ isAppIdAdded = true
+ IndexedListSet()
+ }.add(packageState.packageName)
+ }
+ if (isAppIdAdded) {
+ forEachSchemePolicy { it.onAppIdAdded(packageState.appId, oldState, newState) }
+ }
+ forEachSchemePolicy { it.onPackageAdded(packageState, oldState, newState) }
+ }
+
+ fun onPackageRemoved(packageState: PackageState, oldState: AccessState, newState: AccessState) {
+ var isAppIdRemoved = false
+ newState.systemState.apply {
+ packageStates -= packageState.packageName
+ appIds.apply appIds@{
+ this[packageState.appId]?.apply {
+ this -= packageState.packageName
+ if (isEmpty()) {
+ this@appIds -= packageState.appId
+ isAppIdRemoved = true
+ }
+ }
+ }
+ }
+ forEachSchemePolicy { it.onPackageRemoved(packageState, oldState, newState) }
+ if (isAppIdRemoved) {
+ forEachSchemePolicy { it.onAppIdRemoved(packageState.appId, oldState, newState) }
+ }
+ }
+
+ fun BinaryXmlPullParser.parseSystemState(systemState: SystemState) {
+ forEachTag {
+ when (tagName) {
+ TAG_ACCESS -> {
+ forEachTag {
+ forEachSchemePolicy {
+ with(it) { this@parseSystemState.parseSystemState(systemState) }
+ }
+ }
+ }
+ else -> Log.w(LOG_TAG, "Ignoring unknown tag $tagName when parsing system state")
+ }
+ }
+ }
+
+ fun BinaryXmlSerializer.serializeSystemState(systemState: SystemState) {
+ tag(TAG_ACCESS) {
+ forEachSchemePolicy {
+ with(it) { this@serializeSystemState.serializeSystemState(systemState) }
+ }
+ }
+ }
+
+ fun BinaryXmlPullParser.parseUserState(userId: Int, userState: UserState) {
+ forEachTag {
+ when (tagName) {
+ TAG_ACCESS -> {
+ forEachTag {
+ forEachSchemePolicy {
+ with(it) { this@parseUserState.parseUserState(userId, userState) }
+ }
+ }
+ }
+ else -> {
+ Log.w(
+ LOG_TAG,
+ "Ignoring unknown tag $tagName when parsing user state for user $userId"
+ )
+ }
+ }
+ }
+ }
+
+ fun BinaryXmlSerializer.serializeUserState(userId: Int, userState: UserState) {
+ tag(TAG_ACCESS) {
+ forEachSchemePolicy {
+ with(it) { this@serializeUserState.serializeUserState(userId, userState) }
+ }
+ }
+ }
+
+ private inline fun forEachSchemePolicy(action: (SchemePolicy) -> Unit) {
+ schemePolicies.forEachValueIndexed { _, objectSchemePolicies ->
+ objectSchemePolicies.forEachValueIndexed { _, schemePolicy ->
+ action(schemePolicy)
+ }
+ }
+ }
+
+ companion object {
+ private val LOG_TAG = AccessPolicy::class.java.simpleName
+
+ private const val TAG_ACCESS = "access"
+ }
+}
+
+abstract class SchemePolicy {
+ @Volatile
+ private var onDecisionChangedListeners = IndexedListSet<OnDecisionChangedListener>()
+ private val onDecisionChangedListenersLock = Any()
+
+ abstract val subjectScheme: String
+
+ abstract val objectScheme: String
+
+ abstract fun getDecision(subject: AccessUri, `object`: AccessUri, state: AccessState): Int
+
+ abstract fun setDecision(
+ subject: AccessUri,
+ `object`: AccessUri,
+ decision: Int,
+ oldState: AccessState,
+ newState: AccessState
+ )
+
+ fun addOnDecisionChangedListener(listener: OnDecisionChangedListener) {
+ synchronized(onDecisionChangedListenersLock) {
+ onDecisionChangedListeners = onDecisionChangedListeners + listener
+ }
+ }
+
+ fun removeOnDecisionChangedListener(listener: OnDecisionChangedListener) {
+ synchronized(onDecisionChangedListenersLock) {
+ onDecisionChangedListeners = onDecisionChangedListeners - listener
+ }
+ }
+
+ protected fun notifyOnDecisionChangedListeners(
+ subject: AccessUri,
+ `object`: AccessUri,
+ oldDecision: Int,
+ newDecision: Int
+ ) {
+ val listeners = onDecisionChangedListeners
+ listeners.forEachIndexed { _, it ->
+ it.onDecisionChanged(subject, `object`, oldDecision, newDecision)
+ }
+ }
+
+ open fun onUserAdded(userId: Int, oldState: AccessState, newState: AccessState) {}
+
+ open fun onUserRemoved(userId: Int, oldState: AccessState, newState: AccessState) {}
+
+ open fun onAppIdAdded(appId: Int, oldState: AccessState, newState: AccessState) {}
+
+ open fun onAppIdRemoved(appId: Int, oldState: AccessState, newState: AccessState) {}
+
+ open fun onPackageAdded(
+ packageState: PackageState,
+ oldState: AccessState,
+ newState: AccessState
+ ) {}
+
+ open fun onPackageRemoved(
+ packageState: PackageState,
+ oldState: AccessState,
+ newState: AccessState
+ ) {}
+
+ open fun BinaryXmlPullParser.parseSystemState(systemState: SystemState) {}
+
+ open fun BinaryXmlSerializer.serializeSystemState(systemState: SystemState) {}
+
+ open fun BinaryXmlPullParser.parseUserState(userId: Int, userState: UserState) {}
+
+ open fun BinaryXmlSerializer.serializeUserState(userId: Int, userState: UserState) {}
+
+ fun interface OnDecisionChangedListener {
+ fun onDecisionChanged(
+ subject: AccessUri,
+ `object`: AccessUri,
+ oldDecision: Int,
+ newDecision: Int
+ )
+ }
+}
diff --git a/services/permission/java/com/android/server/permission/access/AccessState.kt b/services/permission/java/com/android/server/permission/access/AccessState.kt
new file mode 100644
index 000000000000..f496dbd03130
--- /dev/null
+++ b/services/permission/java/com/android/server/permission/access/AccessState.kt
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.permission.access
+
+import android.content.pm.PermissionGroupInfo
+import com.android.server.permission.access.collection.* // ktlint-disable no-wildcard-imports
+import com.android.server.permission.access.data.Permission
+import com.android.server.permission.access.external.PackageState
+
+class AccessState private constructor(
+ val systemState: SystemState,
+ val userStates: IntMap<UserState>
+) {
+ constructor() : this(SystemState(), IntMap())
+
+ fun copy(): AccessState = AccessState(systemState.copy(), userStates.copy { it.copy() })
+}
+
+class SystemState private constructor(
+ val userIds: IntSet,
+ val packageStates: IndexedMap<String, PackageState>,
+ val disabledSystemPackageStates: IndexedMap<String, PackageState>,
+ val appIds: IntMap<IndexedListSet<String>>,
+ // A map of KnownPackagesInt to a set of known package names
+ val knownPackages: IntMap<IndexedListSet<String>>,
+ // A map of userId to packageName
+ val deviceAndProfileOwners: IntMap<String>,
+ // A map of packageName to (A map of oem permission name to whether it's granted)
+ val oemPermissions: IndexedMap<String, IndexedMap<String, Boolean>>,
+ val privilegedPermissionAllowlistSourcePackageNames: IndexedListSet<String>,
+ // A map of packageName to a set of vendor priv app permission names
+ val vendorPrivAppPermissions: Map<String, Set<String>>,
+ val productPrivAppPermissions: Map<String, Set<String>>,
+ val systemExtPrivAppPermissions: Map<String, Set<String>>,
+ val privAppPermissions: Map<String, Set<String>>,
+ val apexPrivAppPermissions: Map<String, Map<String, Set<String>>>,
+ val vendorPrivAppDenyPermissions: Map<String, Set<String>>,
+ val productPrivAppDenyPermissions: Map<String, Set<String>>,
+ val systemExtPrivAppDenyPermissions: Map<String, Set<String>>,
+ val apexPrivAppDenyPermissions: Map<String, Map<String, Set<String>>>,
+ val privAppDenyPermissions: Map<String, Set<String>>,
+ val implicitToSourcePermissions: Map<String, Set<String>>,
+ val permissionGroups: IndexedMap<String, PermissionGroupInfo>,
+ val permissionTrees: IndexedMap<String, Permission>,
+ val permissions: IndexedMap<String, Permission>
+) : WritableState() {
+ constructor() : this(
+ IntSet(), IndexedMap(), IndexedMap(), IntMap(), IntMap(), IntMap(), IndexedMap(),
+ IndexedListSet(), IndexedMap(), IndexedMap(), IndexedMap(), IndexedMap(), IndexedMap(),
+ IndexedMap(), IndexedMap(), IndexedMap(), IndexedMap(), IndexedMap(), IndexedMap(),
+ IndexedMap(), IndexedMap(), IndexedMap()
+ )
+
+ fun copy(): SystemState =
+ SystemState(
+ userIds.copy(),
+ packageStates.copy { it },
+ disabledSystemPackageStates.copy { it },
+ appIds.copy { it.copy() },
+ knownPackages.copy { it.copy() },
+ deviceAndProfileOwners.copy { it },
+ oemPermissions.copy { it.copy { it } },
+ privilegedPermissionAllowlistSourcePackageNames.copy(),
+ vendorPrivAppPermissions,
+ productPrivAppPermissions,
+ systemExtPrivAppPermissions,
+ privAppPermissions,
+ apexPrivAppPermissions,
+ vendorPrivAppDenyPermissions,
+ productPrivAppDenyPermissions,
+ systemExtPrivAppDenyPermissions,
+ apexPrivAppDenyPermissions,
+ privAppDenyPermissions,
+ implicitToSourcePermissions,
+ permissionGroups.copy { it },
+ permissionTrees.copy { it },
+ permissions.copy { it }
+ )
+}
+
+class UserState private constructor(
+ // A map of (appId to a map of (permissionName to permissionFlags))
+ val permissionFlags: IntMap<IndexedMap<String, Int>>,
+ val uidAppOpModes: IntMap<IndexedMap<String, Int>>,
+ val packageAppOpModes: IndexedMap<String, IndexedMap<String, Int>>
+) : WritableState() {
+ constructor() : this(IntMap(), IntMap(), IndexedMap())
+
+ fun copy(): UserState = UserState(permissionFlags.copy { it.copy { it } },
+ uidAppOpModes.copy { it.copy { it } }, packageAppOpModes.copy { it.copy { it } })
+}
+
+object WriteMode {
+ const val NONE = 0
+ const val SYNC = 1
+ const val ASYNC = 2
+}
+
+abstract class WritableState {
+ var writeMode: Int = WriteMode.NONE
+ private set
+
+ fun requestWrite(sync: Boolean = false) {
+ if (sync) {
+ writeMode = WriteMode.SYNC
+ } else {
+ if (writeMode != WriteMode.SYNC) {
+ writeMode = WriteMode.ASYNC
+ }
+ }
+ }
+}
diff --git a/services/permission/java/com/android/server/permission/access/AccessUri.kt b/services/permission/java/com/android/server/permission/access/AccessUri.kt
new file mode 100644
index 000000000000..7e98d2cb13e7
--- /dev/null
+++ b/services/permission/java/com/android/server/permission/access/AccessUri.kt
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.permission.access
+
+import com.android.server.permission.access.external.UserHandle
+import com.android.server.permission.access.external.UserHandleCompat
+
+sealed class AccessUri(
+ val scheme: String
+) {
+ override fun equals(other: Any?): Boolean {
+ throw NotImplementedError()
+ }
+
+ override fun hashCode(): Int {
+ throw NotImplementedError()
+ }
+
+ override fun toString(): String {
+ throw NotImplementedError()
+ }
+}
+
+data class AppOpUri(
+ val appOpName: String
+) : AccessUri(SCHEME) {
+ override fun toString(): String = "$scheme:///$appOpName"
+
+ companion object {
+ const val SCHEME = "app-op"
+ }
+}
+
+data class PackageUri(
+ val packageName: String,
+ val userId: Int
+) : AccessUri(SCHEME) {
+ override fun toString(): String = "$scheme:///$packageName/$userId"
+
+ companion object {
+ const val SCHEME = "package"
+ }
+}
+
+data class PermissionUri(
+ val permissionName: String
+) : AccessUri(SCHEME) {
+ override fun toString(): String = "$scheme:///$permissionName"
+
+ companion object {
+ const val SCHEME = "permission"
+ }
+}
+
+data class UidUri(
+ val uid: Int
+) : AccessUri(SCHEME) {
+ val userId: Int
+ get() = UserHandleCompat.getUserId(uid)
+
+ val appId: Int
+ get() = UserHandle.getAppId(uid)
+
+ override fun toString(): String = "$scheme:///$uid"
+
+ companion object {
+ const val SCHEME = "uid"
+ }
+}
diff --git a/services/permission/java/com/android/server/permission/access/appop/AppOpModes.kt b/services/permission/java/com/android/server/permission/access/appop/AppOpModes.kt
new file mode 100644
index 000000000000..d90846ffad47
--- /dev/null
+++ b/services/permission/java/com/android/server/permission/access/appop/AppOpModes.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.permission.access.appop
+
+import android.app.AppOpsManager
+
+object AppOpModes {
+ const val MODE_ALLOWED = AppOpsManager.MODE_ALLOWED
+ const val MODE_IGNORED = AppOpsManager.MODE_IGNORED
+ const val MODE_ERRORED = AppOpsManager.MODE_ERRORED
+ const val MODE_DEFAULT = AppOpsManager.MODE_DEFAULT
+ const val MODE_FOREGROUND = AppOpsManager.MODE_FOREGROUND
+}
diff --git a/services/permission/java/com/android/server/permission/access/appop/BaseAppOpPersistence.kt b/services/permission/java/com/android/server/permission/access/appop/BaseAppOpPersistence.kt
new file mode 100644
index 000000000000..031c9287a9a4
--- /dev/null
+++ b/services/permission/java/com/android/server/permission/access/appop/BaseAppOpPersistence.kt
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.permission.access.appop
+
+import android.util.Log
+import com.android.modules.utils.BinaryXmlPullParser
+import com.android.modules.utils.BinaryXmlSerializer
+import com.android.server.permission.access.UserState
+import com.android.server.permission.access.collection.* // ktlint-disable no-wildcard-imports
+import com.android.server.permission.access.util.attributeInt
+import com.android.server.permission.access.util.attributeInterned
+import com.android.server.permission.access.util.forEachTag
+import com.android.server.permission.access.util.getAttributeIntOrThrow
+import com.android.server.permission.access.util.getAttributeValueOrThrow
+import com.android.server.permission.access.util.tag
+import com.android.server.permission.access.util.tagName
+
+abstract class BaseAppOpPersistence {
+ abstract fun BinaryXmlPullParser.parseUserState(userId: Int, userState: UserState)
+
+ abstract fun BinaryXmlSerializer.serializeUserState(userId: Int, userState: UserState)
+
+ protected fun BinaryXmlPullParser.parseAppOps(appOpModes: IndexedMap<String, Int>) {
+ forEachTag {
+ when (tagName) {
+ TAG_APP_OP -> parseAppOp(appOpModes)
+ else -> Log.w(LOG_TAG, "Ignoring unknown tag $name when parsing app-op state")
+ }
+ }
+ }
+
+ private fun BinaryXmlPullParser.parseAppOp(appOpModes: IndexedMap<String, Int>) {
+ val name = getAttributeValueOrThrow(ATTR_NAME).intern()
+ val mode = getAttributeIntOrThrow(ATTR_MODE)
+ appOpModes[name] = mode
+ }
+
+ protected fun BinaryXmlSerializer.serializeAppOps(appOpModes: IndexedMap<String, Int>) {
+ appOpModes.forEachIndexed { _, name, mode ->
+ serializeAppOp(name, mode)
+ }
+ }
+
+ private fun BinaryXmlSerializer.serializeAppOp(name: String, mode: Int) {
+ tag(TAG_APP_OP) {
+ attributeInterned(ATTR_NAME, name)
+ attributeInt(ATTR_MODE, mode)
+ }
+ }
+
+ companion object {
+ private val LOG_TAG = BaseAppOpPersistence::class.java.simpleName
+
+ private const val TAG_APP_OP = "app-op"
+
+ private const val ATTR_NAME = "name"
+ private const val ATTR_MODE = "mode"
+ }
+}
diff --git a/services/permission/java/com/android/server/permission/access/appop/BaseAppOpPolicy.kt b/services/permission/java/com/android/server/permission/access/appop/BaseAppOpPolicy.kt
new file mode 100644
index 000000000000..0b052f918a20
--- /dev/null
+++ b/services/permission/java/com/android/server/permission/access/appop/BaseAppOpPolicy.kt
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.permission.access.appop
+
+import android.app.AppOpsManager
+import com.android.modules.utils.BinaryXmlPullParser
+import com.android.modules.utils.BinaryXmlSerializer
+import com.android.server.permission.access.AccessState
+import com.android.server.permission.access.AccessUri
+import com.android.server.permission.access.AppOpUri
+import com.android.server.permission.access.SchemePolicy
+import com.android.server.permission.access.UserState
+import com.android.server.permission.access.collection.* // ktlint-disable no-wildcard-imports
+
+abstract class BaseAppOpPolicy(private val persistence: BaseAppOpPersistence) : SchemePolicy() {
+ override fun getDecision(subject: AccessUri, `object`: AccessUri, state: AccessState): Int {
+ `object` as AppOpUri
+ return getModes(subject, state)
+ .getWithDefault(`object`.appOpName, opToDefaultMode(`object`.appOpName))
+ }
+
+ override fun setDecision(
+ subject: AccessUri,
+ `object`: AccessUri,
+ decision: Int,
+ oldState: AccessState,
+ newState: AccessState
+ ) {
+ `object` as AppOpUri
+ val modes = getOrCreateModes(subject, newState)
+ val oldMode = modes.putWithDefault(`object`.appOpName, decision,
+ opToDefaultMode(`object`.appOpName))
+ if (modes.isEmpty()) {
+ removeModes(subject, newState)
+ }
+ if (oldMode != decision) {
+ notifyOnDecisionChangedListeners(subject, `object`, oldMode, decision)
+ }
+ }
+
+ abstract fun getModes(subject: AccessUri, state: AccessState): IndexedMap<String, Int>?
+
+ abstract fun getOrCreateModes(subject: AccessUri, state: AccessState): IndexedMap<String, Int>
+
+ abstract fun removeModes(subject: AccessUri, state: AccessState)
+
+ // TODO need to check that [AppOpsManager.getSystemAlertWindowDefault] works; likely no issue
+ // since running in system process.
+ private fun opToDefaultMode(appOpName: String) = AppOpsManager.opToDefaultMode(appOpName)
+
+ override fun BinaryXmlPullParser.parseUserState(userId: Int, userState: UserState) {
+ with(persistence) { this@parseUserState.parseUserState(userId, userState) }
+ }
+
+ override fun BinaryXmlSerializer.serializeUserState(userId: Int, userState: UserState) {
+ with(persistence) { this@serializeUserState.serializeUserState(userId, userState) }
+ }
+}
diff --git a/services/permission/java/com/android/server/permission/access/appop/PackageAppOpPersistence.kt b/services/permission/java/com/android/server/permission/access/appop/PackageAppOpPersistence.kt
new file mode 100644
index 000000000000..183a352b9acd
--- /dev/null
+++ b/services/permission/java/com/android/server/permission/access/appop/PackageAppOpPersistence.kt
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.permission.access.appop
+
+import android.util.Log
+import com.android.modules.utils.BinaryXmlPullParser
+import com.android.modules.utils.BinaryXmlSerializer
+import com.android.server.permission.access.UserState
+import com.android.server.permission.access.collection.* // ktlint-disable no-wildcard-imports
+import com.android.server.permission.access.util.attributeInterned
+import com.android.server.permission.access.util.forEachTag
+import com.android.server.permission.access.util.getAttributeValueOrThrow
+import com.android.server.permission.access.util.tag
+import com.android.server.permission.access.util.tagName
+
+class PackageAppOpPersistence : BaseAppOpPersistence() {
+ override fun BinaryXmlPullParser.parseUserState(userId: Int, userState: UserState) {
+ when (tagName) {
+ TAG_PACKAGE_APP_OPS -> parsePackageAppOps(userState)
+ else -> {}
+ }
+ }
+
+ private fun BinaryXmlPullParser.parsePackageAppOps(userState: UserState) {
+ forEachTag {
+ when (tagName) {
+ TAG_PACKAGE -> parsePackage(userState)
+ else -> Log.w(LOG_TAG, "Ignoring unknown tag $name when parsing app-op state")
+ }
+ }
+ }
+
+ private fun BinaryXmlPullParser.parsePackage(userState: UserState) {
+ val packageName = getAttributeValueOrThrow(ATTR_NAME).intern()
+ val appOpModes = IndexedMap<String, Int>()
+ userState.packageAppOpModes[packageName] = appOpModes
+ parseAppOps(appOpModes)
+ }
+
+ override fun BinaryXmlSerializer.serializeUserState(userId: Int, userState: UserState) {
+ serializePackageAppOps(userState)
+ }
+
+ private fun BinaryXmlSerializer.serializePackageAppOps(userState: UserState) {
+ tag(TAG_PACKAGE_APP_OPS) {
+ userState.packageAppOpModes.forEachIndexed { _, packageName, appOpModes ->
+ serializePackage(packageName, appOpModes)
+ }
+ }
+ }
+
+ private fun BinaryXmlSerializer.serializePackage(
+ packageName: String,
+ appOpModes: IndexedMap<String, Int>
+ ) {
+ tag(TAG_PACKAGE) {
+ attributeInterned(ATTR_NAME, packageName)
+ serializeAppOps(appOpModes)
+ }
+ }
+
+ companion object {
+ private val LOG_TAG = PackageAppOpPersistence::class.java.simpleName
+
+ private const val TAG_PACKAGE_APP_OPS = "package-app-ops"
+ private const val TAG_PACKAGE = "package"
+
+ private const val ATTR_NAME = "name"
+ }
+}
diff --git a/services/permission/java/com/android/server/permission/access/appop/PackageAppOpPolicy.kt b/services/permission/java/com/android/server/permission/access/appop/PackageAppOpPolicy.kt
new file mode 100644
index 000000000000..7c3c14c1d753
--- /dev/null
+++ b/services/permission/java/com/android/server/permission/access/appop/PackageAppOpPolicy.kt
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.permission.access.appop
+
+import com.android.server.permission.access.AccessState
+import com.android.server.permission.access.AccessUri
+import com.android.server.permission.access.AppOpUri
+import com.android.server.permission.access.PackageUri
+import com.android.server.permission.access.UserState
+import com.android.server.permission.access.collection.* // ktlint-disable no-wildcard-imports
+import com.android.server.permission.access.external.PackageState
+
+class PackageAppOpPolicy : BaseAppOpPolicy(PackageAppOpPersistence()) {
+ override val subjectScheme: String
+ get() = PackageUri.SCHEME
+
+ override val objectScheme: String
+ get() = AppOpUri.SCHEME
+
+ override fun getModes(subject: AccessUri, state: AccessState): IndexedMap<String, Int>? {
+ subject as PackageUri
+ return state.userStates[subject.userId]?.packageAppOpModes?.get(subject.packageName)
+ }
+
+ override fun getOrCreateModes(subject: AccessUri, state: AccessState): IndexedMap<String, Int> {
+ subject as PackageUri
+ return state.userStates.getOrPut(subject.userId) { UserState() }
+ .packageAppOpModes.getOrPut(subject.packageName) { IndexedMap() }
+ }
+
+ override fun removeModes(subject: AccessUri, state: AccessState) {
+ subject as PackageUri
+ state.userStates[subject.userId]?.packageAppOpModes?.remove(subject.packageName)
+ }
+
+ override fun onPackageRemoved(
+ packageState: PackageState,
+ oldState: AccessState,
+ newState: AccessState
+ ) {
+ newState.userStates.forEachIndexed { _, _, userState ->
+ userState.packageAppOpModes -= packageState.packageName
+ }
+ }
+}
diff --git a/services/permission/java/com/android/server/permission/access/appop/UidAppOpPersistence.kt b/services/permission/java/com/android/server/permission/access/appop/UidAppOpPersistence.kt
new file mode 100644
index 000000000000..3c3a9d18926a
--- /dev/null
+++ b/services/permission/java/com/android/server/permission/access/appop/UidAppOpPersistence.kt
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.permission.access.appop
+
+import android.util.Log
+import com.android.modules.utils.BinaryXmlPullParser
+import com.android.modules.utils.BinaryXmlSerializer
+import com.android.server.permission.access.UserState
+import com.android.server.permission.access.collection.* // ktlint-disable no-wildcard-imports
+import com.android.server.permission.access.util.attributeInt
+import com.android.server.permission.access.util.forEachTag
+import com.android.server.permission.access.util.getAttributeIntOrThrow
+import com.android.server.permission.access.util.tag
+import com.android.server.permission.access.util.tagName
+
+class UidAppOpPersistence : BaseAppOpPersistence() {
+ override fun BinaryXmlPullParser.parseUserState(userId: Int, userState: UserState) {
+ when (tagName) {
+ TAG_UID_APP_OPS -> parseUidAppOps(userState)
+ else -> {}
+ }
+ }
+
+ private fun BinaryXmlPullParser.parseUidAppOps(userState: UserState) {
+ forEachTag {
+ when (tagName) {
+ TAG_UID -> parseUid(userState)
+ else -> Log.w(LOG_TAG, "Ignoring unknown tag $name when parsing app-op state")
+ }
+ }
+ }
+
+ private fun BinaryXmlPullParser.parseUid(userState: UserState) {
+ val uid = getAttributeIntOrThrow(ATTR_UID)
+ val appOpModes = IndexedMap<String, Int>()
+ userState.uidAppOpModes[uid] = appOpModes
+ parseAppOps(appOpModes)
+ }
+
+ override fun BinaryXmlSerializer.serializeUserState(userId: Int, userState: UserState) {
+ serializeUidAppOps(userState)
+ }
+
+ private fun BinaryXmlSerializer.serializeUidAppOps(userState: UserState) {
+ tag(TAG_UID_APP_OPS) {
+ userState.uidAppOpModes.forEachIndexed { _, uid, appOpModes ->
+ serializeUid(uid, appOpModes)
+ }
+ }
+ }
+
+ private fun BinaryXmlSerializer.serializeUid(uid: Int, appOpModes: IndexedMap<String, Int>) {
+ tag(TAG_UID) {
+ attributeInt(ATTR_UID, uid)
+ serializeAppOps(appOpModes)
+ }
+ }
+
+ companion object {
+ private val LOG_TAG = UidAppOpPersistence::class.java.simpleName
+
+ private const val TAG_UID_APP_OPS = "uid-app-ops"
+ private const val TAG_UID = "uid"
+
+ private const val ATTR_UID = "uid"
+ }
+}
diff --git a/services/permission/java/com/android/server/permission/access/appop/UidAppOpPolicy.kt b/services/permission/java/com/android/server/permission/access/appop/UidAppOpPolicy.kt
new file mode 100644
index 000000000000..26d01144609a
--- /dev/null
+++ b/services/permission/java/com/android/server/permission/access/appop/UidAppOpPolicy.kt
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.permission.access.appop
+
+import com.android.server.permission.access.AccessState
+import com.android.server.permission.access.AccessUri
+import com.android.server.permission.access.AppOpUri
+import com.android.server.permission.access.UidUri
+import com.android.server.permission.access.UserState
+import com.android.server.permission.access.collection.* // ktlint-disable no-wildcard-imports
+
+class UidAppOpPolicy : BaseAppOpPolicy(UidAppOpPersistence()) {
+ override val subjectScheme: String
+ get() = UidUri.SCHEME
+
+ override val objectScheme: String
+ get() = AppOpUri.SCHEME
+
+ override fun getModes(subject: AccessUri, state: AccessState): IndexedMap<String, Int>? {
+ subject as UidUri
+ return state.userStates[subject.userId]?.uidAppOpModes?.get(subject.appId)
+ }
+
+ override fun getOrCreateModes(subject: AccessUri, state: AccessState): IndexedMap<String, Int> {
+ subject as UidUri
+ return state.userStates.getOrPut(subject.userId) { UserState() }
+ .uidAppOpModes.getOrPut(subject.appId) { IndexedMap() }
+ }
+
+ override fun removeModes(subject: AccessUri, state: AccessState) {
+ subject as UidUri
+ state.userStates[subject.userId]?.uidAppOpModes?.remove(subject.appId)
+ }
+
+ override fun onAppIdRemoved(appId: Int, oldState: AccessState, newState: AccessState) {
+ newState.userStates.forEachIndexed { _, _, userState ->
+ userState.uidAppOpModes -= appId
+ }
+ }
+}
diff --git a/services/permission/java/com/android/server/permission/access/collection/IndexedList.kt b/services/permission/java/com/android/server/permission/access/collection/IndexedList.kt
new file mode 100644
index 000000000000..5ba435c79e2f
--- /dev/null
+++ b/services/permission/java/com/android/server/permission/access/collection/IndexedList.kt
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.permission.access.collection
+
+typealias IndexedList<T> = ArrayList<T>
+
+inline fun <T> IndexedList<T>.allIndexed(predicate: (Int, T) -> Boolean): Boolean {
+ for (index in 0 until size) {
+ if (!predicate(index, this[index])) {
+ return false
+ }
+ }
+ return true
+}
+
+inline fun <T> IndexedList<T>.anyIndexed(predicate: (Int, T) -> Boolean): Boolean {
+ for (index in 0 until size) {
+ if (predicate(index, this[index])) {
+ return true
+ }
+ }
+ return false
+}
+
+@Suppress("NOTHING_TO_INLINE")
+inline fun <T> IndexedList<T>.copy(): IndexedList<T> = IndexedList(this)
+
+inline fun <T> IndexedList<T>.forEachIndexed(action: (Int, T) -> Unit) {
+ for (index in indices) {
+ action(index, this[index])
+ }
+}
+
+@Suppress("NOTHING_TO_INLINE")
+inline operator fun <T> IndexedList<T>.minus(element: T): IndexedList<T> =
+ copy().apply { this -= element }
+
+@Suppress("NOTHING_TO_INLINE")
+inline operator fun <T> IndexedList<T>.minusAssign(element: T) {
+ remove(element)
+}
+
+inline fun <T> IndexedList<T>.noneIndexed(predicate: (Int, T) -> Boolean): Boolean {
+ for (index in 0 until size) {
+ if (predicate(index, this[index])) {
+ return false
+ }
+ }
+ return true
+}
+
+@Suppress("NOTHING_TO_INLINE")
+inline operator fun <T> IndexedList<T>.plus(element: T): IndexedList<T> =
+ copy().apply { this += element }
+
+@Suppress("NOTHING_TO_INLINE")
+inline operator fun <T> IndexedList<T>.plusAssign(element: T) {
+ add(element)
+}
+
+inline fun <T> IndexedList<T>.removeAllIndexed(predicate: (Int, T) -> Boolean) {
+ for (index in lastIndex downTo 0) {
+ if (predicate(index, this[index])) {
+ removeAt(index)
+ }
+ }
+}
+
+inline fun <T> IndexedList<T>.retainAllIndexed(predicate: (Int, T) -> Boolean) {
+ for (index in lastIndex downTo 0) {
+ if (!predicate(index, this[index])) {
+ removeAt(index)
+ }
+ }
+}
diff --git a/services/permission/java/com/android/server/permission/access/collection/IndexedListSet.kt b/services/permission/java/com/android/server/permission/access/collection/IndexedListSet.kt
new file mode 100644
index 000000000000..ac552fff6cdb
--- /dev/null
+++ b/services/permission/java/com/android/server/permission/access/collection/IndexedListSet.kt
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.permission.access.collection
+
+class IndexedListSet<T> private constructor(
+ private val list: ArrayList<T>
+) : MutableSet<T> {
+ constructor() : this(ArrayList())
+
+ override val size: Int
+ get() = list.size
+
+ override fun contains(element: T): Boolean = list.contains(element)
+
+ override fun isEmpty(): Boolean = list.isEmpty()
+
+ override fun iterator(): MutableIterator<T> = list.iterator()
+
+ override fun containsAll(elements: Collection<T>): Boolean {
+ throw NotImplementedError()
+ }
+
+ fun elementAt(index: Int): T = list[index]
+
+ fun indexOf(element: T): Int = list.indexOf(element)
+
+ override fun add(element: T): Boolean =
+ if (list.contains(element)) {
+ false
+ } else {
+ list.add(element)
+ true
+ }
+
+ override fun remove(element: T): Boolean = list.remove(element)
+
+ override fun clear() {
+ list.clear()
+ }
+
+ override fun addAll(elements: Collection<T>): Boolean {
+ throw NotImplementedError()
+ }
+
+ override fun removeAll(elements: Collection<T>): Boolean {
+ throw NotImplementedError()
+ }
+
+ override fun retainAll(elements: Collection<T>): Boolean {
+ throw NotImplementedError()
+ }
+
+ fun removeAt(index: Int): T? = list.removeAt(index)
+
+ fun copy(): IndexedListSet<T> = IndexedListSet(ArrayList(list))
+}
+
+inline fun <T> IndexedListSet<T>.allIndexed(predicate: (Int, T) -> Boolean): Boolean {
+ for (index in 0 until size) {
+ if (!predicate(index, elementAt(index))) {
+ return false
+ }
+ }
+ return true
+}
+
+inline fun <T> IndexedListSet<T>.anyIndexed(predicate: (Int, T) -> Boolean): Boolean {
+ for (index in 0 until size) {
+ if (predicate(index, elementAt(index))) {
+ return true
+ }
+ }
+ return false
+}
+
+inline fun <T> IndexedListSet<T>.forEachIndexed(action: (Int, T) -> Unit) {
+ for (index in indices) {
+ action(index, elementAt(index))
+ }
+}
+
+inline val <T> IndexedListSet<T>.lastIndex: Int
+ get() = size - 1
+
+@Suppress("NOTHING_TO_INLINE")
+inline operator fun <T> IndexedListSet<T>.minus(element: T): IndexedListSet<T> =
+ copy().apply { this -= element }
+
+@Suppress("NOTHING_TO_INLINE")
+inline operator fun <T> IndexedListSet<T>.minusAssign(element: T) {
+ remove(element)
+}
+
+inline fun <T> IndexedListSet<T>.noneIndexed(predicate: (Int, T) -> Boolean): Boolean {
+ for (index in 0 until size) {
+ if (predicate(index, elementAt(index))) {
+ return false
+ }
+ }
+ return true
+}
+
+@Suppress("NOTHING_TO_INLINE")
+inline operator fun <T> IndexedListSet<T>.plus(element: T): IndexedListSet<T> =
+ copy().apply { this += element }
+
+@Suppress("NOTHING_TO_INLINE")
+inline operator fun <T> IndexedListSet<T>.plusAssign(element: T) {
+ add(element)
+}
+
+inline fun <T> IndexedListSet<T>.removeAllIndexed(predicate: (Int, T) -> Boolean) {
+ for (index in lastIndex downTo 0) {
+ if (predicate(index, elementAt(index))) {
+ removeAt(index)
+ }
+ }
+}
+
+inline fun <T> IndexedListSet<T>.retainAllIndexed(predicate: (Int, T) -> Boolean) {
+ for (index in lastIndex downTo 0) {
+ if (!predicate(index, elementAt(index))) {
+ removeAt(index)
+ }
+ }
+}
diff --git a/services/permission/java/com/android/server/permission/access/collection/IndexedMap.kt b/services/permission/java/com/android/server/permission/access/collection/IndexedMap.kt
new file mode 100644
index 000000000000..1251666089f5
--- /dev/null
+++ b/services/permission/java/com/android/server/permission/access/collection/IndexedMap.kt
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.permission.access.collection
+
+import android.util.ArrayMap
+
+typealias IndexedMap<K, V> = ArrayMap<K, V>
+
+inline fun <K, V> IndexedMap<K, V>.allIndexed(predicate: (Int, K, V) -> Boolean): Boolean {
+ for (index in 0 until size) {
+ if (!predicate(index, keyAt(index), valueAt(index))) {
+ return false
+ }
+ }
+ return true
+}
+
+inline fun <K, V> IndexedMap<K, V>.anyIndexed(predicate: (Int, K, V) -> Boolean): Boolean {
+ for (index in 0 until size) {
+ if (predicate(index, keyAt(index), valueAt(index))) {
+ return true
+ }
+ }
+ return false
+}
+
+inline fun <K, V> IndexedMap<K, V>.copy(copyValue: (V) -> V): IndexedMap<K, V> =
+ IndexedMap(this).apply {
+ forEachValueIndexed { index, value ->
+ setValueAt(index, copyValue(value))
+ }
+ }
+
+inline fun <K, V, R> IndexedMap<K, V>.firstNotNullOfOrNullIndexed(transform: (Int, K, V) -> R): R? {
+ for (index in 0 until size) {
+ transform(index, keyAt(index), valueAt(index))?.let { return it }
+ }
+ return null
+}
+
+inline fun <K, V> IndexedMap<K, V>.forEachIndexed(action: (Int, K, V) -> Unit) {
+ for (index in 0 until size) {
+ action(index, keyAt(index), valueAt(index))
+ }
+}
+
+inline fun <K, V> IndexedMap<K, V>.forEachKeyIndexed(action: (Int, K) -> Unit) {
+ for (index in 0 until size) {
+ action(index, keyAt(index))
+ }
+}
+
+inline fun <K, V> IndexedMap<K, V>.forEachValueIndexed(action: (Int, V) -> Unit) {
+ for (index in 0 until size) {
+ action(index, valueAt(index))
+ }
+}
+
+inline fun <K, V> IndexedMap<K, V>.getOrPut(key: K, defaultValue: () -> V): V {
+ get(key)?.let { return it }
+ return defaultValue().also { put(key, it) }
+}
+
+@Suppress("NOTHING_TO_INLINE")
+inline fun <K, V> IndexedMap<K, V>?.getWithDefault(key: K, defaultValue: V): V {
+ this ?: return defaultValue
+ val index = indexOfKey(key)
+ return if (index >= 0) valueAt(index) else defaultValue
+}
+
+inline val <K, V> IndexedMap<K, V>.lastIndex: Int
+ get() = size - 1
+
+@Suppress("NOTHING_TO_INLINE")
+inline operator fun <K, V> IndexedMap<K, V>.minusAssign(key: K) {
+ remove(key)
+}
+
+@Suppress("NOTHING_TO_INLINE")
+inline fun <K, V> IndexedMap<K, V>.putWithDefault(key: K, value: V, defaultValue: V): V {
+ val index = indexOfKey(key)
+ if (index >= 0) {
+ val oldValue = valueAt(index)
+ if (value != oldValue) {
+ if (value == defaultValue) {
+ removeAt(index)
+ } else {
+ setValueAt(index, value)
+ }
+ }
+ return oldValue
+ } else {
+ if (value != defaultValue) {
+ put(key, value)
+ }
+ return defaultValue
+ }
+}
+
+inline fun <K, V> IndexedMap<K, V>.removeAllIndexed(predicate: (Int, K, V) -> Boolean) {
+ for (index in lastIndex downTo 0) {
+ if (predicate(index, keyAt(index), valueAt(index))) {
+ removeAt(index)
+ }
+ }
+}
+
+inline fun <K, V> IndexedMap<K, V>.retainAllIndexed(predicate: (Int, K, V) -> Boolean) {
+ for (index in lastIndex downTo 0) {
+ if (!predicate(index, keyAt(index), valueAt(index))) {
+ removeAt(index)
+ }
+ }
+}
+
+@Suppress("NOTHING_TO_INLINE")
+inline operator fun <K, V> IndexedMap<K, V>.set(key: K, value: V) {
+ put(key, value)
+}
diff --git a/services/permission/java/com/android/server/permission/access/collection/IndexedSet.kt b/services/permission/java/com/android/server/permission/access/collection/IndexedSet.kt
new file mode 100644
index 000000000000..36d8ff0c0087
--- /dev/null
+++ b/services/permission/java/com/android/server/permission/access/collection/IndexedSet.kt
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.permission.access.collection
+
+import android.util.ArraySet
+
+typealias IndexedSet<T> = ArraySet<T>
+
+inline fun <T> IndexedSet<T>.allIndexed(predicate: (Int, T) -> Boolean): Boolean {
+ for (index in 0 until size) {
+ if (!predicate(index, elementAt(index))) {
+ return false
+ }
+ }
+ return true
+}
+
+inline fun <T> IndexedSet<T>.anyIndexed(predicate: (Int, T) -> Boolean): Boolean {
+ for (index in 0 until size) {
+ if (predicate(index, elementAt(index))) {
+ return true
+ }
+ }
+ return false
+}
+
+@Suppress("NOTHING_TO_INLINE")
+inline fun <T> IndexedSet<T>.copy(): IndexedSet<T> = IndexedSet(this)
+
+@Suppress("NOTHING_TO_INLINE")
+inline fun <T> IndexedSet<T>.elementAt(index: Int): T = valueAt(index)
+
+inline fun <T> IndexedSet<T>.forEachIndexed(action: (Int, T) -> Unit) {
+ for (index in indices) {
+ action(index, elementAt(index))
+ }
+}
+
+inline val <T> IndexedSet<T>.lastIndex: Int
+ get() = size - 1
+
+@Suppress("NOTHING_TO_INLINE")
+inline operator fun <T> IndexedSet<T>.minus(element: T): IndexedSet<T> =
+ copy().apply { this -= element }
+
+@Suppress("NOTHING_TO_INLINE")
+inline operator fun <T> IndexedSet<T>.minusAssign(element: T) {
+ remove(element)
+}
+
+inline fun <T> IndexedSet<T>.noneIndexed(predicate: (Int, T) -> Boolean): Boolean {
+ for (index in 0 until size) {
+ if (predicate(index, elementAt(index))) {
+ return false
+ }
+ }
+ return true
+}
+
+@Suppress("NOTHING_TO_INLINE")
+inline operator fun <T> IndexedSet<T>.plus(element: T): IndexedSet<T> =
+ copy().apply { this += element }
+
+@Suppress("NOTHING_TO_INLINE")
+inline operator fun <T> IndexedSet<T>.plusAssign(element: T) {
+ add(element)
+}
+
+inline fun <T> IndexedSet<T>.removeAllIndexed(predicate: (Int, T) -> Boolean) {
+ for (index in lastIndex downTo 0) {
+ if (predicate(index, elementAt(index))) {
+ removeAt(index)
+ }
+ }
+}
+
+inline fun <T> IndexedSet<T>.retainAllIndexed(predicate: (Int, T) -> Boolean) {
+ for (index in lastIndex downTo 0) {
+ if (!predicate(index, elementAt(index))) {
+ removeAt(index)
+ }
+ }
+}
+
+@Suppress("NOTHING_TO_INLINE")
+inline fun <T> indexedSetOf(vararg elements: T): IndexedSet<T> = IndexedSet(elements.asList())
diff --git a/services/permission/java/com/android/server/permission/access/collection/IntMap.kt b/services/permission/java/com/android/server/permission/access/collection/IntMap.kt
new file mode 100644
index 000000000000..9051c66120d8
--- /dev/null
+++ b/services/permission/java/com/android/server/permission/access/collection/IntMap.kt
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.permission.access.collection
+
+import android.util.SparseArray
+
+typealias IntMap<T> = SparseArray<T>
+
+inline fun <T> IntMap<T>.allIndexed(predicate: (Int, Int, T) -> Boolean): Boolean {
+ for (index in 0 until size) {
+ if (!predicate(index, keyAt(index), valueAt(index))) {
+ return false
+ }
+ }
+ return true
+}
+
+inline fun <T> IntMap<T>.anyIndexed(predicate: (Int, Int, T) -> Boolean): Boolean {
+ for (index in 0 until size) {
+ if (predicate(index, keyAt(index), valueAt(index))) {
+ return true
+ }
+ }
+ return false
+}
+
+inline fun <T> IntMap<T>.copy(copyValue: (T) -> T): IntMap<T> =
+ this.clone().apply {
+ forEachValueIndexed { index, value ->
+ setValueAt(index, copyValue(value))
+ }
+ }
+
+inline fun <T, R> IntMap<T>.firstNotNullOfOrNullIndexed(transform: (Int, Int, T) -> R): R? {
+ for (index in 0 until size) {
+ transform(index, keyAt(index), valueAt(index))?.let { return it }
+ }
+ return null
+}
+
+inline fun <T> IntMap<T>.forEachIndexed(action: (Int, Int, T) -> Unit) {
+ for (index in 0 until size) {
+ action(index, keyAt(index), valueAt(index))
+ }
+}
+
+inline fun <T> IntMap<T>.forEachKeyIndexed(action: (Int, Int) -> Unit) {
+ for (index in 0 until size) {
+ action(index, keyAt(index))
+ }
+}
+
+inline fun <T> IntMap<T>.forEachValueIndexed(action: (Int, T) -> Unit) {
+ for (index in 0 until size) {
+ action(index, valueAt(index))
+ }
+}
+
+inline fun <T> IntMap<T>.getOrPut(key: Int, defaultValue: () -> T): T {
+ get(key)?.let { return it }
+ return defaultValue().also { put(key, it) }
+}
+
+@Suppress("NOTHING_TO_INLINE")
+inline fun <T> IntMap<T>?.getWithDefault(key: Int, defaultValue: T): T {
+ this ?: return defaultValue
+ val index = indexOfKey(key)
+ return if (index >= 0) valueAt(index) else defaultValue
+}
+
+inline val <T> IntMap<T>.lastIndex: Int
+ get() = size - 1
+
+@Suppress("NOTHING_TO_INLINE")
+inline operator fun <T> IntMap<T>.minusAssign(key: Int) {
+ remove(key)
+}
+
+inline fun <T> IntMap<T>.noneIndexed(predicate: (Int, Int, T) -> Boolean): Boolean {
+ for (index in 0 until size) {
+ if (predicate(index, keyAt(index), valueAt(index))) {
+ return false
+ }
+ }
+ return true
+}
+
+@Suppress("NOTHING_TO_INLINE")
+inline fun <T> IntMap<T>.putWithDefault(key: Int, value: T, defaultValue: T): T {
+ val index = indexOfKey(key)
+ if (index >= 0) {
+ val oldValue = valueAt(index)
+ if (value != oldValue) {
+ if (value == defaultValue) {
+ removeAt(index)
+ } else {
+ setValueAt(index, value)
+ }
+ }
+ return oldValue
+ } else {
+ if (value != defaultValue) {
+ put(key, value)
+ }
+ return defaultValue
+ }
+}
+
+inline fun <T> IntMap<T>.removeAllIndexed(predicate: (Int, Int, T) -> Boolean) {
+ for (index in lastIndex downTo 0) {
+ if (predicate(index, keyAt(index), valueAt(index))) {
+ removeAt(index)
+ }
+ }
+}
+
+inline fun <T> IntMap<T>.retainAllIndexed(predicate: (Int, Int, T) -> Boolean) {
+ for (index in lastIndex downTo 0) {
+ if (!predicate(index, keyAt(index), valueAt(index))) {
+ removeAt(index)
+ }
+ }
+}
+
+inline val <T> IntMap<T>.size: Int
+ get() = size()
diff --git a/services/permission/java/com/android/server/permission/access/collection/IntSet.kt b/services/permission/java/com/android/server/permission/access/collection/IntSet.kt
new file mode 100644
index 000000000000..d6dfe9d0eb37
--- /dev/null
+++ b/services/permission/java/com/android/server/permission/access/collection/IntSet.kt
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.permission.access.collection
+
+import android.util.SparseBooleanArray
+
+class IntSet private constructor(
+ private val array: SparseBooleanArray
+) {
+ constructor() : this(SparseBooleanArray())
+
+ val size: Int
+ get() = array.size()
+
+ operator fun contains(element: Int): Boolean = array[element]
+
+ fun elementAt(index: Int): Int = array.keyAt(index)
+
+ fun indexOf(element: Int): Int = array.indexOfKey(element)
+
+ fun add(element: Int) {
+ array.put(element, true)
+ }
+
+ fun remove(element: Int) {
+ array.delete(element)
+ }
+
+ fun clear() {
+ array.clear()
+ }
+
+ fun removeAt(index: Int) {
+ array.removeAt(index)
+ }
+
+ fun copy(): IntSet = IntSet(array.clone())
+}
+
+inline fun IntSet.allIndexed(predicate: (Int, Int) -> Boolean): Boolean {
+ for (index in 0 until size) {
+ if (!predicate(index, elementAt(index))) {
+ return false
+ }
+ }
+ return true
+}
+
+inline fun IntSet.anyIndexed(predicate: (Int, Int) -> Boolean): Boolean {
+ for (index in 0 until size) {
+ if (predicate(index, elementAt(index))) {
+ return true
+ }
+ }
+ return false
+}
+
+inline fun IntSet.forEachIndexed(action: (Int, Int) -> Unit) {
+ for (index in 0 until size) {
+ action(index, elementAt(index))
+ }
+}
+
+inline val IntSet.lastIndex: Int
+ get() = size - 1
+
+@Suppress("NOTHING_TO_INLINE")
+inline operator fun IntSet.minus(element: Int): IntSet = copy().apply { this -= element }
+
+@Suppress("NOTHING_TO_INLINE")
+inline operator fun IntSet.minusAssign(element: Int) {
+ remove(element)
+}
+
+inline fun IntSet.noneIndexed(predicate: (Int, Int) -> Boolean): Boolean {
+ for (index in 0 until size) {
+ if (predicate(index, elementAt(index))) {
+ return false
+ }
+ }
+ return true
+}
+
+@Suppress("NOTHING_TO_INLINE")
+inline operator fun IntSet.plus(element: Int): IntSet = copy().apply { this += element }
+
+@Suppress("NOTHING_TO_INLINE")
+inline operator fun IntSet.plusAssign(element: Int) {
+ add(element)
+}
+
+inline fun IntSet.removeAllIndexed(predicate: (Int, Int) -> Boolean) {
+ for (index in lastIndex downTo 0) {
+ if (predicate(index, elementAt(index))) {
+ removeAt(index)
+ }
+ }
+}
+
+inline fun IntSet.retainAllIndexed(predicate: (Int, Int) -> Boolean) {
+ for (index in lastIndex downTo 0) {
+ if (!predicate(index, elementAt(index))) {
+ removeAt(index)
+ }
+ }
+}
diff --git a/services/permission/java/com/android/server/permission/access/collection/List.kt b/services/permission/java/com/android/server/permission/access/collection/List.kt
new file mode 100644
index 000000000000..dc28642bc2c6
--- /dev/null
+++ b/services/permission/java/com/android/server/permission/access/collection/List.kt
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.permission.access.collection
+
+inline fun <T> List<T>.allIndexed(predicate: (Int, T) -> Boolean): Boolean {
+ for (index in 0 until size) {
+ if (!predicate(index, this[index])) {
+ return false
+ }
+ }
+ return true
+}
+
+inline fun <T> List<T>.anyIndexed(predicate: (Int, T) -> Boolean): Boolean {
+ for (index in 0 until size) {
+ if (predicate(index, this[index])) {
+ return true
+ }
+ }
+ return false
+}
+
+inline fun <T> List<T>.forEachIndexed(action: (Int, T) -> Unit) {
+ for (index in indices) {
+ action(index, this[index])
+ }
+}
+
+inline fun <T> List<T>.noneIndexed(predicate: (Int, T) -> Boolean): Boolean {
+ for (index in 0 until size) {
+ if (predicate(index, this[index])) {
+ return false
+ }
+ }
+ return true
+}
+
+inline fun <T> MutableList<T>.removeAllIndexed(predicate: (Int, T) -> Boolean) {
+ for (index in lastIndex downTo 0) {
+ if (predicate(index, this[index])) {
+ removeAt(index)
+ }
+ }
+}
+
+inline fun <T> MutableList<T>.retainAllIndexed(predicate: (Int, T) -> Boolean) {
+ for (index in lastIndex downTo 0) {
+ if (!predicate(index, this[index])) {
+ removeAt(index)
+ }
+ }
+}
diff --git a/services/permission/java/com/android/server/permission/access/data/Package.kt b/services/permission/java/com/android/server/permission/access/data/Package.kt
new file mode 100644
index 000000000000..d6f98ab256cf
--- /dev/null
+++ b/services/permission/java/com/android/server/permission/access/data/Package.kt
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.permission.access.data
+
+import com.android.server.permission.access.external.AndroidPackage
+
+class Package(
+ private val androidPackage: AndroidPackage
+) {
+ val name: String
+ get() = androidPackage.packageName
+
+ val adoptPermissions: List<String>
+ get() = androidPackage.adoptPermissions
+
+ val appId: Int
+ get() = androidPackage.appId
+
+ val requestedPermissions: List<String>
+ get() = androidPackage.requestedPermissions
+
+ override fun equals(other: Any?): Boolean {
+ throw NotImplementedError()
+ }
+
+ override fun hashCode(): Int {
+ throw NotImplementedError()
+ }
+}
diff --git a/services/permission/java/com/android/server/permission/access/data/Permission.kt b/services/permission/java/com/android/server/permission/access/data/Permission.kt
new file mode 100644
index 000000000000..877f23b0e825
--- /dev/null
+++ b/services/permission/java/com/android/server/permission/access/data/Permission.kt
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.permission.access.data
+
+import android.content.pm.PermissionInfo
+import com.android.server.permission.access.util.hasBits
+
+data class Permission(
+ val permissionInfo: PermissionInfo,
+ val isReconciled: Boolean,
+ val type: Int,
+ val appId: Int
+) {
+ inline val name: String
+ get() = permissionInfo.name
+
+ inline val packageName: String
+ get() = permissionInfo.packageName
+
+ inline val isDynamic: Boolean
+ get() = type == TYPE_DYNAMIC
+
+ inline val isNormal: Boolean
+ get() = permissionInfo.protection == PermissionInfo.PROTECTION_NORMAL
+
+ inline val isRuntime: Boolean
+ get() = permissionInfo.protection == PermissionInfo.PROTECTION_DANGEROUS
+
+ inline val isSoftRestricted: Boolean
+ get() = permissionInfo.protectionFlags.hasBits(PermissionInfo.FLAG_SOFT_RESTRICTED)
+
+ inline val isHardRestricted: Boolean
+ get() = permissionInfo.protectionFlags.hasBits(PermissionInfo.FLAG_HARD_RESTRICTED)
+
+ inline val isSignature: Boolean
+ get() = permissionInfo.protection == PermissionInfo.PROTECTION_SIGNATURE
+
+ inline val isInternal: Boolean
+ get() = permissionInfo.protection == PermissionInfo.PROTECTION_INTERNAL
+
+ inline val isDevelopment: Boolean
+ get() = permissionInfo.protectionFlags.hasBits(PermissionInfo.PROTECTION_FLAG_DEVELOPMENT)
+
+ inline val isInstaller: Boolean
+ get() = permissionInfo.protectionFlags.hasBits(PermissionInfo.PROTECTION_FLAG_INSTALLER)
+
+ inline val isOem: Boolean
+ get() = permissionInfo.protectionFlags.hasBits(PermissionInfo.PROTECTION_FLAG_OEM)
+
+ inline val isPre23: Boolean
+ get() = permissionInfo.protectionFlags.hasBits(PermissionInfo.PROTECTION_FLAG_PRE23)
+
+ inline val isPreInstalled: Boolean
+ get() = permissionInfo.protectionFlags.hasBits(PermissionInfo.PROTECTION_FLAG_PREINSTALLED)
+
+ inline val isPrivileged: Boolean
+ get() = permissionInfo.protectionFlags.hasBits(PermissionInfo.PROTECTION_FLAG_PRIVILEGED)
+
+ inline val isSetup: Boolean
+ get() = permissionInfo.protectionFlags.hasBits(PermissionInfo.PROTECTION_FLAG_SETUP)
+
+ inline val isVerifier: Boolean
+ get() = permissionInfo.protectionFlags.hasBits(PermissionInfo.PROTECTION_FLAG_VERIFIER)
+
+ inline val isVendorPrivileged: Boolean
+ get() = permissionInfo.protectionFlags
+ .hasBits(PROTECTION_FLAG_VENDOR_PRIVILEGED)
+
+ inline val isSystemTextClassifier: Boolean
+ get() = permissionInfo.protectionFlags
+ .hasBits(PermissionInfo.PROTECTION_FLAG_SYSTEM_TEXT_CLASSIFIER)
+
+ inline val isConfigurator: Boolean
+ get() = permissionInfo.protectionFlags.hasBits(PermissionInfo.PROTECTION_FLAG_CONFIGURATOR)
+
+ inline val isIncidentReportApprover: Boolean
+ get() = permissionInfo.protectionFlags
+ .hasBits(PermissionInfo.PROTECTION_FLAG_INCIDENT_REPORT_APPROVER)
+
+ inline val isAppPredictor: Boolean
+ get() = permissionInfo.protectionFlags.hasBits(PermissionInfo.PROTECTION_FLAG_APP_PREDICTOR)
+
+ inline val isCompanion: Boolean
+ get() = permissionInfo.protectionFlags.hasBits(PermissionInfo.PROTECTION_FLAG_COMPANION)
+
+ inline val isRetailDemo: Boolean
+ get() = permissionInfo.protectionFlags.hasBits(PermissionInfo.PROTECTION_FLAG_RETAIL_DEMO)
+
+ inline val isRecents: Boolean
+ get() = permissionInfo.protectionFlags.hasBits(PermissionInfo.PROTECTION_FLAG_RECENTS)
+
+ inline val isRole: Boolean
+ get() = permissionInfo.protectionFlags.hasBits(PermissionInfo.PROTECTION_FLAG_ROLE)
+
+ inline val isKnownSigner: Boolean
+ get() = permissionInfo.protectionFlags.hasBits(PermissionInfo.PROTECTION_FLAG_KNOWN_SIGNER)
+
+ inline val protectionLevel: Int
+ @Suppress("DEPRECATION")
+ get() = permissionInfo.protectionLevel
+
+ inline val knownCerts: Set<String>
+ get() = permissionInfo.knownCerts
+
+ companion object {
+ // The permission is defined in an application manifest.
+ const val TYPE_MANIFEST = 0
+ // The permission is defined in a system config.
+ const val TYPE_CONFIG = 1
+ // The permission is defined dynamically.
+ const val TYPE_DYNAMIC = 2
+
+ // TODO: PermissionInfo.PROTECTION_FLAG_VENDOR_PRIVILEGED is a testApi
+ const val PROTECTION_FLAG_VENDOR_PRIVILEGED = 0x8000
+ }
+}
diff --git a/services/permission/java/com/android/server/permission/access/external/CompatibilityPermissionInfo.kt b/services/permission/java/com/android/server/permission/access/external/CompatibilityPermissionInfo.kt
new file mode 100644
index 000000000000..aadd8baedc81
--- /dev/null
+++ b/services/permission/java/com/android/server/permission/access/external/CompatibilityPermissionInfo.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.permission.access.external
+
+class CompatibilityPermissionInfo {
+ companion object {
+ val COMPAT_PERMS = arrayOf(CompatibilityPermissionInfo())
+ }
+
+ val name: String
+ get() = throw NotImplementedError()
+
+ val sdkVersion: Int
+ get() = throw NotImplementedError()
+}
diff --git a/services/permission/java/com/android/server/permission/access/external/KnownPackages.kt b/services/permission/java/com/android/server/permission/access/external/KnownPackages.kt
new file mode 100644
index 000000000000..1239450c0963
--- /dev/null
+++ b/services/permission/java/com/android/server/permission/access/external/KnownPackages.kt
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.permission.access.external
+
+class KnownPackages {
+ companion object {
+ const val PACKAGE_SYSTEM = 0
+ const val PACKAGE_SETUP_WIZARD = 1
+ const val PACKAGE_INSTALLER = 2
+ const val PACKAGE_VERIFIER = 4
+ const val PACKAGE_SYSTEM_TEXT_CLASSIFIER = 6
+ const val PACKAGE_PERMISSION_CONTROLLER = 7
+ const val PACKAGE_CONFIGURATOR = 10
+ const val PACKAGE_INCIDENT_REPORT_APPROVER = 11
+ const val PACKAGE_APP_PREDICTOR = 12
+ const val PACKAGE_COMPANION = 15
+ const val PACKAGE_RETAIL_DEMO = 16
+ const val PACKAGE_RECENTS = 17
+ }
+}
diff --git a/services/permission/java/com/android/server/permission/access/external/PackageInfoUtils.kt b/services/permission/java/com/android/server/permission/access/external/PackageInfoUtils.kt
new file mode 100644
index 000000000000..24b28bd49fc9
--- /dev/null
+++ b/services/permission/java/com/android/server/permission/access/external/PackageInfoUtils.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.permission.access.external
+
+import android.content.pm.PermissionGroupInfo
+import android.content.pm.PermissionInfo
+
+object PackageInfoUtils {
+ fun generatePermissionInfo(parsedPermission: ParsedPermission, flags: Long): PermissionInfo {
+ throw NotImplementedError()
+ }
+
+ fun generatePermissionGroupInfo(
+ parsedPermissionGroup: ParsedPermissionGroup,
+ flags: Long
+ ): PermissionGroupInfo {
+ throw NotImplementedError()
+ }
+}
diff --git a/services/permission/java/com/android/server/permission/access/external/PackageState.kt b/services/permission/java/com/android/server/permission/access/external/PackageState.kt
new file mode 100644
index 000000000000..b81d7946f2e9
--- /dev/null
+++ b/services/permission/java/com/android/server/permission/access/external/PackageState.kt
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.permission.access.external
+
+import android.util.SparseArray
+
+interface PackageState {
+ val androidPackage: AndroidPackage?
+ val appId: Int
+ val isSystem: Boolean
+ val isUpdatedSystemApp: Boolean
+ val packageName: String
+ val userStates: SparseArray<PackageUserState>
+ val hasSharedUser: Boolean
+ val sharedUserAppId: Int
+ val signingDetails: SigningDetails
+}
+
+interface AndroidPackage {
+ val packageName: String
+ val apexModuleName: String?
+ val appId: Int
+ val isPrivileged: Boolean
+ val isOem: Boolean
+ val isVendor: Boolean
+ val isProduct: Boolean
+ val isSystemExt: Boolean
+ val targetSdkVersion: Int
+ val adoptPermissions: List<String>
+ val permissions: List<ParsedPermission>
+ val permissionGroups: List<ParsedPermissionGroup>
+ val requestedPermissions: List<String>
+ val implicitPermissions: List<String>
+}
+
+interface ParsedPermission {
+ val name: String
+ val isTree: Boolean
+ val packageName: String
+ val isSignature: Boolean
+ val protectionLevel: Int
+}
+
+interface ParsedPermissionGroup {
+ val name: String
+ val packageName: String
+}
+
+interface PackageUserState {
+ val isInstantApp: Boolean
+}
diff --git a/services/permission/java/com/android/server/permission/access/external/RoSystemProperties.kt b/services/permission/java/com/android/server/permission/access/external/RoSystemProperties.kt
new file mode 100644
index 000000000000..528680e77879
--- /dev/null
+++ b/services/permission/java/com/android/server/permission/access/external/RoSystemProperties.kt
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.permission.access.external
+
+class RoSystemProperties {
+ companion object {
+ const val CONTROL_PRIVAPP_PERMISSIONS_DISABLE = false
+ const val CONTROL_PRIVAPP_PERMISSIONS_ENFORCE = false
+ }
+}
diff --git a/services/permission/java/com/android/server/permission/access/external/SigningDetails.kt b/services/permission/java/com/android/server/permission/access/external/SigningDetails.kt
new file mode 100644
index 000000000000..25917f993d4d
--- /dev/null
+++ b/services/permission/java/com/android/server/permission/access/external/SigningDetails.kt
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.permission.access.external
+
+object SigningDetails {
+ fun hasCommonSignerWithCapability(otherDetails: SigningDetails, flags: Int): Boolean {
+ throw NotImplementedError()
+ }
+
+ fun hasAncestorOrSelf(oldDetails: SigningDetails): Boolean {
+ throw NotImplementedError()
+ }
+
+ fun checkCapability(oldDetails: SigningDetails, flags: Int): Boolean {
+ throw NotImplementedError()
+ }
+
+ fun hasAncestorOrSelfWithDigest(certDigests: Set<String>): Boolean {
+ throw NotImplementedError()
+ }
+
+ class CertCapabilities {
+ companion object {
+ /** grant SIGNATURE permissions to pkgs with this cert */
+ var PERMISSION = 4
+ }
+ }
+}
diff --git a/services/tests/servicestests/test-apps/FakeMediaApp/src/FakeMediaButtonBroadcastReceiver.java b/services/permission/java/com/android/server/permission/access/external/UserHandle.kt
index 41f0cf52301d..e1072a760dc2 100644
--- a/services/tests/servicestests/test-apps/FakeMediaApp/src/FakeMediaButtonBroadcastReceiver.java
+++ b/services/permission/java/com/android/server/permission/access/external/UserHandle.kt
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,19 +14,18 @@
* limitations under the License.
*/
-package com.android.servicestests.apps.fakemediaapp;
+package com.android.server.permission.access.external
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.util.Log;
-
-public class FakeMediaButtonBroadcastReceiver extends BroadcastReceiver {
-
- private static final String TAG = "FakeMediaButtonBroadcastReceiver";
+interface UserHandle {
+ companion object {
+ fun getAppId(uid: Int): Int {
+ throw NotImplementedError()
+ }
+ }
+}
- @Override
- public void onReceive(Context context, Intent intent) {
- Log.v(TAG, "onReceive not expected");
+object UserHandleCompat {
+ fun getUserId(uid: Int): Int {
+ throw NotImplementedError()
}
}
diff --git a/services/permission/java/com/android/server/permission/access/permission/PermissionFlags.kt b/services/permission/java/com/android/server/permission/access/permission/PermissionFlags.kt
new file mode 100644
index 000000000000..bb1a86c7b32d
--- /dev/null
+++ b/services/permission/java/com/android/server/permission/access/permission/PermissionFlags.kt
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.permission.access.permission
+
+object PermissionFlags {
+ const val INSTALL_GRANTED = 1 shl 0
+ const val INSTALL_REVOKED = 1 shl 1
+ const val PROTECTION_GRANTED = 1 shl 2
+ const val ROLE_GRANTED = 1 shl 3
+ // For permissions that are granted in other ways,
+ // ex: via an API or implicit permissions that inherit from granted install permissions
+ const val OTHER_GRANTED = 1 shl 4
+ // For the permissions that are implicit for the package
+ const val IMPLICIT = 1 shl 5
+
+ const val MASK_GRANTED = INSTALL_GRANTED or PROTECTION_GRANTED or OTHER_GRANTED or ROLE_GRANTED
+ const val MASK_RUNTIME = OTHER_GRANTED or IMPLICIT
+}
diff --git a/services/permission/java/com/android/server/permission/access/permission/UidPermissionPersistence.kt b/services/permission/java/com/android/server/permission/access/permission/UidPermissionPersistence.kt
new file mode 100644
index 000000000000..3489061c5bae
--- /dev/null
+++ b/services/permission/java/com/android/server/permission/access/permission/UidPermissionPersistence.kt
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.permission.access.permission
+
+import android.content.pm.PermissionInfo
+import android.util.Log
+import com.android.modules.utils.BinaryXmlPullParser
+import com.android.modules.utils.BinaryXmlSerializer
+import com.android.server.permission.access.SystemState
+import com.android.server.permission.access.collection.* // ktlint-disable no-wildcard-imports
+import com.android.server.permission.access.data.Permission
+import com.android.server.permission.access.util.attribute
+import com.android.server.permission.access.util.attributeInt
+import com.android.server.permission.access.util.attributeIntHex
+import com.android.server.permission.access.util.attributeIntHexWithDefault
+import com.android.server.permission.access.util.attributeInterned
+import com.android.server.permission.access.util.forEachTag
+import com.android.server.permission.access.util.getAttributeIntHexOrDefault
+import com.android.server.permission.access.util.getAttributeIntHexOrThrow
+import com.android.server.permission.access.util.getAttributeIntOrThrow
+import com.android.server.permission.access.util.getAttributeValue
+import com.android.server.permission.access.util.getAttributeValueOrThrow
+import com.android.server.permission.access.util.tag
+import com.android.server.permission.access.util.tagName
+
+class UidPermissionPersistence {
+ fun BinaryXmlPullParser.parseSystemState(systemState: SystemState) {
+ when (tagName) {
+ TAG_PERMISSION_TREES -> parsePermissions(systemState.permissionTrees)
+ TAG_PERMISSIONS -> parsePermissions(systemState.permissions)
+ else -> {}
+ }
+ }
+
+ private fun BinaryXmlPullParser.parsePermissions(permissions: IndexedMap<String, Permission>) {
+ forEachTag {
+ when (val tagName = tagName) {
+ TAG_PERMISSION -> parsePermission(permissions)
+ else -> Log.w(LOG_TAG, "Ignoring unknown tag $tagName when parsing permissions")
+ }
+ }
+ }
+
+ private fun BinaryXmlPullParser.parsePermission(permissions: IndexedMap<String, Permission>) {
+ val name = getAttributeValueOrThrow(ATTR_NAME).intern()
+ @Suppress("DEPRECATION")
+ val permissionInfo = PermissionInfo().apply {
+ this.name = name
+ packageName = getAttributeValueOrThrow(ATTR_PACKAGE_NAME).intern()
+ protectionLevel = getAttributeIntHexOrThrow(ATTR_PROTECTION_LEVEL)
+ }
+ val type = getAttributeIntOrThrow(ATTR_TYPE)
+ when (type) {
+ Permission.TYPE_MANIFEST -> {}
+ Permission.TYPE_CONFIG -> {
+ Log.w(LOG_TAG, "Ignoring unexpected config permission $name")
+ return
+ }
+ Permission.TYPE_DYNAMIC -> {
+ permissionInfo.apply {
+ icon = getAttributeIntHexOrDefault(ATTR_ICON, 0)
+ nonLocalizedLabel = getAttributeValue(ATTR_LABEL)
+ }
+ }
+ else -> {
+ Log.w(LOG_TAG, "Ignoring permission $name with unknown type $type")
+ return
+ }
+ }
+ val permission = Permission(permissionInfo, false, type, 0)
+ permissions[name] = permission
+ }
+
+ fun BinaryXmlSerializer.serializeSystemState(systemState: SystemState) {
+ serializePermissions(TAG_PERMISSION_TREES, systemState.permissionTrees)
+ serializePermissions(TAG_PERMISSIONS, systemState.permissions)
+ }
+
+ private fun BinaryXmlSerializer.serializePermissions(
+ tagName: String,
+ permissions: IndexedMap<String, Permission>
+ ) {
+ tag(tagName) {
+ permissions.forEachValueIndexed { _, it -> serializePermission(it) }
+ }
+ }
+
+ private fun BinaryXmlSerializer.serializePermission(permission: Permission) {
+ val type = permission.type
+ when (type) {
+ Permission.TYPE_MANIFEST, Permission.TYPE_DYNAMIC -> {}
+ Permission.TYPE_CONFIG -> return
+ else -> {
+ Log.w(LOG_TAG, "Skipping serializing permission $name with unknown type $type")
+ return
+ }
+ }
+ tag(TAG_PERMISSION) {
+ attributeInterned(ATTR_NAME, permission.name)
+ attributeInterned(ATTR_PACKAGE_NAME, permission.packageName)
+ attributeIntHex(ATTR_PROTECTION_LEVEL, permission.protectionLevel)
+ attributeInt(ATTR_TYPE, type)
+ if (type == Permission.TYPE_DYNAMIC) {
+ val permissionInfo = permission.permissionInfo
+ attributeIntHexWithDefault(ATTR_ICON, permissionInfo.icon, 0)
+ permissionInfo.nonLocalizedLabel?.toString()?.let { attribute(ATTR_LABEL, it) }
+ }
+ }
+ }
+
+ companion object {
+ private val LOG_TAG = UidPermissionPersistence::class.java.simpleName
+
+ private const val TAG_PERMISSION = "permission"
+ private const val TAG_PERMISSION_TREES = "permission-trees"
+ private const val TAG_PERMISSIONS = "permissions"
+
+ private const val ATTR_ICON = "icon"
+ private const val ATTR_LABEL = "label"
+ private const val ATTR_NAME = "name"
+ private const val ATTR_PACKAGE_NAME = "packageName"
+ private const val ATTR_PROTECTION_LEVEL = "protectionLevel"
+ private const val ATTR_TYPE = "type"
+ }
+}
diff --git a/services/permission/java/com/android/server/permission/access/permission/UidPermissionPolicy.kt b/services/permission/java/com/android/server/permission/access/permission/UidPermissionPolicy.kt
new file mode 100644
index 000000000000..6479e6ad88e3
--- /dev/null
+++ b/services/permission/java/com/android/server/permission/access/permission/UidPermissionPolicy.kt
@@ -0,0 +1,909 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.permission.access.permission
+
+import android.Manifest
+import android.content.pm.PackageManager
+import android.content.pm.PermissionInfo
+import android.os.Build
+import android.os.UserHandle
+import android.util.Log
+import com.android.modules.utils.BinaryXmlPullParser
+import com.android.modules.utils.BinaryXmlSerializer
+import com.android.server.permission.access.AccessState
+import com.android.server.permission.access.AccessUri
+import com.android.server.permission.access.PermissionUri
+import com.android.server.permission.access.SchemePolicy
+import com.android.server.permission.access.SystemState
+import com.android.server.permission.access.UidUri
+import com.android.server.permission.access.UserState
+import com.android.server.permission.access.collection.* // ktlint-disable no-wildcard-imports
+import com.android.server.permission.access.data.Permission
+import com.android.server.permission.access.external.AndroidPackage
+import com.android.server.permission.access.external.CompatibilityPermissionInfo
+import com.android.server.permission.access.external.KnownPackages
+import com.android.server.permission.access.external.PackageInfoUtils
+import com.android.server.permission.access.external.PackageState
+import com.android.server.permission.access.external.RoSystemProperties
+import com.android.server.permission.access.external.SigningDetails
+import com.android.server.permission.access.util.hasAnyBit
+import com.android.server.permission.access.util.hasBits
+
+class UidPermissionPolicy : SchemePolicy() {
+ private val persistence = UidPermissionPersistence()
+
+ override val subjectScheme: String
+ get() = UidUri.SCHEME
+
+ override val objectScheme: String
+ get() = PermissionUri.SCHEME
+
+ override fun getDecision(subject: AccessUri, `object`: AccessUri, state: AccessState): Int {
+ subject as UidUri
+ `object` as PermissionUri
+ return state.userStates[subject.userId]?.permissionFlags?.get(subject.appId)
+ ?.get(`object`.permissionName) ?: 0
+ }
+
+ override fun setDecision(
+ subject: AccessUri,
+ `object`: AccessUri,
+ decision: Int,
+ oldState: AccessState,
+ newState: AccessState
+ ) {
+ subject as UidUri
+ `object` as PermissionUri
+ val uidFlags = newState.userStates.getOrPut(subject.userId) { UserState() }
+ .permissionFlags.getOrPut(subject.appId) { IndexedMap() }
+ uidFlags[`object`.permissionName] = decision
+ }
+
+ override fun onUserAdded(userId: Int, oldState: AccessState, newState: AccessState) {
+ newState.systemState.packageStates.forEachValueIndexed { _, packageState ->
+ evaluateAllPermissionStatesForPackageAndUser(
+ packageState, null, userId, oldState, newState
+ )
+ grantImplicitPermissions(packageState, userId, oldState, newState)
+ }
+ }
+
+ override fun onAppIdAdded(appId: Int, oldState: AccessState, newState: AccessState) {
+ newState.userStates.forEachIndexed { _, _, userState ->
+ userState.permissionFlags.getOrPut(appId) { IndexedMap() }
+ }
+ }
+
+ override fun onAppIdRemoved(appId: Int, oldState: AccessState, newState: AccessState) {
+ newState.userStates.forEachIndexed { _, _, userState -> userState.permissionFlags -= appId }
+ }
+
+ override fun onPackageAdded(
+ packageState: PackageState,
+ oldState: AccessState,
+ newState: AccessState
+ ) {
+ val changedPermissionNames = IndexedSet<String>()
+ adoptPermissions(packageState, changedPermissionNames, newState)
+ addPermissionGroups(packageState, newState)
+ addPermissions(packageState, changedPermissionNames, newState)
+ // TODO: revokeStoragePermissionsIfScopeExpandedInternal()
+ trimPermissions(packageState.packageName, newState)
+ changedPermissionNames.forEachIndexed { _, it ->
+ evaluatePermissionStateForAllPackages(it, packageState, oldState, newState)
+ }
+
+ evaluateAllPermissionStatesForPackage(packageState, packageState, oldState, newState)
+ newState.systemState.userIds.forEachIndexed { _, it ->
+ grantImplicitPermissions(packageState, it, oldState, newState)
+ }
+
+ // TODO: add trimPermissionStates() here for removing the permission states that are
+ // no longer requested. (equivalent to revokeUnusedSharedUserPermissionsLocked())
+ }
+
+ private fun adoptPermissions(
+ packageState: PackageState,
+ changedPermissionNames: IndexedSet<String>,
+ newState: AccessState
+ ) {
+ val `package` = packageState.androidPackage!!
+ `package`.adoptPermissions.forEachIndexed { _, originalPackageName ->
+ val packageName = `package`.packageName
+ if (!canAdoptPermissions(packageName, originalPackageName, newState)) {
+ return@forEachIndexed
+ }
+ newState.systemState.permissions.let { permissions ->
+ permissions.forEachIndexed { i, permissionName, oldPermission ->
+ if (oldPermission.packageName != originalPackageName) {
+ return@forEachIndexed
+ }
+ @Suppress("DEPRECATION")
+ val newPermissionInfo = PermissionInfo().apply {
+ name = oldPermission.permissionInfo.name
+ this.packageName = packageName
+ protectionLevel = oldPermission.permissionInfo.protectionLevel
+ }
+ val newPermission = Permission(newPermissionInfo, false, oldPermission.type, 0)
+ changedPermissionNames += permissionName
+ permissions.setValueAt(i, newPermission)
+ }
+ }
+ }
+ }
+
+ private fun canAdoptPermissions(
+ packageName: String,
+ originalPackageName: String,
+ newState: AccessState
+ ): Boolean {
+ val originalPackageState = newState.systemState.packageStates[originalPackageName]
+ ?: return false
+ if (!originalPackageState.isSystem) {
+ Log.w(
+ LOG_TAG, "Unable to adopt permissions from $originalPackageName to $packageName:" +
+ " original package not in system partition"
+ )
+ return false
+ }
+ if (originalPackageState.androidPackage != null) {
+ Log.w(
+ LOG_TAG, "Unable to adopt permissions from $originalPackageName to $packageName:" +
+ " original package still exists"
+ )
+ return false
+ }
+ return true
+ }
+
+ private fun addPermissionGroups(packageState: PackageState, newState: AccessState) {
+ // Different from the old implementation, which decides whether the app is an instant app by
+ // the install flags, now for consistent behavior we allow adding permission groups if the
+ // app is non-instant in at least one user.
+ val isInstantApp = packageState.userStates.allIndexed { _, _, it -> it.isInstantApp }
+ if (isInstantApp) {
+ Log.w(
+ LOG_TAG, "Ignoring permission groups declared in package" +
+ " ${packageState.packageName}: instant apps cannot declare permission groups"
+ )
+ return
+ }
+ packageState.androidPackage!!.permissionGroups.forEachIndexed { _, parsedPermissionGroup ->
+ val newPermissionGroup = PackageInfoUtils.generatePermissionGroupInfo(
+ parsedPermissionGroup, PackageManager.GET_META_DATA.toLong()
+ )
+ // TODO: Clear permission state on group take-over?
+ val permissionGroupName = newPermissionGroup.name
+ val oldPermissionGroup = newState.systemState.permissionGroups[permissionGroupName]
+ if (oldPermissionGroup != null &&
+ newPermissionGroup.packageName != oldPermissionGroup.packageName) {
+ Log.w(
+ LOG_TAG, "Ignoring permission group $permissionGroupName declared in package" +
+ " ${newPermissionGroup.packageName}: already declared in another package" +
+ " ${oldPermissionGroup.packageName}"
+ )
+ return@forEachIndexed
+ }
+ newState.systemState.permissionGroups[permissionGroupName] = newPermissionGroup
+ }
+ }
+
+ private fun addPermissions(
+ packageState: PackageState,
+ changedPermissionNames: IndexedSet<String>,
+ newState: AccessState
+ ) {
+ packageState.androidPackage!!.permissions.forEachIndexed { _, parsedPermission ->
+ // TODO:
+ // parsedPermission.flags = parsedPermission.flags andInv PermissionInfo.FLAG_INSTALLED
+ // TODO: This seems actually unused.
+ // if (packageState.androidPackage.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
+ // parsedPermission.setParsedPermissionGroup(
+ // newState.systemState.permissionGroup[parsedPermission.group]
+ // )
+ // }
+ val newPermissionInfo = PackageInfoUtils.generatePermissionInfo(
+ parsedPermission, PackageManager.GET_META_DATA.toLong()
+ )
+ // TODO: newPermissionInfo.flags |= PermissionInfo.FLAG_INSTALLED
+ val permissionName = newPermissionInfo.name
+ val oldPermission = if (parsedPermission.isTree) {
+ newState.systemState.permissionTrees[permissionName]
+ } else {
+ newState.systemState.permissions[permissionName]
+ }
+ // Different from the old implementation, which may add an (incomplete) signature
+ // permission inside another package's permission tree, we now consistently ignore such
+ // permissions.
+ val permissionTree = getPermissionTree(permissionName, newState)
+ val newPackageName = newPermissionInfo.packageName
+ if (permissionTree != null && newPackageName != permissionTree.packageName) {
+ Log.w(
+ LOG_TAG, "Ignoring permission $permissionName declared in package" +
+ " $newPackageName: base permission tree ${permissionTree.name} is" +
+ " declared in another package ${permissionTree.packageName}"
+ )
+ return@forEachIndexed
+ }
+ val newPermission = if (oldPermission != null &&
+ newPackageName != oldPermission.packageName) {
+ val oldPackageName = oldPermission.packageName
+ // Only allow system apps to redefine non-system permissions.
+ if (!packageState.isSystem) {
+ Log.w(
+ LOG_TAG, "Ignoring permission $permissionName declared in package" +
+ " $newPackageName: already declared in another package" +
+ " $oldPackageName"
+ )
+ return@forEachIndexed
+ }
+ if (oldPermission.type == Permission.TYPE_CONFIG && !oldPermission.isReconciled) {
+ // It's a config permission and has no owner, take ownership now.
+ Permission(newPermissionInfo, true, Permission.TYPE_CONFIG, packageState.appId)
+ } else if (newState.systemState.packageStates[oldPackageName]?.isSystem != true) {
+ Log.w(
+ LOG_TAG, "Overriding permission $permissionName with new declaration in" +
+ " system package $newPackageName: originally declared in another" +
+ " package $oldPackageName"
+ )
+ // Remove permission state on owner change.
+ newState.userStates.forEachValueIndexed { _, userState ->
+ userState.permissionFlags.forEachValueIndexed { _, permissionFlags ->
+ permissionFlags -= newPermissionInfo.name
+ }
+ }
+ // TODO: Notify re-evaluation of this permission.
+ Permission(
+ newPermissionInfo, true, Permission.TYPE_MANIFEST, packageState.appId
+ )
+ } else {
+ Log.w(
+ LOG_TAG, "Ignoring permission $permissionName declared in system package" +
+ " $newPackageName: already declared in another system package" +
+ " $oldPackageName")
+ return@forEachIndexed
+ }
+ } else {
+ // TODO: STOPSHIP: Clear permission state on type or group change.
+ // Different from the old implementation, which doesn't update the permission
+ // definition upon app update, but does update it on the next boot, we now
+ // consistently update the permission definition upon app update.
+ Permission(newPermissionInfo, true, Permission.TYPE_MANIFEST, packageState.appId)
+ }
+
+ changedPermissionNames += permissionName
+ if (parsedPermission.isTree) {
+ newState.systemState.permissionTrees[permissionName] = newPermission
+ } else {
+ newState.systemState.permissions[permissionName] = newPermission
+ }
+ }
+ }
+
+ private fun trimPermissions(
+ packageName: String,
+ newState: AccessState,
+ ) {
+ val packageState = newState.systemState.packageStates[packageName]
+ val androidPackage = packageState?.androidPackage
+ if (packageState != null && androidPackage == null) {
+ return
+ }
+
+ newState.systemState.permissionTrees.removeAllIndexed {
+ _, permissionTreeName, permissionTree ->
+ permissionTree.packageName == packageName && (
+ packageState == null || androidPackage!!.permissions.noneIndexed { _, it ->
+ it.isTree && it.name == permissionTreeName
+ }
+ )
+ }
+
+ newState.systemState.permissions.removeAllIndexed { i, permissionName, permission ->
+ val updatedPermission = updatePermissionIfDynamic(permission, newState)
+ newState.systemState.permissions.setValueAt(i, updatedPermission)
+ if (updatedPermission.packageName == packageName && (
+ packageState == null || androidPackage!!.permissions.noneIndexed { _, it ->
+ !it.isTree && it.name == permissionName
+ }
+ )) {
+ if (!isPermissionDeclaredByDisabledSystemPackage(permission, newState)) {
+ newState.userStates.forEachIndexed { _, userId, userState ->
+ userState.permissionFlags.forEachKeyIndexed { _, appId ->
+ setPermissionFlags(
+ appId, permissionName, getPermissionFlags(
+ appId, permissionName, userId, newState
+ ) and PermissionFlags.INSTALL_REVOKED, userId, newState
+ )
+ }
+ }
+ }
+ true
+ } else {
+ false
+ }
+ }
+ }
+
+ private fun isPermissionDeclaredByDisabledSystemPackage(
+ permission: Permission,
+ newState: AccessState
+ ): Boolean {
+ val disabledSystemPackage = newState.systemState
+ .disabledSystemPackageStates[permission.packageName]?.androidPackage ?: return false
+ return disabledSystemPackage.permissions.anyIndexed { _, it ->
+ it.name == permission.name && it.protectionLevel == permission.protectionLevel
+ }
+ }
+
+ private fun updatePermissionIfDynamic(
+ permission: Permission,
+ newState: AccessState
+ ): Permission {
+ if (!permission.isDynamic) {
+ return permission
+ }
+ val permissionTree = getPermissionTree(permission.name, newState) ?: return permission
+ @Suppress("DEPRECATION")
+ return permission.copy(
+ permissionInfo = PermissionInfo(permission.permissionInfo).apply {
+ packageName = permissionTree.packageName
+ }, appId = permissionTree.appId, isReconciled = true
+ )
+ }
+
+ private fun getPermissionTree(permissionName: String, newState: AccessState): Permission? =
+ newState.systemState.permissionTrees.firstNotNullOfOrNullIndexed {
+ _, permissionTreeName, permissionTree ->
+ if (permissionName.startsWith(permissionTreeName) &&
+ permissionName.length > permissionTreeName.length &&
+ permissionName[permissionTreeName.length] == '.') {
+ permissionTree
+ } else {
+ null
+ }
+ }
+
+ private fun evaluatePermissionStateForAllPackages(
+ permissionName: String,
+ installedPackageState: PackageState?,
+ oldState: AccessState,
+ newState: AccessState
+ ) {
+ newState.systemState.userIds.forEachIndexed { _, userId ->
+ oldState.userStates[userId]?.permissionFlags?.forEachIndexed {
+ _, appId, permissionFlags ->
+ if (permissionName in permissionFlags) {
+ evaluatePermissionState(
+ appId, permissionName, installedPackageState, userId, oldState, newState
+ )
+ }
+ }
+ }
+ }
+
+ private fun evaluateAllPermissionStatesForPackage(
+ packageState: PackageState,
+ installedPackageState: PackageState?,
+ oldState: AccessState,
+ newState: AccessState
+ ) {
+ newState.systemState.userIds.forEachIndexed { _, userId ->
+ evaluateAllPermissionStatesForPackageAndUser(
+ packageState, installedPackageState, userId, oldState, newState
+ )
+ }
+ }
+
+ private fun evaluateAllPermissionStatesForPackageAndUser(
+ packageState: PackageState,
+ installedPackageState: PackageState?,
+ userId: Int,
+ oldState: AccessState,
+ newState: AccessState
+ ) {
+ packageState.androidPackage?.requestedPermissions?.forEachIndexed { _, it ->
+ evaluatePermissionState(
+ packageState.appId, it, installedPackageState, userId, oldState, newState
+ )
+ }
+ }
+
+ private fun evaluatePermissionState(
+ appId: Int,
+ permissionName: String,
+ installedPackageState: PackageState?,
+ userId: Int,
+ oldState: AccessState,
+ newState: AccessState
+ ) {
+ val packageNames = newState.systemState.appIds[appId]
+ val hasMissingPackage = packageNames.anyIndexed { _, packageName ->
+ newState.systemState.packageStates[packageName]!!.androidPackage == null
+ }
+ if (packageNames.size == 1 && hasMissingPackage) {
+ // For non-shared-user packages with missing androidPackage, skip evaluation.
+ return
+ }
+ val permission = newState.systemState.permissions[permissionName] ?: return
+ val oldFlags = getPermissionFlags(appId, permissionName, userId, newState)
+ if (permission.isNormal) {
+ val wasGranted = oldFlags.hasBits(PermissionFlags.INSTALL_GRANTED)
+ if (!wasGranted) {
+ val wasRevoked = oldFlags.hasBits(PermissionFlags.INSTALL_REVOKED)
+ val isRequestedByInstalledPackage = installedPackageState != null &&
+ permissionName in installedPackageState.androidPackage!!.requestedPermissions
+ val isRequestedBySystemPackage = anyPackageInAppId(appId, newState) {
+ it.isSystem && permissionName in it.androidPackage!!.requestedPermissions
+ }
+ val isCompatibilityPermission = anyPackageInAppId(appId, newState) {
+ isCompatibilityPermissionForPackage(it.androidPackage!!, permissionName)
+ }
+ // If this is an existing, non-system package,
+ // then we can't add any new permissions to it.
+ // Except if this is a permission that was added to the platform
+ val newFlags = if (!wasRevoked || isRequestedByInstalledPackage ||
+ isRequestedBySystemPackage || isCompatibilityPermission) {
+ PermissionFlags.INSTALL_GRANTED
+ } else {
+ PermissionFlags.INSTALL_REVOKED
+ }
+ setPermissionFlags(appId, permissionName, newFlags, userId, newState)
+ }
+ } else if (permission.isSignature || permission.isInternal) {
+ val wasProtectionGranted = oldFlags.hasBits(PermissionFlags.PROTECTION_GRANTED)
+ var newFlags = if (hasMissingPackage && wasProtectionGranted) {
+ // Keep the non-runtime permission grants for shared UID with missing androidPackage
+ PermissionFlags.PROTECTION_GRANTED
+ } else {
+ val mayGrantByPrivileged = !permission.isPrivileged || (
+ anyPackageInAppId(appId, newState) {
+ checkPrivilegedPermissionAllowlist(it, permission, newState)
+ }
+ )
+ val shouldGrantBySignature = permission.isSignature && (
+ anyPackageInAppId(appId, newState) {
+ shouldGrantPermissionBySignature(it, permission, newState)
+ }
+ )
+ val shouldGrantByProtectionFlags = anyPackageInAppId(appId, newState) {
+ shouldGrantPermissionByProtectionFlags(it, permission, newState)
+ }
+ if (mayGrantByPrivileged &&
+ (shouldGrantBySignature || shouldGrantByProtectionFlags)) {
+ PermissionFlags.PROTECTION_GRANTED
+ } else {
+ 0
+ }
+ }
+ // Different from the old implementation, which seemingly allows granting an
+ // unallowlisted privileged permission via development or role but revokes it upon next
+ // reconciliation, we now properly allows that because the privileged protection flag
+ // should only affect the other static flags, but not dynamic flags like development or
+ // role. This may be useful in the case of an updated system app.
+ if (permission.isDevelopment) {
+ newFlags = newFlags or (oldFlags and PermissionFlags.OTHER_GRANTED)
+ }
+ if (permission.isRole) {
+ newFlags = newFlags or (oldFlags and PermissionFlags.ROLE_GRANTED)
+ }
+ setPermissionFlags(appId, permissionName, newFlags, userId, newState)
+ } else if (permission.isRuntime) {
+ // TODO: add runtime permissions
+ } else {
+ Log.e(LOG_TAG, "Unknown protection level ${permission.protectionLevel}" +
+ "for permission ${permission.name} while evaluating permission state" +
+ "for appId $appId and userId $userId")
+ }
+
+ // TODO: revokePermissionsNoLongerImplicitLocked() for runtime permissions
+ }
+
+ private fun grantImplicitPermissions(
+ packageState: PackageState,
+ userId: Int,
+ oldState: AccessState,
+ newState: AccessState
+ ) {
+ val appId = packageState.appId
+ val androidPackage = packageState.androidPackage ?: return
+ androidPackage.implicitPermissions.forEachIndexed implicitPermissions@ {
+ _, implicitPermissionName ->
+ val implicitPermission = newState.systemState.permissions[implicitPermissionName]
+ checkNotNull(implicitPermission) {
+ "Unknown implicit permission $implicitPermissionName in split permissions"
+ }
+ if (!implicitPermission.isRuntime) {
+ return@implicitPermissions
+ }
+ val isNewPermission = getPermissionFlags(
+ appId, implicitPermissionName, userId, oldState
+ ) == 0
+ if (!isNewPermission) {
+ return@implicitPermissions
+ }
+ val sourcePermissions = newState.systemState
+ .implicitToSourcePermissions[implicitPermissionName] ?: return@implicitPermissions
+ var newFlags = 0
+ sourcePermissions.forEachIndexed sourcePermissions@ { _, sourcePermissionName ->
+ val sourcePermission = newState.systemState.permissions[sourcePermissionName]
+ checkNotNull(sourcePermission) {
+ "Unknown source permission $sourcePermissionName in split permissions"
+ }
+ val sourceFlags = getPermissionFlags(appId, sourcePermissionName, userId, newState)
+ val isSourceGranted = sourceFlags.hasAnyBit(PermissionFlags.MASK_GRANTED)
+ val isNewGranted = newFlags.hasAnyBit(PermissionFlags.MASK_GRANTED)
+ val isGrantingNewFromRevoke = isSourceGranted && !isNewGranted
+ if (isSourceGranted == isNewGranted || isGrantingNewFromRevoke) {
+ if (isGrantingNewFromRevoke) {
+ newFlags = 0
+ }
+ newFlags = newFlags or (sourceFlags and PermissionFlags.MASK_RUNTIME)
+ if (!sourcePermission.isRuntime && isSourceGranted) {
+ newFlags = newFlags or PermissionFlags.OTHER_GRANTED
+ }
+ }
+ }
+ newFlags = newFlags or PermissionFlags.IMPLICIT
+ setPermissionFlags(appId, implicitPermissionName, newFlags, userId, newState)
+ }
+ }
+
+ private fun getPermissionFlags(
+ appId: Int,
+ permissionName: String,
+ userId: Int,
+ state: AccessState
+ ): Int = state.userStates[userId].permissionFlags[appId].getWithDefault(permissionName, 0)
+
+ private fun setPermissionFlags(
+ appId: Int,
+ permissionName: String,
+ flags: Int,
+ userId: Int,
+ newState: AccessState
+ ) {
+ newState.userStates[userId].permissionFlags[appId]!!
+ .putWithDefault(permissionName, flags, 0)
+ }
+
+ private fun isCompatibilityPermissionForPackage(
+ androidPackage: AndroidPackage,
+ permissionName: String
+ ): Boolean {
+ for (info: CompatibilityPermissionInfo in CompatibilityPermissionInfo.COMPAT_PERMS) {
+ if (info.name == permissionName && androidPackage.targetSdkVersion < info.sdkVersion) {
+ Log.i(
+ LOG_TAG, "Auto-granting $permissionName to old package" +
+ " ${androidPackage.packageName}"
+ )
+ return true
+ }
+ }
+ return false
+ }
+
+ private fun shouldGrantPermissionBySignature(
+ packageState: PackageState,
+ permission: Permission,
+ newState: AccessState
+ ): Boolean {
+ // check if the package is allow to use this signature permission. A package is allowed to
+ // use a signature permission if:
+ // - it has the same set of signing certificates as the source package
+ // - or its signing certificate was rotated from the source package's certificate
+ // - or its signing certificate is a previous signing certificate of the defining
+ // package, and the defining package still trusts the old certificate for permissions
+ // - or it shares a common signing certificate in its lineage with the defining package,
+ // and the defining package still trusts the old certificate for permissions
+ // - or it shares the above relationships with the system package
+ val sourceSigningDetails = newState.systemState
+ .packageStates[permission.packageName]?.signingDetails
+ val platformSigningDetails = newState.systemState
+ .packageStates[PLATFORM_PACKAGE_NAME]!!.signingDetails
+ return sourceSigningDetails?.hasCommonSignerWithCapability(packageState.signingDetails,
+ SigningDetails.CertCapabilities.PERMISSION) == true ||
+ packageState.signingDetails.hasAncestorOrSelf(platformSigningDetails) ||
+ platformSigningDetails.checkCapability(packageState.signingDetails,
+ SigningDetails.CertCapabilities.PERMISSION)
+ }
+
+ private fun checkPrivilegedPermissionAllowlist(
+ packageState: PackageState,
+ permission: Permission,
+ newState: AccessState
+ ): Boolean {
+ if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_DISABLE) {
+ return true
+ }
+ if (packageState.packageName == PLATFORM_PACKAGE_NAME) {
+ return true
+ }
+ val androidPackage = packageState.androidPackage!!
+ if (!androidPackage.isPrivileged) {
+ return true
+ }
+ if (permission.packageName !in
+ newState.systemState.privilegedPermissionAllowlistSourcePackageNames) {
+ return true
+ }
+ if (isInSystemConfigPrivAppPermissions(androidPackage, permission.name, newState)) {
+ return true
+ }
+ if (isInSystemConfigPrivAppDenyPermissions(androidPackage, permission.name, newState)) {
+ return false
+ }
+ // Updated system apps do not need to be allowlisted
+ if (packageState.isUpdatedSystemApp) {
+ return true
+ }
+ // TODO: Enforce the allowlist on boot
+ return !RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE
+ }
+
+ private fun isInSystemConfigPrivAppPermissions(
+ androidPackage: AndroidPackage,
+ permissionName: String,
+ newState: AccessState
+ ): Boolean {
+ val apexModuleName = androidPackage.apexModuleName
+ val systemState = newState.systemState
+ val packageName = androidPackage.packageName
+ val permissionNames = when {
+ androidPackage.isVendor -> systemState.vendorPrivAppPermissions[packageName]
+ androidPackage.isProduct -> systemState.productPrivAppPermissions[packageName]
+ androidPackage.isSystemExt -> systemState.systemExtPrivAppPermissions[packageName]
+ apexModuleName != null -> {
+ val apexPrivAppPermissions = systemState.apexPrivAppPermissions[apexModuleName]
+ ?.get(packageName)
+ val privAppPermissions = systemState.privAppPermissions[packageName]
+ when {
+ apexPrivAppPermissions == null -> privAppPermissions
+ privAppPermissions == null -> apexPrivAppPermissions
+ else -> apexPrivAppPermissions + privAppPermissions
+ }
+ }
+ else -> systemState.privAppPermissions[packageName]
+ }
+ return permissionNames?.contains(permissionName) == true
+ }
+
+ private fun isInSystemConfigPrivAppDenyPermissions(
+ androidPackage: AndroidPackage,
+ permissionName: String,
+ newState: AccessState
+ ): Boolean {
+ // Different from the previous implementation, which may incorrectly use the APEX package
+ // name, we now use the APEX module name to be consistent with the allowlist.
+ val apexModuleName = androidPackage.apexModuleName
+ val systemState = newState.systemState
+ val packageName = androidPackage.packageName
+ val permissionNames = when {
+ androidPackage.isVendor -> systemState.vendorPrivAppDenyPermissions[packageName]
+ androidPackage.isProduct -> systemState.productPrivAppDenyPermissions[packageName]
+ androidPackage.isSystemExt -> systemState.systemExtPrivAppDenyPermissions[packageName]
+ // Different from the previous implementation, which ignores the regular priv app
+ // denylist in this case, we now respect it as well to be consistent with the allowlist.
+ apexModuleName != null -> {
+ val apexPrivAppDenyPermissions = systemState
+ .apexPrivAppDenyPermissions[apexModuleName]?.get(packageName)
+ val privAppDenyPermissions = systemState.privAppDenyPermissions[packageName]
+ when {
+ apexPrivAppDenyPermissions == null -> privAppDenyPermissions
+ privAppDenyPermissions == null -> apexPrivAppDenyPermissions
+ else -> apexPrivAppDenyPermissions + privAppDenyPermissions
+ }
+ }
+ else -> systemState.privAppDenyPermissions[packageName]
+ }
+ return permissionNames?.contains(permissionName) == true
+ }
+
+ private fun anyPackageInAppId(
+ appId: Int,
+ newState: AccessState,
+ predicate: (PackageState) -> Boolean
+ ): Boolean {
+ val packageNames = newState.systemState.appIds[appId]
+ return packageNames.anyIndexed { _, packageName ->
+ val packageState = newState.systemState.packageStates[packageName]!!
+ packageState.androidPackage != null && predicate(packageState)
+ }
+ }
+
+ private fun shouldGrantPermissionByProtectionFlags(
+ packageState: PackageState,
+ permission: Permission,
+ newState: AccessState
+ ): Boolean {
+ val androidPackage = packageState.androidPackage!!
+ val knownPackages = newState.systemState.knownPackages
+ val packageName = packageState.packageName
+ if ((permission.isPrivileged || permission.isOem) && packageState.isSystem) {
+ val shouldGrant = if (packageState.isUpdatedSystemApp) {
+ // For updated system applications, a privileged/oem permission
+ // is granted only if it had been defined by the original application.
+ val disabledSystemPackage = newState.systemState
+ .disabledSystemPackageStates[packageState.packageName]?.androidPackage
+ disabledSystemPackage != null &&
+ permission.name in disabledSystemPackage.requestedPermissions &&
+ shouldGrantPrivilegedOrOemPermission(
+ disabledSystemPackage, permission, newState
+ )
+ } else {
+ shouldGrantPrivilegedOrOemPermission(androidPackage, permission, newState)
+ }
+ if (shouldGrant) {
+ return true
+ }
+ }
+ if (permission.isPre23 && androidPackage.targetSdkVersion < Build.VERSION_CODES.M) {
+ // If this was a previously normal/dangerous permission that got moved
+ // to a system permission as part of the runtime permission redesign, then
+ // we still want to blindly grant it to old apps.
+ return true
+ }
+ if (permission.isInstaller && (
+ packageName in knownPackages[KnownPackages.PACKAGE_INSTALLER] ||
+ packageName in knownPackages[KnownPackages.PACKAGE_PERMISSION_CONTROLLER]
+ )) {
+ // If this permission is to be granted to the system installer and
+ // this app is an installer or permission controller, then it gets the permission.
+ return true
+ }
+ if (permission.isVerifier &&
+ packageName in knownPackages[KnownPackages.PACKAGE_VERIFIER]) {
+ // If this permission is to be granted to the system verifier and
+ // this app is a verifier, then it gets the permission.
+ return true
+ }
+ if (permission.isPreInstalled && packageState.isSystem) {
+ // Any pre-installed system app is allowed to get this permission.
+ return true
+ }
+ if (permission.isKnownSigner &&
+ packageState.signingDetails.hasAncestorOrSelfWithDigest(permission.knownCerts)) {
+ // If the permission is to be granted to a known signer then check if any of this
+ // app's signing certificates are in the trusted certificate digest Set.
+ return true
+ }
+ if (permission.isSetup &&
+ packageName in knownPackages[KnownPackages.PACKAGE_SETUP_WIZARD]) {
+ // If this permission is to be granted to the system setup wizard and
+ // this app is a setup wizard, then it gets the permission.
+ return true
+ }
+ if (permission.isSystemTextClassifier &&
+ packageName in knownPackages[KnownPackages.PACKAGE_SYSTEM_TEXT_CLASSIFIER]) {
+ // Special permissions for the system default text classifier.
+ return true
+ }
+ if (permission.isConfigurator &&
+ packageName in knownPackages[KnownPackages.PACKAGE_CONFIGURATOR]) {
+ // Special permissions for the device configurator.
+ return true
+ }
+ if (permission.isIncidentReportApprover &&
+ packageName in knownPackages[KnownPackages.PACKAGE_INCIDENT_REPORT_APPROVER]) {
+ // If this permission is to be granted to the incident report approver and
+ // this app is the incident report approver, then it gets the permission.
+ return true
+ }
+ if (permission.isAppPredictor &&
+ packageName in knownPackages[KnownPackages.PACKAGE_APP_PREDICTOR]) {
+ // Special permissions for the system app predictor.
+ return true
+ }
+ if (permission.isCompanion &&
+ packageName in knownPackages[KnownPackages.PACKAGE_COMPANION]) {
+ // Special permissions for the system companion device manager.
+ return true
+ }
+ if (permission.isRetailDemo &&
+ packageName in knownPackages[KnownPackages.PACKAGE_RETAIL_DEMO] &&
+ isDeviceOrProfileOwnerUid(packageState.appId, newState)) {
+ // Special permission granted only to the OEM specified retail demo app.
+ // Note that the original code was passing app ID as UID, so this behavior is kept
+ // unchanged.
+ return true
+ }
+ if (permission.isRecents &&
+ packageName in knownPackages[KnownPackages.PACKAGE_RECENTS]) {
+ // Special permission for the recents app.
+ return true
+ }
+ return false
+ }
+
+ private fun shouldGrantPrivilegedOrOemPermission(
+ androidPackage: AndroidPackage,
+ permission: Permission,
+ state: AccessState
+ ): Boolean {
+ val permissionName = permission.name
+ val packageName = androidPackage.packageName
+ when {
+ permission.isPrivileged -> {
+ if (androidPackage.isPrivileged) {
+ // In any case, don't grant a privileged permission to privileged vendor apps,
+ // if the permission's protectionLevel does not have the extra vendorPrivileged
+ // flag.
+ if (androidPackage.isVendor && !permission.isVendorPrivileged) {
+ Log.w(
+ LOG_TAG, "Permission $permissionName cannot be granted to privileged" +
+ " vendor app $packageName because it isn't a vendorPrivileged" +
+ " permission"
+ )
+ return false
+ }
+ return true
+ }
+ }
+ permission.isOem -> {
+ if (androidPackage.isOem) {
+ val isOemAllowlisted = state.systemState
+ .oemPermissions[packageName]?.get(permissionName)
+ checkNotNull(isOemAllowlisted) {
+ "OEM permission $permissionName requested by package" +
+ " $packageName must be explicitly declared granted or not"
+ }
+ return isOemAllowlisted
+ }
+ }
+ }
+ return false
+ }
+
+ private fun isDeviceOrProfileOwnerUid(uid: Int, state: AccessState): Boolean {
+ val userId = UserHandle.getUserId(uid)
+ val ownerPackageName = state.systemState.deviceAndProfileOwners[userId] ?: return false
+ val ownerPackageState = state.systemState.packageStates[ownerPackageName] ?: return false
+ val ownerUid = UserHandle.getUid(userId, ownerPackageState.appId)
+ return uid == ownerUid
+ }
+
+ override fun onPackageRemoved(
+ packageState: PackageState,
+ oldState: AccessState,
+ newState: AccessState
+ ) {
+ // TODO
+ }
+
+ override fun BinaryXmlPullParser.parseSystemState(systemState: SystemState) {
+ with(persistence) { this@parseSystemState.parseSystemState(systemState) }
+ }
+
+ override fun BinaryXmlSerializer.serializeSystemState(systemState: SystemState) {
+ with(persistence) { this@serializeSystemState.serializeSystemState(systemState) }
+ }
+
+ companion object {
+ private val LOG_TAG = UidPermissionPolicy::class.java.simpleName
+
+ private const val PLATFORM_PACKAGE_NAME = "android"
+
+ // A set of permissions that we don't want to revoke when they are no longer implicit.
+ private val RETAIN_IMPLICIT_GRANT_PERMISSIONS = indexedSetOf(
+ Manifest.permission.ACCESS_MEDIA_LOCATION,
+ Manifest.permission.ACTIVITY_RECOGNITION,
+ Manifest.permission.READ_MEDIA_AUDIO,
+ Manifest.permission.READ_MEDIA_IMAGES,
+ Manifest.permission.READ_MEDIA_VIDEO,
+ )
+ }
+}
diff --git a/services/permission/java/com/android/server/permission/access/util/AtomicFileExtensions.kt b/services/permission/java/com/android/server/permission/access/util/AtomicFileExtensions.kt
new file mode 100644
index 000000000000..984dfb5a7548
--- /dev/null
+++ b/services/permission/java/com/android/server/permission/access/util/AtomicFileExtensions.kt
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.permission.access.util
+
+import android.util.AtomicFile
+import java.io.FileInputStream
+import java.io.FileOutputStream
+import java.io.IOException
+
+/**
+ * Read from an [AtomicFile] and close everything safely when done.
+ */
+@Throws(IOException::class)
+inline fun AtomicFile.read(block: (FileInputStream) -> Unit) {
+ openRead().use(block)
+}
+
+/**
+ * Write to an [AtomicFile] and close everything safely when done.
+ */
+@Throws(IOException::class)
+// Renamed to writeInlined() to avoid conflict with the hidden AtomicFile.write() that isn't inline.
+inline fun AtomicFile.writeInlined(block: (FileOutputStream) -> Unit) {
+ startWrite().use {
+ try {
+ block(it)
+ finishWrite(it)
+ } catch (t: Throwable) {
+ failWrite(it)
+ throw t
+ }
+ }
+}
diff --git a/services/permission/java/com/android/server/permission/access/util/BinaryXmlPullParserExtensions.kt b/services/permission/java/com/android/server/permission/access/util/BinaryXmlPullParserExtensions.kt
new file mode 100644
index 000000000000..1d27aef39a2c
--- /dev/null
+++ b/services/permission/java/com/android/server/permission/access/util/BinaryXmlPullParserExtensions.kt
@@ -0,0 +1,300 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.permission.access.util
+
+import com.android.modules.utils.BinaryXmlPullParser
+import java.io.IOException
+import java.io.InputStream
+import org.xmlpull.v1.XmlPullParser
+import org.xmlpull.v1.XmlPullParserException
+
+/**
+ * Parse content from [InputStream] with [BinaryXmlPullParser].
+ */
+@Throws(IOException::class, XmlPullParserException::class)
+inline fun InputStream.parseBinaryXml(block: BinaryXmlPullParser.() -> Unit) {
+ BinaryXmlPullParser().apply {
+ setInput(this@parseBinaryXml, null)
+ block()
+ }
+}
+
+/**
+ * Iterate through child tags of the current tag.
+ * <p>
+ * Attributes for the current tag needs to be accessed before this method is called because this
+ * method will advance the parser past the start tag of the current tag. The code inspecting each
+ * child tag may access the attributes of the child tag, and/or call [forEachTag] recursively to
+ * inspect grandchild tags, which will naturally leave the parser at either the start tag or the end
+ * tag of the child tag it inspected.
+ *
+ * @see BinaryXmlPullParser.next
+ * @see BinaryXmlPullParser.getEventType
+ * @see BinaryXmlPullParser.getDepth
+ */
+@Throws(IOException::class, XmlPullParserException::class)
+inline fun BinaryXmlPullParser.forEachTag(block: BinaryXmlPullParser.() -> Unit) {
+ when (val eventType = eventType) {
+ // Document start or start tag of the parent tag.
+ XmlPullParser.START_DOCUMENT, XmlPullParser.START_TAG -> nextTagOrEnd()
+ else -> throw XmlPullParserException("Unexpected event type $eventType")
+ }
+ while (true) {
+ when (val eventType = eventType) {
+ // Start tag of a child tag.
+ XmlPullParser.START_TAG -> {
+ val childDepth = depth
+ block()
+ // block() should leave the parser at either the start tag (no grandchild tags
+ // expected) or the end tag (grandchild tags parsed with forEachTag()) of this child
+ // tag.
+ val postBlockDepth = depth
+ if (postBlockDepth != childDepth) {
+ throw XmlPullParserException(
+ "Unexpected post-block depth $postBlockDepth, expected $childDepth"
+ )
+ }
+ // Skip the parser to the end tag of this child tag.
+ while (true) {
+ when (val childEventType = this.eventType) {
+ // Start tag of either this child tag or a grandchild tag.
+ XmlPullParser.START_TAG -> nextTagOrEnd()
+ XmlPullParser.END_TAG -> {
+ if (depth > childDepth) {
+ // End tag of a grandchild tag.
+ nextTagOrEnd()
+ } else {
+ // End tag of this child tag.
+ break
+ }
+ }
+ else ->
+ throw XmlPullParserException("Unexpected event type $childEventType")
+ }
+ }
+ // Skip the end tag of this child tag.
+ nextTagOrEnd()
+ }
+ // End tag of the parent tag, or document end.
+ XmlPullParser.END_TAG, XmlPullParser.END_DOCUMENT -> break
+ else -> throw XmlPullParserException("Unexpected event type $eventType")
+ }
+ }
+}
+
+/**
+ * Advance the parser until the current event is one of [XmlPullParser.START_TAG],
+ * [XmlPullParser.START_TAG] and [XmlPullParser.START_TAG]
+ *
+ * @see BinaryXmlPullParser.next
+ */
+@Throws(IOException::class, XmlPullParserException::class)
+@Suppress("NOTHING_TO_INLINE")
+inline fun BinaryXmlPullParser.nextTagOrEnd(): Int {
+ while (true) {
+ when (val eventType = next()) {
+ XmlPullParser.START_TAG, XmlPullParser.END_TAG, XmlPullParser.END_DOCUMENT ->
+ return eventType
+ else -> continue
+ }
+ }
+}
+
+/**
+ * @see BinaryXmlPullParser.getName
+ */
+inline val BinaryXmlPullParser.tagName: String
+ get() = name
+
+/**
+ * Check whether an attribute exists for the current tag.
+ */
+@Suppress("NOTHING_TO_INLINE")
+inline fun BinaryXmlPullParser.hasAttribute(name: String): Boolean = getAttributeIndex(name) != -1
+
+/**
+ * @see BinaryXmlPullParser.getAttributeIndex
+ */
+@Suppress("NOTHING_TO_INLINE")
+inline fun BinaryXmlPullParser.getAttributeIndex(name: String): Int = getAttributeIndex(null, name)
+
+/**
+ * @see BinaryXmlPullParser.getAttributeIndexOrThrow
+ */
+@Suppress("NOTHING_TO_INLINE")
+@Throws(XmlPullParserException::class)
+inline fun BinaryXmlPullParser.getAttributeIndexOrThrow(name: String): Int =
+ getAttributeIndexOrThrow(null, name)
+
+/**
+ * @see BinaryXmlPullParser.getAttributeValue
+ */
+@Suppress("NOTHING_TO_INLINE")
+@Throws(XmlPullParserException::class)
+inline fun BinaryXmlPullParser.getAttributeValue(name: String): String? =
+ getAttributeValue(null, name)
+
+/**
+ * @see BinaryXmlPullParser.getAttributeValue
+ */
+@Suppress("NOTHING_TO_INLINE")
+@Throws(XmlPullParserException::class)
+inline fun BinaryXmlPullParser.getAttributeValueOrThrow(name: String): String =
+ getAttributeValue(getAttributeIndexOrThrow(name))
+
+/**
+ * @see BinaryXmlPullParser.getAttributeBytesHex
+ */
+@Suppress("NOTHING_TO_INLINE")
+inline fun BinaryXmlPullParser.getAttributeBytesHex(name: String): ByteArray? =
+ getAttributeBytesHex(null, name, null)
+
+/**
+ * @see BinaryXmlPullParser.getAttributeBytesHex
+ */
+@Suppress("NOTHING_TO_INLINE")
+@Throws(XmlPullParserException::class)
+inline fun BinaryXmlPullParser.getAttributeBytesHexOrThrow(name: String): ByteArray =
+ getAttributeBytesHex(null, name)
+
+/**
+ * @see BinaryXmlPullParser.getAttributeBytesBase64
+ */
+@Suppress("NOTHING_TO_INLINE")
+inline fun BinaryXmlPullParser.getAttributeBytesBase64(name: String): ByteArray? =
+ getAttributeBytesBase64(null, name, null)
+
+/**
+ * @see BinaryXmlPullParser.getAttributeBytesBase64
+ */
+@Suppress("NOTHING_TO_INLINE")
+@Throws(XmlPullParserException::class)
+inline fun BinaryXmlPullParser.getAttributeBytesBase64OrThrow(name: String): ByteArray =
+ getAttributeBytesBase64(null, name)
+
+/**
+ * @see BinaryXmlPullParser.getAttributeInt
+ */
+@Suppress("NOTHING_TO_INLINE")
+inline fun BinaryXmlPullParser.getAttributeIntOrDefault(name: String, defaultValue: Int): Int =
+ getAttributeInt(null, name, defaultValue)
+
+/**
+ * @see BinaryXmlPullParser.getAttributeInt
+ */
+@Suppress("NOTHING_TO_INLINE")
+@Throws(XmlPullParserException::class)
+inline fun BinaryXmlPullParser.getAttributeIntOrThrow(name: String): Int =
+ getAttributeInt(null, name)
+
+/**
+ * @see BinaryXmlPullParser.getAttributeIntHex
+ */
+@Suppress("NOTHING_TO_INLINE")
+inline fun BinaryXmlPullParser.getAttributeIntHexOrDefault(name: String, defaultValue: Int): Int =
+ getAttributeIntHex(null, name, defaultValue)
+
+/**
+ * @see BinaryXmlPullParser.getAttributeIntHex
+ */
+@Suppress("NOTHING_TO_INLINE")
+@Throws(XmlPullParserException::class)
+inline fun BinaryXmlPullParser.getAttributeIntHexOrThrow(name: String): Int =
+ getAttributeIntHex(null, name)
+
+/**
+ * @see BinaryXmlPullParser.getAttributeLong
+ */
+@Suppress("NOTHING_TO_INLINE")
+inline fun BinaryXmlPullParser.getAttributeLongOrDefault(name: String, defaultValue: Long): Long =
+ getAttributeLong(null, name, defaultValue)
+
+/**
+ * @see BinaryXmlPullParser.getAttributeLong
+ */
+@Suppress("NOTHING_TO_INLINE")
+@Throws(XmlPullParserException::class)
+inline fun BinaryXmlPullParser.getAttributeLongOrThrow(name: String): Long =
+ getAttributeLong(null, name)
+
+/**
+ * @see BinaryXmlPullParser.getAttributeLongHex
+ */
+@Suppress("NOTHING_TO_INLINE")
+inline fun BinaryXmlPullParser.getAttributeLongHexOrDefault(
+ name: String,
+ defaultValue: Long
+): Long = getAttributeLongHex(null, name, defaultValue)
+
+/**
+ * @see BinaryXmlPullParser.getAttributeLongHex
+ */
+@Suppress("NOTHING_TO_INLINE")
+@Throws(XmlPullParserException::class)
+inline fun BinaryXmlPullParser.getAttributeLongHexOrThrow(name: String): Long =
+ getAttributeLongHex(null, name)
+
+/**
+ * @see BinaryXmlPullParser.getAttributeFloat
+ */
+@Suppress("NOTHING_TO_INLINE")
+inline fun BinaryXmlPullParser.getAttributeFloatOrDefault(
+ name: String,
+ defaultValue: Float
+): Float = getAttributeFloat(null, name, defaultValue)
+
+/**
+ * @see BinaryXmlPullParser.getAttributeFloat
+ */
+@Suppress("NOTHING_TO_INLINE")
+@Throws(XmlPullParserException::class)
+inline fun BinaryXmlPullParser.getAttributeFloatOrThrow(name: String): Float =
+ getAttributeFloat(null, name)
+
+/**
+ * @see BinaryXmlPullParser.getAttributeDouble
+ */
+@Suppress("NOTHING_TO_INLINE")
+inline fun BinaryXmlPullParser.getAttributeDoubleOrDefault(
+ name: String,
+ defaultValue: Double
+): Double = getAttributeDouble(null, name, defaultValue)
+
+/**
+ * @see BinaryXmlPullParser.getAttributeDouble
+ */
+@Suppress("NOTHING_TO_INLINE")
+@Throws(XmlPullParserException::class)
+inline fun BinaryXmlPullParser.getAttributeDoubleOrThrow(name: String): Double =
+ getAttributeDouble(null, name)
+
+/**
+ * @see BinaryXmlPullParser.getAttributeBoolean
+ */
+@Suppress("NOTHING_TO_INLINE")
+inline fun BinaryXmlPullParser.getAttributeBooleanOrDefault(
+ name: String,
+ defaultValue: Boolean
+): Boolean = getAttributeBoolean(null, name, defaultValue)
+
+/**
+ * @see BinaryXmlPullParser.getAttributeBoolean
+ */
+@Suppress("NOTHING_TO_INLINE")
+@Throws(XmlPullParserException::class)
+inline fun BinaryXmlPullParser.getAttributeBooleanOrThrow(name: String): Boolean =
+ getAttributeBoolean(null, name)
diff --git a/services/permission/java/com/android/server/permission/access/util/BinaryXmlSerializerExtensions.kt b/services/permission/java/com/android/server/permission/access/util/BinaryXmlSerializerExtensions.kt
new file mode 100644
index 000000000000..c8cd5866adbc
--- /dev/null
+++ b/services/permission/java/com/android/server/permission/access/util/BinaryXmlSerializerExtensions.kt
@@ -0,0 +1,262 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.permission.access.util
+
+import com.android.modules.utils.BinaryXmlSerializer
+import java.io.IOException
+import java.io.OutputStream
+
+/**
+ * Serialize content into [OutputStream] with [BinaryXmlSerializer].
+ */
+@Throws(IOException::class)
+inline fun OutputStream.serializeBinaryXml(block: BinaryXmlSerializer.() -> Unit) {
+ BinaryXmlSerializer().apply {
+ setOutput(this@serializeBinaryXml, null)
+ document(block)
+ }
+}
+
+/**
+ * Write a document with [BinaryXmlSerializer].
+ *
+ * @see BinaryXmlSerializer.startDocument
+ * @see BinaryXmlSerializer.endDocument
+ */
+@Throws(IOException::class)
+inline fun BinaryXmlSerializer.document(block: BinaryXmlSerializer.() -> Unit) {
+ startDocument(null, true)
+ block()
+ endDocument()
+}
+
+/**
+ * Write a tag with [BinaryXmlSerializer].
+ *
+ * @see BinaryXmlSerializer.startTag
+ * @see BinaryXmlSerializer.endTag
+ */
+@Throws(IOException::class)
+inline fun BinaryXmlSerializer.tag(name: String, block: BinaryXmlSerializer.() -> Unit) {
+ startTag(null, name)
+ block()
+ endTag(null, name)
+}
+
+/**
+ * @see BinaryXmlSerializer.attribute
+ */
+@Suppress("NOTHING_TO_INLINE")
+@Throws(IOException::class)
+inline fun BinaryXmlSerializer.attribute(name: String, value: String) {
+ attribute(null, name, value)
+}
+
+/**
+ * @see BinaryXmlSerializer.attributeInterned
+ */
+@Suppress("NOTHING_TO_INLINE")
+@Throws(IOException::class)
+inline fun BinaryXmlSerializer.attributeInterned(name: String, value: String) {
+ attributeInterned(null, name, value)
+}
+
+/**
+ * @see BinaryXmlSerializer.attributeBytesHex
+ */
+@Suppress("NOTHING_TO_INLINE")
+@Throws(IOException::class)
+inline fun BinaryXmlSerializer.attributeBytesHex(name: String, value: ByteArray) {
+ attributeBytesHex(null, name, value)
+}
+
+/**
+ * @see BinaryXmlSerializer.attributeBytesBase64
+ */
+@Suppress("NOTHING_TO_INLINE")
+@Throws(IOException::class)
+inline fun BinaryXmlSerializer.attributeBytesBase64(name: String, value: ByteArray) {
+ attributeBytesBase64(null, name, value)
+}
+
+/**
+ * @see BinaryXmlSerializer.attributeInt
+ */
+@Suppress("NOTHING_TO_INLINE")
+@Throws(IOException::class)
+inline fun BinaryXmlSerializer.attributeInt(name: String, value: Int) {
+ attributeInt(null, name, value)
+}
+
+/**
+ * @see BinaryXmlSerializer.attributeInt
+ */
+@Suppress("NOTHING_TO_INLINE")
+@Throws(IOException::class)
+inline fun BinaryXmlSerializer.attributeIntWithDefault(
+ name: String,
+ value: Int,
+ defaultValue: Int
+) {
+ if (value != defaultValue) {
+ attributeInt(null, name, value)
+ }
+}
+
+/**
+ * @see BinaryXmlSerializer.attributeIntHex
+ */
+@Suppress("NOTHING_TO_INLINE")
+@Throws(IOException::class)
+inline fun BinaryXmlSerializer.attributeIntHex(name: String, value: Int) {
+ attributeIntHex(null, name, value)
+}
+
+/**
+ * @see BinaryXmlSerializer.attributeIntHex
+ */
+@Suppress("NOTHING_TO_INLINE")
+@Throws(IOException::class)
+inline fun BinaryXmlSerializer.attributeIntHexWithDefault(
+ name: String,
+ value: Int,
+ defaultValue: Int
+) {
+ if (value != defaultValue) {
+ attributeIntHex(null, name, value)
+ }
+}
+
+/**
+ * @see BinaryXmlSerializer.attributeLong
+ */
+@Suppress("NOTHING_TO_INLINE")
+@Throws(IOException::class)
+inline fun BinaryXmlSerializer.attributeLong(name: String, value: Long) {
+ attributeLong(null, name, value)
+}
+
+/**
+ * @see BinaryXmlSerializer.attributeLong
+ */
+@Suppress("NOTHING_TO_INLINE")
+@Throws(IOException::class)
+inline fun BinaryXmlSerializer.attributeLongWithDefault(
+ name: String,
+ value: Long,
+ defaultValue: Long
+) {
+ if (value != defaultValue) {
+ attributeLong(null, name, value)
+ }
+}
+
+/**
+ * @see BinaryXmlSerializer.attributeLongHex
+ */
+@Suppress("NOTHING_TO_INLINE")
+@Throws(IOException::class)
+inline fun BinaryXmlSerializer.attributeLongHex(name: String, value: Long) {
+ attributeLongHex(null, name, value)
+}
+
+/**
+ * @see BinaryXmlSerializer.attributeLongHex
+ */
+@Suppress("NOTHING_TO_INLINE")
+@Throws(IOException::class)
+inline fun BinaryXmlSerializer.attributeLongHexWithDefault(
+ name: String,
+ value: Long,
+ defaultValue: Long
+) {
+ if (value != defaultValue) {
+ attributeLongHex(null, name, value)
+ }
+}
+
+/**
+ * @see BinaryXmlSerializer.attributeFloat
+ */
+@Suppress("NOTHING_TO_INLINE")
+@Throws(IOException::class)
+inline fun BinaryXmlSerializer.attributeFloat(name: String, value: Float) {
+ attributeFloat(null, name, value)
+}
+
+/**
+ * @see BinaryXmlSerializer.attributeFloat
+ */
+@Suppress("NOTHING_TO_INLINE")
+@Throws(IOException::class)
+inline fun BinaryXmlSerializer.attributeFloatWithDefault(
+ name: String,
+ value: Float,
+ defaultValue: Float
+) {
+ if (value != defaultValue) {
+ attributeFloat(null, name, value)
+ }
+}
+
+/**
+ * @see BinaryXmlSerializer.attributeDouble
+ */
+@Suppress("NOTHING_TO_INLINE")
+@Throws(IOException::class)
+inline fun BinaryXmlSerializer.attributeDouble(name: String, value: Double) {
+ attributeDouble(null, name, value)
+}
+
+/**
+ * @see BinaryXmlSerializer.attributeDouble
+ */
+@Suppress("NOTHING_TO_INLINE")
+@Throws(IOException::class)
+inline fun BinaryXmlSerializer.attributeDoubleWithDefault(
+ name: String,
+ value: Double,
+ defaultValue: Double
+) {
+ if (value != defaultValue) {
+ attributeDouble(null, name, value)
+ }
+}
+
+/**
+ * @see BinaryXmlSerializer.attributeBoolean
+ */
+@Suppress("NOTHING_TO_INLINE")
+@Throws(IOException::class)
+inline fun BinaryXmlSerializer.attributeBoolean(name: String, value: Boolean) {
+ attributeBoolean(null, name, value)
+}
+
+/**
+ * @see BinaryXmlSerializer.attributeBoolean
+ */
+@Suppress("NOTHING_TO_INLINE")
+@Throws(IOException::class)
+inline fun BinaryXmlSerializer.attributeBooleanWithDefault(
+ name: String,
+ value: Boolean,
+ defaultValue: Boolean
+) {
+ if (value != defaultValue) {
+ attributeBoolean(null, name, value)
+ }
+}
diff --git a/services/permission/java/com/android/server/permission/access/util/IntExtensions.kt b/services/permission/java/com/android/server/permission/access/util/IntExtensions.kt
new file mode 100644
index 000000000000..e71d7a129a9e
--- /dev/null
+++ b/services/permission/java/com/android/server/permission/access/util/IntExtensions.kt
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.permission.access.util
+
+fun Int.hasAnyBit(bits: Int): Boolean = this and bits != 0
+
+fun Int.hasBits(bits: Int): Boolean = this and bits == bits
+
+infix fun Int.andInv(other: Int): Int = this and other.inv()
diff --git a/services/permission/java/com/android/server/permission/access/util/PermissionApex.kt b/services/permission/java/com/android/server/permission/access/util/PermissionApex.kt
new file mode 100644
index 000000000000..e6b4e3e67b61
--- /dev/null
+++ b/services/permission/java/com/android/server/permission/access/util/PermissionApex.kt
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.permission.access.util
+
+import android.content.ApexEnvironment
+import android.os.UserHandle
+import java.io.File
+
+object PermissionApex {
+ private const val MODULE_NAME = "com.android.permission"
+
+ /**
+ * @see ApexEnvironment.getDeviceProtectedDataDir
+ */
+ val systemDataDirectory: File
+ get() = apexEnvironment.deviceProtectedDataDir
+
+ /**
+ * @see ApexEnvironment.getDeviceProtectedDataDirForUser
+ */
+ fun getUserDataDirectory(userId: Int): File =
+ apexEnvironment.getDeviceProtectedDataDirForUser(UserHandle.of(userId))
+
+ private val apexEnvironment: ApexEnvironment
+ get() = ApexEnvironment.getApexEnvironment(MODULE_NAME)
+}
diff --git a/services/robotests/backup/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java b/services/robotests/backup/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java
index 962a07ac6553..298cbf3e61b9 100644
--- a/services/robotests/backup/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java
+++ b/services/robotests/backup/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java
@@ -77,6 +77,8 @@ import android.app.backup.BackupAgent;
import android.app.backup.BackupDataInput;
import android.app.backup.BackupDataOutput;
import android.app.backup.BackupManager;
+import android.app.backup.BackupManagerMonitor;
+import android.app.backup.BackupRestoreEventLogger;
import android.app.backup.BackupTransport;
import android.app.backup.IBackupCallback;
import android.app.backup.IBackupManager;
@@ -89,6 +91,7 @@ import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.net.Uri;
+import android.os.Bundle;
import android.os.ConditionVariable;
import android.os.DeadObjectException;
import android.os.Handler;
@@ -100,6 +103,7 @@ import android.platform.test.annotations.Presubmit;
import android.util.Pair;
import com.android.internal.backup.IBackupTransport;
+import com.android.internal.infra.AndroidFuture;
import com.android.server.EventLogTags;
import com.android.server.LocalServices;
import com.android.server.backup.BackupRestoreTask;
@@ -131,6 +135,7 @@ import org.junit.After;
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;
@@ -1448,6 +1453,36 @@ public class KeyValueBackupTaskTest {
}
@Test
+ public void testRunTask_whenFinishBackupSucceeds_sendsAgentLogsToMonitor() throws Exception {
+ TransportMock transportMock = setUpInitializedTransport(mTransport);
+ AgentMock agentMock = setUpAgentWithData(PACKAGE_1);
+ KeyValueBackupTask task = createKeyValueBackupTask(transportMock, PACKAGE_1);
+ // Mock the agent logging and returning its logs.
+ List<BackupRestoreEventLogger.DataTypeResult> results = new ArrayList<>();
+ results.add(new BackupRestoreEventLogger.DataTypeResult("testDataTypeResult"));
+ doAnswer(
+ invocation -> {
+ AndroidFuture<List<BackupRestoreEventLogger.DataTypeResult>> in =
+ invocation.getArgument(0);
+ in.complete(results);
+ return null;
+ })
+ .when(agentMock.agentBinder)
+ .getLoggerResults(any());
+
+ runTask(task);
+
+ ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
+ verify(mMonitor).onEvent(bundleCaptor.capture());
+ Bundle eventBundle = bundleCaptor.getValue();
+ List<BackupRestoreEventLogger.DataTypeResult> sentLoggingResults =
+ eventBundle.getParcelableArrayList(
+ BackupManagerMonitor.EXTRA_LOG_AGENT_LOGGING_RESULTS,
+ BackupRestoreEventLogger.DataTypeResult.class);
+ assertThat(sentLoggingResults.get(0).getDataType()).isEqualTo("testDataTypeResult");
+ }
+
+ @Test
public void testRunTask_whenFinishBackupSucceeds_notifiesCorrectly() throws Exception {
TransportMock transportMock = setUpInitializedTransport(mTransport);
setUpAgentWithData(PACKAGE_1);
diff --git a/services/tests/PackageManagerServiceTests/TEST_MAPPING b/services/tests/PackageManagerServiceTests/TEST_MAPPING
index af0008c29aaf..fe27a3777ee8 100644
--- a/services/tests/PackageManagerServiceTests/TEST_MAPPING
+++ b/services/tests/PackageManagerServiceTests/TEST_MAPPING
@@ -2,11 +2,45 @@
"presubmit": [
{
"name": "AppEnumerationInternalTests"
+ },
+ {
+ "name": "PackageManagerServiceServerTests",
+ "options": [
+ {
+ "include-filter": "com.android.server.pm."
+ },
+ {
+ "include-annotation": "android.platform.test.annotations.Presubmit"
+ },
+ {
+ "exclude-annotation": "androidx.test.filters.FlakyTest"
+ },
+ {
+ "exclude-annotation": "org.junit.Ignore"
+ }
+ ]
}
],
"postsubmit": [
{
"name": "PackageManagerServiceHostTests"
+ },
+ {
+ "name": "PackageManagerServiceServerTests",
+ "options": [
+ {
+ "include-filter": "com.android.server.pm."
+ },
+ {
+ "include-annotation": "android.platform.test.annotations.Postsubmit"
+ },
+ {
+ "exclude-annotation": "androidx.test.filters.FlakyTest"
+ },
+ {
+ "exclude-annotation": "org.junit.Ignore"
+ }
+ ]
}
],
"imports": [
diff --git a/services/tests/servicestests/apks/Android.bp b/services/tests/PackageManagerServiceTests/apks/Android.bp
index 6c918064dbff..6c918064dbff 100644
--- a/services/tests/servicestests/apks/Android.bp
+++ b/services/tests/PackageManagerServiceTests/apks/Android.bp
diff --git a/services/tests/servicestests/apks/OWNERS b/services/tests/PackageManagerServiceTests/apks/OWNERS
index d825dfd7cf00..d825dfd7cf00 100644
--- a/services/tests/servicestests/apks/OWNERS
+++ b/services/tests/PackageManagerServiceTests/apks/OWNERS
diff --git a/services/tests/servicestests/apks/install-split-base/Android.bp b/services/tests/PackageManagerServiceTests/apks/install-split-base/Android.bp
index 39992f600b96..39992f600b96 100644
--- a/services/tests/servicestests/apks/install-split-base/Android.bp
+++ b/services/tests/PackageManagerServiceTests/apks/install-split-base/Android.bp
diff --git a/services/tests/servicestests/apks/install-split-base/AndroidManifest.xml b/services/tests/PackageManagerServiceTests/apks/install-split-base/AndroidManifest.xml
index ac563c6fef43..ac563c6fef43 100644
--- a/services/tests/servicestests/apks/install-split-base/AndroidManifest.xml
+++ b/services/tests/PackageManagerServiceTests/apks/install-split-base/AndroidManifest.xml
diff --git a/services/tests/servicestests/apks/install-split-base/src/com/google/android/dexapis/splitapp/BaseActivity.java b/services/tests/PackageManagerServiceTests/apks/install-split-base/src/com/google/android/dexapis/splitapp/BaseActivity.java
index cb5760ceef8e..cb5760ceef8e 100644
--- a/services/tests/servicestests/apks/install-split-base/src/com/google/android/dexapis/splitapp/BaseActivity.java
+++ b/services/tests/PackageManagerServiceTests/apks/install-split-base/src/com/google/android/dexapis/splitapp/BaseActivity.java
diff --git a/services/tests/servicestests/apks/install-split-feature-a/Android.bp b/services/tests/PackageManagerServiceTests/apks/install-split-feature-a/Android.bp
index ca7295e48fbc..ca7295e48fbc 100644
--- a/services/tests/servicestests/apks/install-split-feature-a/Android.bp
+++ b/services/tests/PackageManagerServiceTests/apks/install-split-feature-a/Android.bp
diff --git a/services/tests/servicestests/apks/install-split-feature-a/AndroidManifest.xml b/services/tests/PackageManagerServiceTests/apks/install-split-feature-a/AndroidManifest.xml
index 28c251cb914f..28c251cb914f 100644
--- a/services/tests/servicestests/apks/install-split-feature-a/AndroidManifest.xml
+++ b/services/tests/PackageManagerServiceTests/apks/install-split-feature-a/AndroidManifest.xml
diff --git a/services/tests/servicestests/apks/install-split-feature-a/src/com/google/android/dexapis/splitapp/feature_a/FeatureAActivity.java b/services/tests/PackageManagerServiceTests/apks/install-split-feature-a/src/com/google/android/dexapis/splitapp/feature_a/FeatureAActivity.java
index 0af5f893164c..0af5f893164c 100644
--- a/services/tests/servicestests/apks/install-split-feature-a/src/com/google/android/dexapis/splitapp/feature_a/FeatureAActivity.java
+++ b/services/tests/PackageManagerServiceTests/apks/install-split-feature-a/src/com/google/android/dexapis/splitapp/feature_a/FeatureAActivity.java
diff --git a/services/tests/servicestests/apks/install/Android.bp b/services/tests/PackageManagerServiceTests/apks/install/Android.bp
index 12175fdb7327..12175fdb7327 100644
--- a/services/tests/servicestests/apks/install/Android.bp
+++ b/services/tests/PackageManagerServiceTests/apks/install/Android.bp
diff --git a/services/tests/servicestests/apks/install/AndroidManifest.xml b/services/tests/PackageManagerServiceTests/apks/install/AndroidManifest.xml
index 60f1ba043c2c..60f1ba043c2c 100644
--- a/services/tests/servicestests/apks/install/AndroidManifest.xml
+++ b/services/tests/PackageManagerServiceTests/apks/install/AndroidManifest.xml
diff --git a/services/tests/servicestests/apks/install/res/values/strings.xml b/services/tests/PackageManagerServiceTests/apks/install/res/values/strings.xml
index 984152fb5fa7..984152fb5fa7 100644
--- a/services/tests/servicestests/apks/install/res/values/strings.xml
+++ b/services/tests/PackageManagerServiceTests/apks/install/res/values/strings.xml
diff --git a/services/tests/servicestests/apks/install_bad_dex/Android.bp b/services/tests/PackageManagerServiceTests/apks/install_bad_dex/Android.bp
index ad7566810a62..ad7566810a62 100644
--- a/services/tests/servicestests/apks/install_bad_dex/Android.bp
+++ b/services/tests/PackageManagerServiceTests/apks/install_bad_dex/Android.bp
diff --git a/services/tests/servicestests/apks/install_bad_dex/AndroidManifest.xml b/services/tests/PackageManagerServiceTests/apks/install_bad_dex/AndroidManifest.xml
index 76f0fe588f7b..76f0fe588f7b 100644
--- a/services/tests/servicestests/apks/install_bad_dex/AndroidManifest.xml
+++ b/services/tests/PackageManagerServiceTests/apks/install_bad_dex/AndroidManifest.xml
diff --git a/services/tests/servicestests/apks/install_bad_dex/classes.dex b/services/tests/PackageManagerServiceTests/apks/install_bad_dex/classes.dex
index 284b6d400e15..284b6d400e15 100644
--- a/services/tests/servicestests/apks/install_bad_dex/classes.dex
+++ b/services/tests/PackageManagerServiceTests/apks/install_bad_dex/classes.dex
diff --git a/services/tests/servicestests/apks/install_bad_dex/res/values/strings.xml b/services/tests/PackageManagerServiceTests/apks/install_bad_dex/res/values/strings.xml
index 984152fb5fa7..984152fb5fa7 100644
--- a/services/tests/servicestests/apks/install_bad_dex/res/values/strings.xml
+++ b/services/tests/PackageManagerServiceTests/apks/install_bad_dex/res/values/strings.xml
diff --git a/services/tests/servicestests/apks/install_bad_dex/src/com/android/frameworks/coretests/TestActivity.java b/services/tests/PackageManagerServiceTests/apks/install_bad_dex/src/com/android/frameworks/coretests/TestActivity.java
index 10d0551a3a6f..10d0551a3a6f 100644
--- a/services/tests/servicestests/apks/install_bad_dex/src/com/android/frameworks/coretests/TestActivity.java
+++ b/services/tests/PackageManagerServiceTests/apks/install_bad_dex/src/com/android/frameworks/coretests/TestActivity.java
diff --git a/services/tests/servicestests/apks/install_complete_package_info/Android.bp b/services/tests/PackageManagerServiceTests/apks/install_complete_package_info/Android.bp
index 98aa750231d7..98aa750231d7 100644
--- a/services/tests/servicestests/apks/install_complete_package_info/Android.bp
+++ b/services/tests/PackageManagerServiceTests/apks/install_complete_package_info/Android.bp
diff --git a/services/tests/servicestests/apks/install_complete_package_info/AndroidManifest.xml b/services/tests/PackageManagerServiceTests/apks/install_complete_package_info/AndroidManifest.xml
index 2c430e08c16a..2c430e08c16a 100644
--- a/services/tests/servicestests/apks/install_complete_package_info/AndroidManifest.xml
+++ b/services/tests/PackageManagerServiceTests/apks/install_complete_package_info/AndroidManifest.xml
diff --git a/services/tests/servicestests/apks/install_complete_package_info/src/com/android/frameworks/coretests/TestActivity.java b/services/tests/PackageManagerServiceTests/apks/install_complete_package_info/src/com/android/frameworks/coretests/TestActivity.java
index 10d0551a3a6f..10d0551a3a6f 100644
--- a/services/tests/servicestests/apks/install_complete_package_info/src/com/android/frameworks/coretests/TestActivity.java
+++ b/services/tests/PackageManagerServiceTests/apks/install_complete_package_info/src/com/android/frameworks/coretests/TestActivity.java
diff --git a/services/tests/servicestests/apks/install_complete_package_info/src/com/android/frameworks/coretests/TestProvider.java b/services/tests/PackageManagerServiceTests/apks/install_complete_package_info/src/com/android/frameworks/coretests/TestProvider.java
index 59f9f10c6efe..59f9f10c6efe 100644
--- a/services/tests/servicestests/apks/install_complete_package_info/src/com/android/frameworks/coretests/TestProvider.java
+++ b/services/tests/PackageManagerServiceTests/apks/install_complete_package_info/src/com/android/frameworks/coretests/TestProvider.java
diff --git a/services/tests/servicestests/apks/install_complete_package_info/src/com/android/frameworks/coretests/TestReceiver.java b/services/tests/PackageManagerServiceTests/apks/install_complete_package_info/src/com/android/frameworks/coretests/TestReceiver.java
index 21f6263a38bc..21f6263a38bc 100644
--- a/services/tests/servicestests/apks/install_complete_package_info/src/com/android/frameworks/coretests/TestReceiver.java
+++ b/services/tests/PackageManagerServiceTests/apks/install_complete_package_info/src/com/android/frameworks/coretests/TestReceiver.java
diff --git a/services/tests/servicestests/apks/install_complete_package_info/src/com/android/frameworks/coretests/TestService.java b/services/tests/PackageManagerServiceTests/apks/install_complete_package_info/src/com/android/frameworks/coretests/TestService.java
index b330e75308f9..b330e75308f9 100644
--- a/services/tests/servicestests/apks/install_complete_package_info/src/com/android/frameworks/coretests/TestService.java
+++ b/services/tests/PackageManagerServiceTests/apks/install_complete_package_info/src/com/android/frameworks/coretests/TestService.java
diff --git a/services/tests/servicestests/apks/install_decl_perm/Android.bp b/services/tests/PackageManagerServiceTests/apks/install_decl_perm/Android.bp
index ef65f5de6a1b..ef65f5de6a1b 100644
--- a/services/tests/servicestests/apks/install_decl_perm/Android.bp
+++ b/services/tests/PackageManagerServiceTests/apks/install_decl_perm/Android.bp
diff --git a/services/tests/servicestests/apks/install_decl_perm/AndroidManifest.xml b/services/tests/PackageManagerServiceTests/apks/install_decl_perm/AndroidManifest.xml
index 6a0c4215ce52..6a0c4215ce52 100644
--- a/services/tests/servicestests/apks/install_decl_perm/AndroidManifest.xml
+++ b/services/tests/PackageManagerServiceTests/apks/install_decl_perm/AndroidManifest.xml
diff --git a/services/tests/servicestests/apks/install_decl_perm/res/values/strings.xml b/services/tests/PackageManagerServiceTests/apks/install_decl_perm/res/values/strings.xml
index 984152fb5fa7..984152fb5fa7 100644
--- a/services/tests/servicestests/apks/install_decl_perm/res/values/strings.xml
+++ b/services/tests/PackageManagerServiceTests/apks/install_decl_perm/res/values/strings.xml
diff --git a/services/tests/servicestests/apks/install_intent_filters/Android.bp b/services/tests/PackageManagerServiceTests/apks/install_intent_filters/Android.bp
index 643824de785c..643824de785c 100644
--- a/services/tests/servicestests/apks/install_intent_filters/Android.bp
+++ b/services/tests/PackageManagerServiceTests/apks/install_intent_filters/Android.bp
diff --git a/services/tests/servicestests/apks/install_intent_filters/AndroidManifest.xml b/services/tests/PackageManagerServiceTests/apks/install_intent_filters/AndroidManifest.xml
index d60e19428f43..d60e19428f43 100644
--- a/services/tests/servicestests/apks/install_intent_filters/AndroidManifest.xml
+++ b/services/tests/PackageManagerServiceTests/apks/install_intent_filters/AndroidManifest.xml
diff --git a/services/tests/servicestests/apks/install_intent_filters/src/com/android/frameworks/servicestests/TestActivity.java b/services/tests/PackageManagerServiceTests/apks/install_intent_filters/src/com/android/frameworks/servicestests/TestActivity.java
index 08a19aacc21e..08a19aacc21e 100644
--- a/services/tests/servicestests/apks/install_intent_filters/src/com/android/frameworks/servicestests/TestActivity.java
+++ b/services/tests/PackageManagerServiceTests/apks/install_intent_filters/src/com/android/frameworks/servicestests/TestActivity.java
diff --git a/services/tests/servicestests/apks/install_loc_auto/Android.bp b/services/tests/PackageManagerServiceTests/apks/install_loc_auto/Android.bp
index 4e4ae526d0dc..4e4ae526d0dc 100644
--- a/services/tests/servicestests/apks/install_loc_auto/Android.bp
+++ b/services/tests/PackageManagerServiceTests/apks/install_loc_auto/Android.bp
diff --git a/services/tests/servicestests/apks/install_loc_auto/AndroidManifest.xml b/services/tests/PackageManagerServiceTests/apks/install_loc_auto/AndroidManifest.xml
index 5a903e2903d3..5a903e2903d3 100644
--- a/services/tests/servicestests/apks/install_loc_auto/AndroidManifest.xml
+++ b/services/tests/PackageManagerServiceTests/apks/install_loc_auto/AndroidManifest.xml
diff --git a/services/tests/servicestests/apks/install_loc_auto/res/values/strings.xml b/services/tests/PackageManagerServiceTests/apks/install_loc_auto/res/values/strings.xml
index 984152fb5fa7..984152fb5fa7 100644
--- a/services/tests/servicestests/apks/install_loc_auto/res/values/strings.xml
+++ b/services/tests/PackageManagerServiceTests/apks/install_loc_auto/res/values/strings.xml
diff --git a/services/tests/servicestests/apks/install_loc_internal/Android.bp b/services/tests/PackageManagerServiceTests/apks/install_loc_internal/Android.bp
index 39cdd5178a6d..39cdd5178a6d 100644
--- a/services/tests/servicestests/apks/install_loc_internal/Android.bp
+++ b/services/tests/PackageManagerServiceTests/apks/install_loc_internal/Android.bp
diff --git a/services/tests/servicestests/apks/install_loc_internal/AndroidManifest.xml b/services/tests/PackageManagerServiceTests/apks/install_loc_internal/AndroidManifest.xml
index 2568f3729523..2568f3729523 100644
--- a/services/tests/servicestests/apks/install_loc_internal/AndroidManifest.xml
+++ b/services/tests/PackageManagerServiceTests/apks/install_loc_internal/AndroidManifest.xml
diff --git a/services/tests/servicestests/apks/install_loc_internal/res/values/strings.xml b/services/tests/PackageManagerServiceTests/apks/install_loc_internal/res/values/strings.xml
index 984152fb5fa7..984152fb5fa7 100644
--- a/services/tests/servicestests/apks/install_loc_internal/res/values/strings.xml
+++ b/services/tests/PackageManagerServiceTests/apks/install_loc_internal/res/values/strings.xml
diff --git a/services/tests/servicestests/apks/install_loc_sdcard/Android.bp b/services/tests/PackageManagerServiceTests/apks/install_loc_sdcard/Android.bp
index ed82793ff6e6..ed82793ff6e6 100644
--- a/services/tests/servicestests/apks/install_loc_sdcard/Android.bp
+++ b/services/tests/PackageManagerServiceTests/apks/install_loc_sdcard/Android.bp
diff --git a/services/tests/servicestests/apks/install_loc_sdcard/AndroidManifest.xml b/services/tests/PackageManagerServiceTests/apks/install_loc_sdcard/AndroidManifest.xml
index 647f4e5f60ff..647f4e5f60ff 100644
--- a/services/tests/servicestests/apks/install_loc_sdcard/AndroidManifest.xml
+++ b/services/tests/PackageManagerServiceTests/apks/install_loc_sdcard/AndroidManifest.xml
diff --git a/services/tests/servicestests/apks/install_loc_sdcard/res/values/strings.xml b/services/tests/PackageManagerServiceTests/apks/install_loc_sdcard/res/values/strings.xml
index 984152fb5fa7..984152fb5fa7 100644
--- a/services/tests/servicestests/apks/install_loc_sdcard/res/values/strings.xml
+++ b/services/tests/PackageManagerServiceTests/apks/install_loc_sdcard/res/values/strings.xml
diff --git a/services/tests/servicestests/apks/install_loc_unspecified/Android.bp b/services/tests/PackageManagerServiceTests/apks/install_loc_unspecified/Android.bp
index fd15cb8e9f92..fd15cb8e9f92 100644
--- a/services/tests/servicestests/apks/install_loc_unspecified/Android.bp
+++ b/services/tests/PackageManagerServiceTests/apks/install_loc_unspecified/Android.bp
diff --git a/services/tests/servicestests/apks/install_loc_unspecified/AndroidManifest.xml b/services/tests/PackageManagerServiceTests/apks/install_loc_unspecified/AndroidManifest.xml
index 07b1eb3105e3..07b1eb3105e3 100644
--- a/services/tests/servicestests/apks/install_loc_unspecified/AndroidManifest.xml
+++ b/services/tests/PackageManagerServiceTests/apks/install_loc_unspecified/AndroidManifest.xml
diff --git a/services/tests/servicestests/apks/install_loc_unspecified/res/values/strings.xml b/services/tests/PackageManagerServiceTests/apks/install_loc_unspecified/res/values/strings.xml
index 984152fb5fa7..984152fb5fa7 100644
--- a/services/tests/servicestests/apks/install_loc_unspecified/res/values/strings.xml
+++ b/services/tests/PackageManagerServiceTests/apks/install_loc_unspecified/res/values/strings.xml
diff --git a/services/tests/servicestests/apks/install_use_perm_good/Android.bp b/services/tests/PackageManagerServiceTests/apks/install_use_perm_good/Android.bp
index 959ffbcc48b1..959ffbcc48b1 100644
--- a/services/tests/servicestests/apks/install_use_perm_good/Android.bp
+++ b/services/tests/PackageManagerServiceTests/apks/install_use_perm_good/Android.bp
diff --git a/services/tests/servicestests/apks/install_use_perm_good/AndroidManifest.xml b/services/tests/PackageManagerServiceTests/apks/install_use_perm_good/AndroidManifest.xml
index dadce7d55fba..dadce7d55fba 100644
--- a/services/tests/servicestests/apks/install_use_perm_good/AndroidManifest.xml
+++ b/services/tests/PackageManagerServiceTests/apks/install_use_perm_good/AndroidManifest.xml
diff --git a/services/tests/servicestests/apks/install_use_perm_good/res/values/strings.xml b/services/tests/PackageManagerServiceTests/apks/install_use_perm_good/res/values/strings.xml
index 984152fb5fa7..984152fb5fa7 100644
--- a/services/tests/servicestests/apks/install_use_perm_good/res/values/strings.xml
+++ b/services/tests/PackageManagerServiceTests/apks/install_use_perm_good/res/values/strings.xml
diff --git a/services/tests/servicestests/apks/install_uses_feature/Android.bp b/services/tests/PackageManagerServiceTests/apks/install_uses_feature/Android.bp
index fa25af4c5b30..fa25af4c5b30 100644
--- a/services/tests/servicestests/apks/install_uses_feature/Android.bp
+++ b/services/tests/PackageManagerServiceTests/apks/install_uses_feature/Android.bp
diff --git a/services/tests/servicestests/apks/install_uses_feature/AndroidManifest.xml b/services/tests/PackageManagerServiceTests/apks/install_uses_feature/AndroidManifest.xml
index ecbd7c423370..ecbd7c423370 100644
--- a/services/tests/servicestests/apks/install_uses_feature/AndroidManifest.xml
+++ b/services/tests/PackageManagerServiceTests/apks/install_uses_feature/AndroidManifest.xml
diff --git a/services/tests/servicestests/apks/install_uses_feature/res/values/strings.xml b/services/tests/PackageManagerServiceTests/apks/install_uses_feature/res/values/strings.xml
index 984152fb5fa7..984152fb5fa7 100644
--- a/services/tests/servicestests/apks/install_uses_feature/res/values/strings.xml
+++ b/services/tests/PackageManagerServiceTests/apks/install_uses_feature/res/values/strings.xml
diff --git a/services/tests/servicestests/apks/install_uses_sdk/Android.bp b/services/tests/PackageManagerServiceTests/apks/install_uses_sdk/Android.bp
index 289439561178..289439561178 100644
--- a/services/tests/servicestests/apks/install_uses_sdk/Android.bp
+++ b/services/tests/PackageManagerServiceTests/apks/install_uses_sdk/Android.bp
diff --git a/services/tests/servicestests/apks/install_uses_sdk/AndroidManifest-0.xml b/services/tests/PackageManagerServiceTests/apks/install_uses_sdk/AndroidManifest-0.xml
index 90b13d45fc05..90b13d45fc05 100644
--- a/services/tests/servicestests/apks/install_uses_sdk/AndroidManifest-0.xml
+++ b/services/tests/PackageManagerServiceTests/apks/install_uses_sdk/AndroidManifest-0.xml
diff --git a/services/tests/servicestests/apks/install_uses_sdk/AndroidManifest-q0-r0.xml b/services/tests/PackageManagerServiceTests/apks/install_uses_sdk/AndroidManifest-q0-r0.xml
index 2a3227660686..2a3227660686 100644
--- a/services/tests/servicestests/apks/install_uses_sdk/AndroidManifest-q0-r0.xml
+++ b/services/tests/PackageManagerServiceTests/apks/install_uses_sdk/AndroidManifest-q0-r0.xml
diff --git a/services/tests/servicestests/apks/install_uses_sdk/AndroidManifest-q0.xml b/services/tests/PackageManagerServiceTests/apks/install_uses_sdk/AndroidManifest-q0.xml
index c0e58674a226..c0e58674a226 100644
--- a/services/tests/servicestests/apks/install_uses_sdk/AndroidManifest-q0.xml
+++ b/services/tests/PackageManagerServiceTests/apks/install_uses_sdk/AndroidManifest-q0.xml
diff --git a/services/tests/servicestests/apks/install_uses_sdk/AndroidManifest-r-none.xml b/services/tests/PackageManagerServiceTests/apks/install_uses_sdk/AndroidManifest-r-none.xml
index c79c61c3dc32..c79c61c3dc32 100644
--- a/services/tests/servicestests/apks/install_uses_sdk/AndroidManifest-r-none.xml
+++ b/services/tests/PackageManagerServiceTests/apks/install_uses_sdk/AndroidManifest-r-none.xml
diff --git a/services/tests/servicestests/apks/install_uses_sdk/AndroidManifest-r0-s0.xml b/services/tests/PackageManagerServiceTests/apks/install_uses_sdk/AndroidManifest-r0-s0.xml
index af30915b4f0b..af30915b4f0b 100644
--- a/services/tests/servicestests/apks/install_uses_sdk/AndroidManifest-r0-s0.xml
+++ b/services/tests/PackageManagerServiceTests/apks/install_uses_sdk/AndroidManifest-r0-s0.xml
diff --git a/services/tests/servicestests/apks/install_uses_sdk/AndroidManifest-r0-s1000.xml b/services/tests/PackageManagerServiceTests/apks/install_uses_sdk/AndroidManifest-r0-s1000.xml
index 25743b87cabd..25743b87cabd 100644
--- a/services/tests/servicestests/apks/install_uses_sdk/AndroidManifest-r0-s1000.xml
+++ b/services/tests/PackageManagerServiceTests/apks/install_uses_sdk/AndroidManifest-r0-s1000.xml
diff --git a/services/tests/servicestests/apks/install_uses_sdk/AndroidManifest-r0.xml b/services/tests/PackageManagerServiceTests/apks/install_uses_sdk/AndroidManifest-r0.xml
index 2920b8641586..2920b8641586 100644
--- a/services/tests/servicestests/apks/install_uses_sdk/AndroidManifest-r0.xml
+++ b/services/tests/PackageManagerServiceTests/apks/install_uses_sdk/AndroidManifest-r0.xml
diff --git a/services/tests/servicestests/apks/install_uses_sdk/AndroidManifest-r1000.xml b/services/tests/PackageManagerServiceTests/apks/install_uses_sdk/AndroidManifest-r1000.xml
index 9bf925417e49..9bf925417e49 100644
--- a/services/tests/servicestests/apks/install_uses_sdk/AndroidManifest-r1000.xml
+++ b/services/tests/PackageManagerServiceTests/apks/install_uses_sdk/AndroidManifest-r1000.xml
diff --git a/services/tests/servicestests/apks/install_uses_sdk/res/values/strings.xml b/services/tests/PackageManagerServiceTests/apks/install_uses_sdk/res/values/strings.xml
index fcab92b84879..fcab92b84879 100644
--- a/services/tests/servicestests/apks/install_uses_sdk/res/values/strings.xml
+++ b/services/tests/PackageManagerServiceTests/apks/install_uses_sdk/res/values/strings.xml
diff --git a/services/tests/servicestests/apks/keyset/Android.bp b/services/tests/PackageManagerServiceTests/apks/keyset/Android.bp
index ce7919c9d0a8..ce7919c9d0a8 100644
--- a/services/tests/servicestests/apks/keyset/Android.bp
+++ b/services/tests/PackageManagerServiceTests/apks/keyset/Android.bp
diff --git a/services/tests/servicestests/apks/keyset/api_test/AndroidManifest.xml b/services/tests/PackageManagerServiceTests/apks/keyset/api_test/AndroidManifest.xml
index 2897bd5d0b55..2897bd5d0b55 100644
--- a/services/tests/servicestests/apks/keyset/api_test/AndroidManifest.xml
+++ b/services/tests/PackageManagerServiceTests/apks/keyset/api_test/AndroidManifest.xml
diff --git a/services/tests/servicestests/apks/keyset/permDef/AndroidManifest.xml b/services/tests/PackageManagerServiceTests/apks/keyset/permDef/AndroidManifest.xml
index 8f7ad4aec603..8f7ad4aec603 100644
--- a/services/tests/servicestests/apks/keyset/permDef/AndroidManifest.xml
+++ b/services/tests/PackageManagerServiceTests/apks/keyset/permDef/AndroidManifest.xml
diff --git a/services/tests/servicestests/apks/keyset/permUse/AndroidManifest.xml b/services/tests/PackageManagerServiceTests/apks/keyset/permUse/AndroidManifest.xml
index c56079f8d3cf..c56079f8d3cf 100644
--- a/services/tests/servicestests/apks/keyset/permUse/AndroidManifest.xml
+++ b/services/tests/PackageManagerServiceTests/apks/keyset/permUse/AndroidManifest.xml
diff --git a/services/tests/servicestests/apks/keyset/res/values/strings.xml b/services/tests/PackageManagerServiceTests/apks/keyset/res/values/strings.xml
index d811ec29ef19..d811ec29ef19 100644
--- a/services/tests/servicestests/apks/keyset/res/values/strings.xml
+++ b/services/tests/PackageManagerServiceTests/apks/keyset/res/values/strings.xml
diff --git a/services/tests/servicestests/apks/keyset/uA/AndroidManifest.xml b/services/tests/PackageManagerServiceTests/apks/keyset/uA/AndroidManifest.xml
index 8c440f54993b..8c440f54993b 100644
--- a/services/tests/servicestests/apks/keyset/uA/AndroidManifest.xml
+++ b/services/tests/PackageManagerServiceTests/apks/keyset/uA/AndroidManifest.xml
diff --git a/services/tests/servicestests/apks/keyset/uAB/AndroidManifest.xml b/services/tests/PackageManagerServiceTests/apks/keyset/uAB/AndroidManifest.xml
index 015c3ad2993e..015c3ad2993e 100644
--- a/services/tests/servicestests/apks/keyset/uAB/AndroidManifest.xml
+++ b/services/tests/PackageManagerServiceTests/apks/keyset/uAB/AndroidManifest.xml
diff --git a/services/tests/servicestests/apks/keyset/uAuB/AndroidManifest.xml b/services/tests/PackageManagerServiceTests/apks/keyset/uAuB/AndroidManifest.xml
index 9491dbeacc48..9491dbeacc48 100644
--- a/services/tests/servicestests/apks/keyset/uAuB/AndroidManifest.xml
+++ b/services/tests/PackageManagerServiceTests/apks/keyset/uAuB/AndroidManifest.xml
diff --git a/services/tests/servicestests/apks/keyset/uB/AndroidManifest.xml b/services/tests/PackageManagerServiceTests/apks/keyset/uB/AndroidManifest.xml
index f4918400f38b..f4918400f38b 100644
--- a/services/tests/servicestests/apks/keyset/uB/AndroidManifest.xml
+++ b/services/tests/PackageManagerServiceTests/apks/keyset/uB/AndroidManifest.xml
diff --git a/services/tests/servicestests/apks/keyset/uNone/AndroidManifest.xml b/services/tests/PackageManagerServiceTests/apks/keyset/uNone/AndroidManifest.xml
index 9c9ef2b2ea6f..9c9ef2b2ea6f 100644
--- a/services/tests/servicestests/apks/keyset/uNone/AndroidManifest.xml
+++ b/services/tests/PackageManagerServiceTests/apks/keyset/uNone/AndroidManifest.xml
diff --git a/services/tests/PackageManagerServiceTests/server/Android.bp b/services/tests/PackageManagerServiceTests/server/Android.bp
new file mode 100644
index 000000000000..ebd6b649c4a8
--- /dev/null
+++ b/services/tests/PackageManagerServiceTests/server/Android.bp
@@ -0,0 +1,159 @@
+//########################################################################
+// Build PackageManagerServiceServerTests package
+//########################################################################
+
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "frameworks_base_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["frameworks_base_license"],
+}
+
+android_test {
+ name: "PackageManagerServiceServerTests",
+
+ // Include all test java files.
+ srcs: [
+ "src/**/*.java",
+ "src/**/*.kt",
+ ],
+ static_libs: [
+ "frameworks-base-testutils",
+ "services.accessibility",
+ "services.appwidget",
+ "services.autofill",
+ "services.backup",
+ "services.companion",
+ "services.core",
+ "services.devicepolicy",
+ "services.net",
+ "services.people",
+ "services.usage",
+ "guava",
+ "guava-android-testlib",
+ "androidx.test.core",
+ "androidx.test.ext.truth",
+ "androidx.test.runner",
+ "androidx.test.rules",
+ "cts-wm-util",
+ "platform-compat-test-rules",
+ "mockito-target-minus-junit4",
+ "platform-test-annotations",
+ "ShortcutManagerTestUtils",
+ "truth-prebuilt",
+ "testables",
+ "ub-uiautomator",
+ "platformprotosnano",
+ "framework-protos",
+ "hamcrest-library",
+ "servicestests-core-utils",
+ "servicestests-dpm-utils",
+ "servicestests-utils",
+ "service-permission.impl",
+ "testng",
+ "truth-prebuilt",
+ "junit",
+ "junit-params",
+ "platform-compat-test-rules",
+ "ActivityContext",
+ "coretests-aidl",
+ ],
+
+ libs: [
+ "android.hardware.power-V1-java",
+ "android.hardware.tv.cec-V1.0-java",
+ "android.hardware.vibrator-V2-java",
+ "android.hidl.manager-V1.0-java",
+ "android.test.mock",
+ "android.test.base",
+ "android.test.runner",
+ ],
+
+ platform_apis: true,
+
+ test_suites: [
+ "device-tests",
+ "automotive-tests",
+ ],
+
+ certificate: "platform",
+
+ // These are not normally accessible from apps so they must be explicitly included.
+ jni_libs: [
+ "libbase",
+ "libbinder",
+ "libc++",
+ "libcutils",
+ "liblog",
+ "liblzma",
+ "libnativehelper",
+ "libpsi",
+ "libui",
+ "libunwindstack",
+ "libutils",
+ "netd_aidl_interface-V5-cpp",
+ ],
+
+ dxflags: ["--multi-dex"],
+
+ java_resources: [
+ ":PackageParserTestApp1",
+ ":PackageParserTestApp2",
+ ":PackageParserTestApp3",
+ ":PackageParserTestApp4",
+ ":PackageParserTestApp5",
+ ":PackageParserTestApp6",
+ ],
+ resource_zips: [":PackageManagerServiceServerTests_apks_as_resources"],
+}
+
+// Rules to copy all the test apks to the intermediate raw resource directory
+java_genrule {
+ name: "PackageManagerServiceServerTests_apks_as_resources",
+ srcs: [
+ ":FrameworksServicesTests_install",
+ ":FrameworksServicesTests_install_bad_dex",
+ ":FrameworksServicesTests_install_complete_package_info",
+ ":FrameworksServicesTests_install_decl_perm",
+ ":FrameworksServicesTests_install_intent_filters",
+ ":FrameworksServicesTests_install_loc_auto",
+ ":FrameworksServicesTests_install_loc_internal",
+ ":FrameworksServicesTests_install_loc_sdcard",
+ ":FrameworksServicesTests_install_loc_unspecified",
+ ":FrameworksServicesTests_install_use_perm_good",
+ ":FrameworksServicesTests_install_uses_feature",
+ ":FrameworksServicesTests_install_uses_sdk_0",
+ ":FrameworksServicesTests_install_uses_sdk_q0",
+ ":FrameworksServicesTests_install_uses_sdk_q0_r0",
+ ":FrameworksServicesTests_install_uses_sdk_r0",
+ ":FrameworksServicesTests_install_uses_sdk_r1000",
+ ":FrameworksServicesTests_install_uses_sdk_r_none",
+ ":FrameworksServicesTests_install_uses_sdk_r0_s0",
+ ":FrameworksServicesTests_install_uses_sdk_r0_s1000",
+ ":FrameworksServicesTests_keyset_permdef_sa_unone",
+ ":FrameworksServicesTests_keyset_permuse_sa_ua_ub",
+ ":FrameworksServicesTests_keyset_permuse_sb_ua_ub",
+ ":FrameworksServicesTests_keyset_sa_ua",
+ ":FrameworksServicesTests_keyset_sa_ua_ub",
+ ":FrameworksServicesTests_keyset_sa_uab",
+ ":FrameworksServicesTests_keyset_sa_ub",
+ ":FrameworksServicesTests_keyset_sa_unone",
+ ":FrameworksServicesTests_keyset_sab_ua",
+ ":FrameworksServicesTests_keyset_sau_ub",
+ ":FrameworksServicesTests_keyset_sb_ua",
+ ":FrameworksServicesTests_keyset_sb_ub",
+ ":FrameworksServicesTests_keyset_splat_api",
+ ":FrameworksServicesTests_keyset_splata_api",
+ ],
+ out: ["PackageManagerServiceServerTests_apks_as_resources.res.zip"],
+ tools: ["soong_zip"],
+
+ cmd: "mkdir -p $(genDir)/res/raw && " +
+ "for i in $(in); do " +
+ " x=$${i##*FrameworksCoreTests_}; cp $$i $(genDir)/res/raw/$${x%.apk};" +
+ " x=$${i##*FrameworksServicesTests_}; cp $$i $(genDir)/res/raw/$${x%.apk};" +
+ "done && " +
+ "$(location soong_zip) -o $(out) -C $(genDir)/res -D $(genDir)/res",
+}
diff --git a/services/tests/PackageManagerServiceTests/server/AndroidManifest.xml b/services/tests/PackageManagerServiceTests/server/AndroidManifest.xml
new file mode 100644
index 000000000000..c383197792b0
--- /dev/null
+++ b/services/tests/PackageManagerServiceTests/server/AndroidManifest.xml
@@ -0,0 +1,126 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2022 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.server.pm.test.service.server">
+
+ <uses-permission android:name="android.permission.READ_LOGS"/>
+ <uses-permission android:name="android.permission.ACCESS_VR_MANAGER"/>
+ <uses-permission android:name="android.permission.ACCOUNT_MANAGER"/>
+ <uses-permission android:name="android.permission.WRITE_SETTINGS"/>
+ <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS"/>
+ <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
+ <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
+ <uses-permission android:name="android.permission.BROADCAST_STICKY"/>
+ <uses-permission android:name="android.permission.UPDATE_DEVICE_STATS"/>
+ <uses-permission android:name="android.permission.MANAGE_APP_TOKENS"/>
+ <uses-permission android:name="android.permission.WAKE_LOCK"/>
+ <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS"/>
+ <uses-permission android:name="android.permission.REAL_GET_TASKS"/>
+ <uses-permission android:name="android.permission.GET_DETAILED_TASKS"/>
+ <uses-permission android:name="android.permission.REORDER_TASKS"/>
+ <uses-permission android:name="android.permission.MANAGE_NETWORK_POLICY"/>
+ <uses-permission android:name="android.permission.READ_NETWORK_USAGE_HISTORY"/>
+ <uses-permission android:name="android.permission.OBSERVE_NETWORK_POLICY"/>
+ <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
+ <uses-permission android:name="android.permission.MANAGE_USERS"/>
+ <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL"/>
+ <uses-permission android:name="android.permission.MANAGE_DEVICE_ADMINS"/>
+ <uses-permission android:name="android.permission.MODIFY_PHONE_STATE"/>
+ <uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE"/>
+ <uses-permission android:name="android.permission.INTERNET"/>
+ <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
+ <uses-permission android:name="android.permission.PACKET_KEEPALIVE_OFFLOAD"/>
+ <uses-permission android:name="android.permission.GET_INTENT_SENDER_INTENT"/>
+ <uses-permission android:name="android.permission.MANAGE_ACTIVITY_TASKS"/>
+ <uses-permission android:name="android.permission.INSTALL_PACKAGES"/>
+ <uses-permission android:name="android.permission.CHANGE_CONFIGURATION"/>
+ <uses-permission android:name="android.permission.CHANGE_COMPONENT_ENABLED_STATE"/>
+ <uses-permission android:name="android.permission.DELETE_PACKAGES"/>
+ <uses-permission android:name="android.permission.GET_APP_OPS_STATS"/>
+ <uses-permission android:name="android.permission.UPDATE_APP_OPS_STATS"/>
+ <uses-permission android:name="android.permission.MANAGE_APP_OPS_MODES"/>
+ <uses-permission android:name="android.permission.DEVICE_POWER"/>
+ <uses-permission android:name="android.permission.FORCE_STOP_PACKAGES"/>
+ <uses-permission android:name="android.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST"/>
+ <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
+ <uses-permission android:name="android.permission.STATUS_BAR"/>
+ <uses-permission android:name="android.permission.STATUS_BAR_SERVICE"/>
+ <uses-permission android:name="android.permission.ACCESS_SURFACE_FLINGER"/>
+ <uses-permission android:name="android.permission.READ_FRAME_BUFFER"/>
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
+ <uses-permission android:name="android.permission.STORAGE_INTERNAL"/>
+ <uses-permission android:name="android.permission.WATCH_APPOPS"/>
+ <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
+ <uses-permission android:name="android.permission.SUSPEND_APPS"/>
+ <uses-permission android:name="android.permission.LOG_COMPAT_CHANGE"/>
+ <uses-permission android:name="android.permission.READ_COMPAT_CHANGE_CONFIG"/>
+ <uses-permission android:name="android.permission.CONTROL_KEYGUARD"/>
+ <uses-permission android:name="android.permission.MANAGE_BIND_INSTANT_SERVICE"/>
+ <uses-permission android:name="android.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS"/>
+ <uses-permission android:name="android.permission.CONTROL_DISPLAY_BRIGHTNESS"/>
+ <uses-permission android:name="android.permission.CONFIGURE_DISPLAY_BRIGHTNESS"/>
+ <uses-permission android:name="android.permission.READ_DEVICE_CONFIG"/>
+ <uses-permission android:name="android.permission.WRITE_DEVICE_CONFIG"/>
+ <uses-permission android:name="android.permission.HARDWARE_TEST"/>
+ <uses-permission android:name="android.permission.BLUETOOTH"/>
+ <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
+ <uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE"/>
+ <uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>
+ <uses-permission android:name="android.permission.BLUETOOTH_SCAN"/>
+ <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"/>
+ <uses-permission android:name="android.permission.DUMP"/>
+ <uses-permission android:name="android.permission.READ_DREAM_STATE"/>
+ <uses-permission android:name="android.permission.READ_DREAM_SUPPRESSION"/>
+ <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-permission android:name="android.permission.VIBRATE"/>
+ <uses-permission android:name="android.permission.ACCESS_VIBRATOR_STATE"/>
+ <uses-permission android:name="android.permission.VIBRATE_ALWAYS_ON"/>
+ <uses-permission android:name="android.permission.CONTROL_DEVICE_STATE"/>
+ <uses-permission android:name="android.permission.READ_PROJECTION_STATE"/>
+ <uses-permission android:name="android.permission.KILL_UID"/>
+ <uses-permission android:name="android.permission.MAINLINE_NETWORK_STACK"/>
+ <uses-permission
+ android:name="android.permission.OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD"/>
+ <uses-permission android:name="android.permission.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY" />
+ <uses-permission android:name="android.permission.READ_NEARBY_STREAMING_POLICY" />
+ <uses-permission android:name="android.permission.MODIFY_AUDIO_ROUTING" />
+ <uses-permission android:name="android.permission.PACKAGE_VERIFICATION_AGENT" />
+ <uses-permission android:name="android.permission.OBSERVE_ROLE_HOLDERS" />
+ <uses-permission android:name="android.permission.BATTERY_STATS" />
+
+ <!-- Uses API introduced in O (26) -->
+ <uses-sdk android:minSdkVersion="1" android:targetSdkVersion="26"/>
+
+ <application android:testOnly="true" android:debuggable="true">
+ <uses-library android:name="android.test.runner"/>
+ </application>
+
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="com.android.server.pm.test.service.server"
+ android:label="Package Manager Service Tests"/>
+
+ <key-sets>
+ <key-set android:name="A" >
+ <public-key android:name="keyA"
+ android:value="MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsMpNthdOxud7roPDZMMomOqXgJJdRfIWpkKEqmC61Mv+Nf6QY3TorEwJeghjSmqj7IbBKrtvfQq4E2XJO1HuspmQO4Ng2gvn+r+6EwNfKc9k55d6s+27SR867jKurBbHNtZMG+tjL1yH4r+tNzcuJCsgyAFqLmxFdcxEwzNvREyRpoYc5RDR0mmTwkMCUhJ6CId1EYEKiCEdNzxv+fWPEb21u+/MWpleGCILs8kglRVb2q/WOzAAvGr4FY5plfaE6N+lr7+UschQ+aMi1+uqewo2o0qPFVmZP5hnwj55K4UMzu/NhhDqQQsX4cSGES1KgHo5MTqRqZjN/I7emw5pFQIDAQAB"/>
+ </key-set>
+ <upgrade-key-set android:name="A"/>
+ </key-sets>
+</manifest>
diff --git a/services/tests/PackageManagerServiceTests/server/AndroidTest.xml b/services/tests/PackageManagerServiceTests/server/AndroidTest.xml
new file mode 100644
index 000000000000..869d60ead3a1
--- /dev/null
+++ b/services/tests/PackageManagerServiceTests/server/AndroidTest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT 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 Frameworks Services Tests.">
+ <option name="test-suite-tag" value="apct" />
+ <option name="test-suite-tag" value="apct-instrumentation" />
+
+ <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+ <option name="cleanup-apks" value="true" />
+ <option name="install-arg" value="-t" />
+ <option name="test-file-name" value="PackageManagerServiceServerTests.apk" />
+ </target_preparer>
+
+ <option name="test-tag" value="PackageManagerServiceServerTests" />
+ <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+ <option name="package" value="com.android.server.pm.test.service.server" />
+ <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
+ <option name="hidden-api-checks" value="false"/>
+ <option name="exclude-annotation" value="androidx.test.filters.FlakyTest" />
+ </test>
+</configuration>
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256-lineage-2-signers b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/certs/ec-p256-lineage-2-signers
index 509ea3b2e61d..509ea3b2e61d 100644
--- a/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256-lineage-2-signers
+++ b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/certs/ec-p256-lineage-2-signers
Binary files differ
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256-lineage-3-signers b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/certs/ec-p256-lineage-3-signers
index bee71c0189fa..bee71c0189fa 100644
--- a/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256-lineage-3-signers
+++ b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/certs/ec-p256-lineage-3-signers
Binary files differ
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256.pk8 b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/certs/ec-p256.pk8
index f781c3083e54..f781c3083e54 100644
--- a/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256.pk8
+++ b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/certs/ec-p256.pk8
Binary files differ
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256.x509.der b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/certs/ec-p256.x509.der
index e611e3d9383f..e611e3d9383f 100644
--- a/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256.x509.der
+++ b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/certs/ec-p256.x509.der
Binary files differ
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256_2.pk8 b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/certs/ec-p256_2.pk8
index 5e73f27847d2..5e73f27847d2 100644
--- a/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256_2.pk8
+++ b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/certs/ec-p256_2.pk8
Binary files differ
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256_2.x509.der b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/certs/ec-p256_2.x509.der
index 7723beab5715..7723beab5715 100644
--- a/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256_2.x509.der
+++ b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/certs/ec-p256_2.x509.der
Binary files differ
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256_3.pk8 b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/certs/ec-p256_3.pk8
index d7309dd3f024..d7309dd3f024 100644
--- a/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256_3.pk8
+++ b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/certs/ec-p256_3.pk8
Binary files differ
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256_3.x509.der b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/certs/ec-p256_3.x509.der
index cc82af9c0310..cc82af9c0310 100644
--- a/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256_3.x509.der
+++ b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/certs/ec-p256_3.x509.der
Binary files differ
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/README b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/README
index 43d5bb8864df..43d5bb8864df 100644
--- a/services/tests/servicestests/assets/PackageSignaturesTest/xml/README
+++ b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/README
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-extra-cert-tag.xml b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/one-signer-extra-cert-tag.xml
index 4d55bad7cc90..4d55bad7cc90 100644
--- a/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-extra-cert-tag.xml
+++ b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/one-signer-extra-cert-tag.xml
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-invalid-cert-index.xml b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/one-signer-invalid-cert-index.xml
index f7882b1389b0..f7882b1389b0 100644
--- a/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-invalid-cert-index.xml
+++ b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/one-signer-invalid-cert-index.xml
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-invalid-cert-key.xml b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/one-signer-invalid-cert-key.xml
index af2c293c0f4a..af2c293c0f4a 100644
--- a/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-invalid-cert-key.xml
+++ b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/one-signer-invalid-cert-key.xml
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-invalid-public-key-cert-key.xml b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/one-signer-invalid-public-key-cert-key.xml
index 893402d1004e..893402d1004e 100644
--- a/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-invalid-public-key-cert-key.xml
+++ b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/one-signer-invalid-public-key-cert-key.xml
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-invalid-tag.xml b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/one-signer-invalid-tag.xml
index 1f81dacc2727..1f81dacc2727 100644
--- a/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-invalid-tag.xml
+++ b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/one-signer-invalid-tag.xml
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-missing-cert-index.xml b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/one-signer-missing-cert-index.xml
index c38e4d94a6d0..c38e4d94a6d0 100644
--- a/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-missing-cert-index.xml
+++ b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/one-signer-missing-cert-index.xml
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-missing-cert-key.xml b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/one-signer-missing-cert-key.xml
index 8e8cbcf7174e..8e8cbcf7174e 100644
--- a/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-missing-cert-key.xml
+++ b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/one-signer-missing-cert-key.xml
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-missing-cert-tag.xml b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/one-signer-missing-cert-tag.xml
index 57e96a8db0a0..57e96a8db0a0 100644
--- a/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-missing-cert-tag.xml
+++ b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/one-signer-missing-cert-tag.xml
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-missing-scheme-version.xml b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/one-signer-missing-scheme-version.xml
index d9f7a5f29d22..d9f7a5f29d22 100644
--- a/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-missing-scheme-version.xml
+++ b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/one-signer-missing-scheme-version.xml
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-missing-sigs-count.xml b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/one-signer-missing-sigs-count.xml
index 4eefdd9dbbbb..4eefdd9dbbbb 100644
--- a/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-missing-sigs-count.xml
+++ b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/one-signer-missing-sigs-count.xml
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-previous-cert.xml b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/one-signer-previous-cert.xml
index 2aeeb7124be9..2aeeb7124be9 100644
--- a/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-previous-cert.xml
+++ b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/one-signer-previous-cert.xml
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer.xml b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/one-signer.xml
index 14471f84cb1b..14471f84cb1b 100644
--- a/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer.xml
+++ b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/one-signer.xml
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/three-signers-in-lineage-invalid-pastSigs-count.xml b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/three-signers-in-lineage-invalid-pastSigs-count.xml
index 2b2e383cd098..2b2e383cd098 100644
--- a/services/tests/servicestests/assets/PackageSignaturesTest/xml/three-signers-in-lineage-invalid-pastSigs-count.xml
+++ b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/three-signers-in-lineage-invalid-pastSigs-count.xml
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/three-signers-in-lineage-missing-pastSigs-cert-tag.xml b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/three-signers-in-lineage-missing-pastSigs-cert-tag.xml
index f992104ba00d..f992104ba00d 100644
--- a/services/tests/servicestests/assets/PackageSignaturesTest/xml/three-signers-in-lineage-missing-pastSigs-cert-tag.xml
+++ b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/three-signers-in-lineage-missing-pastSigs-cert-tag.xml
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/three-signers-in-lineage-missing-pastSigs-count.xml b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/three-signers-in-lineage-missing-pastSigs-count.xml
index 6ef0fe5c38da..6ef0fe5c38da 100644
--- a/services/tests/servicestests/assets/PackageSignaturesTest/xml/three-signers-in-lineage-missing-pastSigs-count.xml
+++ b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/three-signers-in-lineage-missing-pastSigs-count.xml
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/three-signers-in-lineage-missing-scheme-version.xml b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/three-signers-in-lineage-missing-scheme-version.xml
index d98573dbc08c..d98573dbc08c 100644
--- a/services/tests/servicestests/assets/PackageSignaturesTest/xml/three-signers-in-lineage-missing-scheme-version.xml
+++ b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/three-signers-in-lineage-missing-scheme-version.xml
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/three-signers-in-lineage.xml b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/three-signers-in-lineage.xml
index 2ccf5060f9e2..2ccf5060f9e2 100644
--- a/services/tests/servicestests/assets/PackageSignaturesTest/xml/three-signers-in-lineage.xml
+++ b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/three-signers-in-lineage.xml
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-invalid-certs-flags.xml b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/two-signers-in-lineage-invalid-certs-flags.xml
index 6d567e994d91..6d567e994d91 100644
--- a/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-invalid-certs-flags.xml
+++ b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/two-signers-in-lineage-invalid-certs-flags.xml
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-invalid-pastSigs-cert-index.xml b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/two-signers-in-lineage-invalid-pastSigs-cert-index.xml
index a2146b7b63ec..a2146b7b63ec 100644
--- a/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-invalid-pastSigs-cert-index.xml
+++ b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/two-signers-in-lineage-invalid-pastSigs-cert-index.xml
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-missing-certs-flags.xml b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/two-signers-in-lineage-missing-certs-flags.xml
index 90a4a8472e40..90a4a8472e40 100644
--- a/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-missing-certs-flags.xml
+++ b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/two-signers-in-lineage-missing-certs-flags.xml
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-missing-pastSigs-cert-index.xml b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/two-signers-in-lineage-missing-pastSigs-cert-index.xml
index 6525e48061ea..6525e48061ea 100644
--- a/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-missing-pastSigs-cert-index.xml
+++ b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/two-signers-in-lineage-missing-pastSigs-cert-index.xml
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-multiple-pastSigs-tags.xml b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/two-signers-in-lineage-multiple-pastSigs-tags.xml
index e06892c6f7da..e06892c6f7da 100644
--- a/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-multiple-pastSigs-tags.xml
+++ b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/two-signers-in-lineage-multiple-pastSigs-tags.xml
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-no-caps.xml b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/two-signers-in-lineage-no-caps.xml
index 8081d2e6d78d..8081d2e6d78d 100644
--- a/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-no-caps.xml
+++ b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/two-signers-in-lineage-no-caps.xml
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-undefined-pastSigs-index.xml b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/two-signers-in-lineage-undefined-pastSigs-index.xml
index 127000a160da..127000a160da 100644
--- a/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-undefined-pastSigs-index.xml
+++ b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/two-signers-in-lineage-undefined-pastSigs-index.xml
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage.xml b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/two-signers-in-lineage.xml
index 6097ea6d7bd0..6097ea6d7bd0 100644
--- a/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage.xml
+++ b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/two-signers-in-lineage.xml
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-v1v2-missing-cert-tag.xml b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/two-signers-v1v2-missing-cert-tag.xml
index 6ed3be8615cb..6ed3be8615cb 100644
--- a/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-v1v2-missing-cert-tag.xml
+++ b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/two-signers-v1v2-missing-cert-tag.xml
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-v1v2.xml b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/two-signers-v1v2.xml
index ee4c4ebde3a9..ee4c4ebde3a9 100644
--- a/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-v1v2.xml
+++ b/services/tests/PackageManagerServiceTests/server/assets/PackageSignaturesTest/xml/two-signers-v1v2.xml
diff --git a/services/tests/servicestests/res/raw/PackageParsingTestAppEmptyActionSdkQ.apk b/services/tests/PackageManagerServiceTests/server/res/raw/PackageParsingTestAppEmptyActionSdkQ.apk
index 841fcebd6c1f..841fcebd6c1f 100644
--- a/services/tests/servicestests/res/raw/PackageParsingTestAppEmptyActionSdkQ.apk
+++ b/services/tests/PackageManagerServiceTests/server/res/raw/PackageParsingTestAppEmptyActionSdkQ.apk
Binary files differ
diff --git a/services/tests/servicestests/res/raw/PackageParsingTestAppEmptyActionSdkR.apk b/services/tests/PackageManagerServiceTests/server/res/raw/PackageParsingTestAppEmptyActionSdkR.apk
index 3520650215ef..3520650215ef 100644
--- a/services/tests/servicestests/res/raw/PackageParsingTestAppEmptyActionSdkR.apk
+++ b/services/tests/PackageManagerServiceTests/server/res/raw/PackageParsingTestAppEmptyActionSdkR.apk
Binary files differ
diff --git a/services/tests/servicestests/res/raw/PackageParsingTestAppEmptyCategorySdkQ.apk b/services/tests/PackageManagerServiceTests/server/res/raw/PackageParsingTestAppEmptyCategorySdkQ.apk
index 6774d5f0a452..6774d5f0a452 100644
--- a/services/tests/servicestests/res/raw/PackageParsingTestAppEmptyCategorySdkQ.apk
+++ b/services/tests/PackageManagerServiceTests/server/res/raw/PackageParsingTestAppEmptyCategorySdkQ.apk
Binary files differ
diff --git a/services/tests/servicestests/res/raw/PackageParsingTestAppEmptyCategorySdkR.apk b/services/tests/PackageManagerServiceTests/server/res/raw/PackageParsingTestAppEmptyCategorySdkR.apk
index 23efb1977bbc..23efb1977bbc 100644
--- a/services/tests/servicestests/res/raw/PackageParsingTestAppEmptyCategorySdkR.apk
+++ b/services/tests/PackageManagerServiceTests/server/res/raw/PackageParsingTestAppEmptyCategorySdkR.apk
Binary files differ
diff --git a/services/tests/servicestests/res/raw/PackageParsingTestAppMissingAppSdkQ.apk b/services/tests/PackageManagerServiceTests/server/res/raw/PackageParsingTestAppMissingAppSdkQ.apk
index f684f8691151..f684f8691151 100644
--- a/services/tests/servicestests/res/raw/PackageParsingTestAppMissingAppSdkQ.apk
+++ b/services/tests/PackageManagerServiceTests/server/res/raw/PackageParsingTestAppMissingAppSdkQ.apk
Binary files differ
diff --git a/services/tests/servicestests/res/raw/PackageParsingTestAppMissingAppSdkR.apk b/services/tests/PackageManagerServiceTests/server/res/raw/PackageParsingTestAppMissingAppSdkR.apk
index 491c56cef86b..491c56cef86b 100644
--- a/services/tests/servicestests/res/raw/PackageParsingTestAppMissingAppSdkR.apk
+++ b/services/tests/PackageManagerServiceTests/server/res/raw/PackageParsingTestAppMissingAppSdkR.apk
Binary files differ
diff --git a/services/tests/servicestests/res/raw/install_app1_cert1 b/services/tests/PackageManagerServiceTests/server/res/raw/install_app1_cert1
index f880c0b1126b..f880c0b1126b 100644
--- a/services/tests/servicestests/res/raw/install_app1_cert1
+++ b/services/tests/PackageManagerServiceTests/server/res/raw/install_app1_cert1
Binary files differ
diff --git a/services/tests/servicestests/res/raw/install_app1_cert1_cert2 b/services/tests/PackageManagerServiceTests/server/res/raw/install_app1_cert1_cert2
index ed89fbb2eb35..ed89fbb2eb35 100644
--- a/services/tests/servicestests/res/raw/install_app1_cert1_cert2
+++ b/services/tests/PackageManagerServiceTests/server/res/raw/install_app1_cert1_cert2
Binary files differ
diff --git a/services/tests/servicestests/res/raw/install_app1_cert2 b/services/tests/PackageManagerServiceTests/server/res/raw/install_app1_cert2
index 5551c7ebff07..5551c7ebff07 100644
--- a/services/tests/servicestests/res/raw/install_app1_cert2
+++ b/services/tests/PackageManagerServiceTests/server/res/raw/install_app1_cert2
Binary files differ
diff --git a/services/tests/servicestests/res/raw/install_app1_cert3 b/services/tests/PackageManagerServiceTests/server/res/raw/install_app1_cert3
index 0d1a4dcce854..0d1a4dcce854 100644
--- a/services/tests/servicestests/res/raw/install_app1_cert3
+++ b/services/tests/PackageManagerServiceTests/server/res/raw/install_app1_cert3
Binary files differ
diff --git a/services/tests/servicestests/res/raw/install_app1_cert3_cert4 b/services/tests/PackageManagerServiceTests/server/res/raw/install_app1_cert3_cert4
index 29ff3b6c5971..29ff3b6c5971 100644
--- a/services/tests/servicestests/res/raw/install_app1_cert3_cert4
+++ b/services/tests/PackageManagerServiceTests/server/res/raw/install_app1_cert3_cert4
Binary files differ
diff --git a/services/tests/servicestests/res/raw/install_app1_cert5 b/services/tests/PackageManagerServiceTests/server/res/raw/install_app1_cert5
index 138b6113ea6b..138b6113ea6b 100644
--- a/services/tests/servicestests/res/raw/install_app1_cert5
+++ b/services/tests/PackageManagerServiceTests/server/res/raw/install_app1_cert5
Binary files differ
diff --git a/services/tests/servicestests/res/raw/install_app1_cert5_rotated_cert6 b/services/tests/PackageManagerServiceTests/server/res/raw/install_app1_cert5_rotated_cert6
index 2da2436d9b16..2da2436d9b16 100644
--- a/services/tests/servicestests/res/raw/install_app1_cert5_rotated_cert6
+++ b/services/tests/PackageManagerServiceTests/server/res/raw/install_app1_cert5_rotated_cert6
Binary files differ
diff --git a/services/tests/servicestests/res/raw/install_app1_cert6 b/services/tests/PackageManagerServiceTests/server/res/raw/install_app1_cert6
index 256e03a2de54..256e03a2de54 100644
--- a/services/tests/servicestests/res/raw/install_app1_cert6
+++ b/services/tests/PackageManagerServiceTests/server/res/raw/install_app1_cert6
Binary files differ
diff --git a/services/tests/servicestests/res/raw/install_app1_unsigned b/services/tests/PackageManagerServiceTests/server/res/raw/install_app1_unsigned
index 01b39e28866f..01b39e28866f 100644
--- a/services/tests/servicestests/res/raw/install_app1_unsigned
+++ b/services/tests/PackageManagerServiceTests/server/res/raw/install_app1_unsigned
Binary files differ
diff --git a/services/tests/servicestests/res/raw/install_app2_cert1 b/services/tests/PackageManagerServiceTests/server/res/raw/install_app2_cert1
index 12bfc6f5aa5d..12bfc6f5aa5d 100644
--- a/services/tests/servicestests/res/raw/install_app2_cert1
+++ b/services/tests/PackageManagerServiceTests/server/res/raw/install_app2_cert1
Binary files differ
diff --git a/services/tests/servicestests/res/raw/install_app2_cert1_cert2 b/services/tests/PackageManagerServiceTests/server/res/raw/install_app2_cert1_cert2
index 39095ba7faa2..39095ba7faa2 100644
--- a/services/tests/servicestests/res/raw/install_app2_cert1_cert2
+++ b/services/tests/PackageManagerServiceTests/server/res/raw/install_app2_cert1_cert2
Binary files differ
diff --git a/services/tests/servicestests/res/raw/install_app2_cert2 b/services/tests/PackageManagerServiceTests/server/res/raw/install_app2_cert2
index f6d965be6f37..f6d965be6f37 100644
--- a/services/tests/servicestests/res/raw/install_app2_cert2
+++ b/services/tests/PackageManagerServiceTests/server/res/raw/install_app2_cert2
Binary files differ
diff --git a/services/tests/servicestests/res/raw/install_app2_cert3 b/services/tests/PackageManagerServiceTests/server/res/raw/install_app2_cert3
index 3d8b6f17f397..3d8b6f17f397 100644
--- a/services/tests/servicestests/res/raw/install_app2_cert3
+++ b/services/tests/PackageManagerServiceTests/server/res/raw/install_app2_cert3
Binary files differ
diff --git a/services/tests/servicestests/res/raw/install_app2_cert5_rotated_cert6 b/services/tests/PackageManagerServiceTests/server/res/raw/install_app2_cert5_rotated_cert6
index 30bb6478d18d..30bb6478d18d 100644
--- a/services/tests/servicestests/res/raw/install_app2_cert5_rotated_cert6
+++ b/services/tests/PackageManagerServiceTests/server/res/raw/install_app2_cert5_rotated_cert6
Binary files differ
diff --git a/services/tests/servicestests/res/raw/install_app2_unsigned b/services/tests/PackageManagerServiceTests/server/res/raw/install_app2_unsigned
index b69d9fe5c6f9..b69d9fe5c6f9 100644
--- a/services/tests/servicestests/res/raw/install_app2_unsigned
+++ b/services/tests/PackageManagerServiceTests/server/res/raw/install_app2_unsigned
Binary files differ
diff --git a/services/tests/servicestests/res/raw/install_shared1_cert1 b/services/tests/PackageManagerServiceTests/server/res/raw/install_shared1_cert1
index 714f9fffde4e..714f9fffde4e 100644
--- a/services/tests/servicestests/res/raw/install_shared1_cert1
+++ b/services/tests/PackageManagerServiceTests/server/res/raw/install_shared1_cert1
Binary files differ
diff --git a/services/tests/servicestests/res/raw/install_shared1_cert1_cert2 b/services/tests/PackageManagerServiceTests/server/res/raw/install_shared1_cert1_cert2
index 83725e0d2b26..83725e0d2b26 100644
--- a/services/tests/servicestests/res/raw/install_shared1_cert1_cert2
+++ b/services/tests/PackageManagerServiceTests/server/res/raw/install_shared1_cert1_cert2
Binary files differ
diff --git a/services/tests/servicestests/res/raw/install_shared1_cert2 b/services/tests/PackageManagerServiceTests/server/res/raw/install_shared1_cert2
index 6a3157e1196c..6a3157e1196c 100644
--- a/services/tests/servicestests/res/raw/install_shared1_cert2
+++ b/services/tests/PackageManagerServiceTests/server/res/raw/install_shared1_cert2
Binary files differ
diff --git a/services/tests/servicestests/res/raw/install_shared1_unsigned b/services/tests/PackageManagerServiceTests/server/res/raw/install_shared1_unsigned
index 2a2e5f5fdad8..2a2e5f5fdad8 100644
--- a/services/tests/servicestests/res/raw/install_shared1_unsigned
+++ b/services/tests/PackageManagerServiceTests/server/res/raw/install_shared1_unsigned
Binary files differ
diff --git a/services/tests/servicestests/res/raw/install_shared2_cert1 b/services/tests/PackageManagerServiceTests/server/res/raw/install_shared2_cert1
index 7006edcc67b2..7006edcc67b2 100644
--- a/services/tests/servicestests/res/raw/install_shared2_cert1
+++ b/services/tests/PackageManagerServiceTests/server/res/raw/install_shared2_cert1
Binary files differ
diff --git a/services/tests/servicestests/res/raw/install_shared2_cert1_cert2 b/services/tests/PackageManagerServiceTests/server/res/raw/install_shared2_cert1_cert2
index b7b084c0a779..b7b084c0a779 100644
--- a/services/tests/servicestests/res/raw/install_shared2_cert1_cert2
+++ b/services/tests/PackageManagerServiceTests/server/res/raw/install_shared2_cert1_cert2
Binary files differ
diff --git a/services/tests/servicestests/res/raw/install_shared2_cert2 b/services/tests/PackageManagerServiceTests/server/res/raw/install_shared2_cert2
index 0f04388c371e..0f04388c371e 100644
--- a/services/tests/servicestests/res/raw/install_shared2_cert2
+++ b/services/tests/PackageManagerServiceTests/server/res/raw/install_shared2_cert2
Binary files differ
diff --git a/services/tests/servicestests/res/raw/install_shared2_unsigned b/services/tests/PackageManagerServiceTests/server/res/raw/install_shared2_unsigned
index 2794282512de..2794282512de 100644
--- a/services/tests/servicestests/res/raw/install_shared2_unsigned
+++ b/services/tests/PackageManagerServiceTests/server/res/raw/install_shared2_unsigned
Binary files differ
diff --git a/services/tests/servicestests/test-apps/FakeMediaApp/AndroidManifest.xml b/services/tests/PackageManagerServiceTests/server/res/values/values.xml
index c08ee7a43976..79c66537a06a 100644
--- a/services/tests/servicestests/test-apps/FakeMediaApp/AndroidManifest.xml
+++ b/services/tests/PackageManagerServiceTests/server/res/values/values.xml
@@ -14,18 +14,7 @@
limitations under the License.
-->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.servicestests.apps.fakemediaapp">
-
- <application>
- <receiver
- android:name=".FakeMediaButtonBroadcastReceiver"
- android:enabled="true"
- android:exported="true">
- <intent-filter>
- <action android:name="android.intent.action.MEDIA_BUTTON" />
- </intent-filter>
- </receiver>
- </application>
-
-</manifest>
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="module_1_name" translatable="false">module_1_name</string>
+ <string name="module_2_name" translatable="false">module_2_name</string>
+</resources>
diff --git a/services/tests/servicestests/res/xml/unparseable_metadata1.xml b/services/tests/PackageManagerServiceTests/server/res/xml/unparseable_metadata1.xml
index 73967f113184..73967f113184 100644
--- a/services/tests/servicestests/res/xml/unparseable_metadata1.xml
+++ b/services/tests/PackageManagerServiceTests/server/res/xml/unparseable_metadata1.xml
diff --git a/services/tests/servicestests/res/xml/unparseable_metadata2.xml b/services/tests/PackageManagerServiceTests/server/res/xml/unparseable_metadata2.xml
index bb5a1b267012..bb5a1b267012 100644
--- a/services/tests/servicestests/res/xml/unparseable_metadata2.xml
+++ b/services/tests/PackageManagerServiceTests/server/res/xml/unparseable_metadata2.xml
diff --git a/services/tests/servicestests/res/xml/well_formed_metadata.xml b/services/tests/PackageManagerServiceTests/server/res/xml/well_formed_metadata.xml
index 17cc36945207..17cc36945207 100644
--- a/services/tests/servicestests/res/xml/well_formed_metadata.xml
+++ b/services/tests/PackageManagerServiceTests/server/res/xml/well_formed_metadata.xml
diff --git a/services/tests/servicestests/src/com/android/server/pm/AppsFilterImplTest.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/AppsFilterImplTest.java
index 1a8ef9e53593..3575b57934ca 100644
--- a/services/tests/servicestests/src/com/android/server/pm/AppsFilterImplTest.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/AppsFilterImplTest.java
@@ -17,6 +17,8 @@
package com.android.server.pm;
+import static android.os.Process.INVALID_UID;
+
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.contains;
import static org.junit.Assert.assertFalse;
@@ -1014,7 +1016,7 @@ public class AppsFilterImplTest {
DUMMY_TARGET_APPID);
PackageSetting calling = simulateAddPackage(appsFilter, pkg("com.some.other.package"),
DUMMY_CALLING_APPID,
- withInstallSource(target.getPackageName(), null, null, null, false));
+ withInstallSource(target.getPackageName(), null, null, INVALID_UID, null, false));
assertFalse(
appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, calling, target,
@@ -1033,7 +1035,7 @@ public class AppsFilterImplTest {
DUMMY_TARGET_APPID);
PackageSetting calling = simulateAddPackage(appsFilter, pkg("com.some.other.package"),
DUMMY_CALLING_APPID,
- withInstallSource(target.getPackageName(), null, null, null, true));
+ withInstallSource(target.getPackageName(), null, null, INVALID_UID, null, true));
assertTrue(
appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, calling, target,
@@ -1056,8 +1058,8 @@ public class AppsFilterImplTest {
DUMMY_TARGET_APPID);
watcher.verifyChangeReported("add package");
PackageSetting calling = simulateAddPackage(appsFilter, pkg("com.some.other.package"),
- DUMMY_CALLING_APPID, withInstallSource(null, target.getPackageName(), null, null,
- false));
+ DUMMY_CALLING_APPID, withInstallSource(null, target.getPackageName(), null,
+ INVALID_UID, null, false));
watcher.verifyChangeReported("add package");
assertTrue(
@@ -1082,8 +1084,8 @@ public class AppsFilterImplTest {
DUMMY_TARGET_APPID);
watcher.verifyChangeReported("add package");
PackageSetting calling = simulateAddPackage(appsFilter, pkg("com.some.other.package"),
- DUMMY_CALLING_APPID, withInstallSource(null, null, target.getPackageName(), null,
- false));
+ DUMMY_CALLING_APPID, withInstallSource(null, null, target.getPackageName(),
+ DUMMY_TARGET_APPID, null, false));
watcher.verifyChangeReported("add package");
assertFalse(
@@ -1668,11 +1670,11 @@ public class AppsFilterImplTest {
}
private WithSettingBuilder withInstallSource(String initiatingPackageName,
- String originatingPackageName, String installerPackageName,
+ String originatingPackageName, String installerPackageName, int installerPackageUid,
String installerAttributionTag, boolean isInitiatingPackageUninstalled) {
final InstallSource installSource = InstallSource.create(initiatingPackageName,
- originatingPackageName, installerPackageName, installerAttributionTag,
- /* isOrphaned= */ false, isInitiatingPackageUninstalled);
+ originatingPackageName, installerPackageName, installerPackageUid,
+ installerAttributionTag, /* isOrphaned= */ false, isInitiatingPackageUninstalled);
return setting -> setting.setInstallSource(installSource);
}
}
diff --git a/services/tests/servicestests/src/com/android/server/pm/BundleUtilsTest.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/BundleUtilsTest.java
index 6245f829fc5a..6245f829fc5a 100644
--- a/services/tests/servicestests/src/com/android/server/pm/BundleUtilsTest.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/BundleUtilsTest.java
diff --git a/services/tests/servicestests/src/com/android/server/pm/CompatibilityModeTest.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/CompatibilityModeTest.java
index f0d389be7cb6..f0d389be7cb6 100644
--- a/services/tests/servicestests/src/com/android/server/pm/CompatibilityModeTest.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/CompatibilityModeTest.java
diff --git a/services/tests/servicestests/src/com/android/server/pm/CrossProfileAppsServiceImplTest.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/CrossProfileAppsServiceImplTest.java
index ce322f7cb6e6..129efc630be6 100644
--- a/services/tests/servicestests/src/com/android/server/pm/CrossProfileAppsServiceImplTest.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/CrossProfileAppsServiceImplTest.java
@@ -38,6 +38,7 @@ import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.content.pm.PermissionInfo;
import android.content.pm.ResolveInfo;
+import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.os.UserHandle;
@@ -47,7 +48,6 @@ import android.permission.PermissionManager;
import android.platform.test.annotations.Presubmit;
import android.util.SparseArray;
-import com.android.activitycontext.ActivityContext;
import com.android.internal.util.FunctionalUtils.ThrowingRunnable;
import com.android.internal.util.FunctionalUtils.ThrowingSupplier;
import com.android.server.LocalServices;
@@ -66,7 +66,7 @@ import java.util.List;
/**
* Build/Install/Run:
- * atest FrameworksServicesTests:com.android.server.pm.CrossProfileAppsServiceImplTest
+ * atest PackageManagerServiceServerTests:com.android.server.pm.CrossProfileAppsServiceImplTest
*/
@Presubmit
@RunWith(MockitoJUnitRunner.class)
@@ -611,34 +611,23 @@ public class CrossProfileAppsServiceImplTest {
mTestInjector.setCallingUserId(PROFILE_OF_PRIMARY_USER);
Bundle options = ActivityOptions.makeOpenCrossProfileAppsAnimation().toBundle();
- IBinder result = ActivityContext.getWithContext(activity -> {
- try {
- IBinder targetTask = activity.getActivityToken();
- mCrossProfileAppsServiceImpl.startActivityAsUser(
- mIApplicationThread,
- PACKAGE_ONE,
- FEATURE_ID,
- ACTIVITY_COMPONENT,
- UserHandle.of(PRIMARY_USER).getIdentifier(),
- true,
- targetTask,
- options);
- return targetTask;
- } catch (Exception re) {
- return null;
- }
- });
- if (result == null) {
- throw new Exception();
- }
-
+ Binder targetTask = new Binder();
+ mCrossProfileAppsServiceImpl.startActivityAsUser(
+ mIApplicationThread,
+ PACKAGE_ONE,
+ FEATURE_ID,
+ ACTIVITY_COMPONENT,
+ UserHandle.of(PRIMARY_USER).getIdentifier(),
+ true,
+ targetTask,
+ options);
verify(mActivityTaskManagerInternal)
.startActivityAsUser(
nullable(IApplicationThread.class),
eq(PACKAGE_ONE),
eq(FEATURE_ID),
any(Intent.class),
- eq(result),
+ eq(targetTask),
anyInt(),
eq(options),
eq(PRIMARY_USER));
diff --git a/services/tests/servicestests/src/com/android/server/pm/InstallerTest.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/InstallerTest.java
index 6591d6f67ac8..6591d6f67ac8 100644
--- a/services/tests/servicestests/src/com/android/server/pm/InstallerTest.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/InstallerTest.java
diff --git a/services/tests/servicestests/src/com/android/server/pm/KeySetManagerServiceTest.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/KeySetManagerServiceTest.java
index d7e3825bf9d0..d7e3825bf9d0 100644
--- a/services/tests/servicestests/src/com/android/server/pm/KeySetManagerServiceTest.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/KeySetManagerServiceTest.java
diff --git a/services/tests/servicestests/src/com/android/server/pm/KeySetStrings.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/KeySetStrings.java
index 89d01ae3cd9d..89d01ae3cd9d 100644
--- a/services/tests/servicestests/src/com/android/server/pm/KeySetStrings.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/KeySetStrings.java
diff --git a/services/tests/servicestests/src/com/android/server/pm/KeySetUtils.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/KeySetUtils.java
index 9e1a366c8fca..9e1a366c8fca 100644
--- a/services/tests/servicestests/src/com/android/server/pm/KeySetUtils.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/KeySetUtils.java
diff --git a/services/tests/servicestests/src/com/android/server/pm/ModuleInfoProviderTest.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/ModuleInfoProviderTest.java
index 9ea7907ef4d0..ad58507522a9 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ModuleInfoProviderTest.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/ModuleInfoProviderTest.java
@@ -24,7 +24,7 @@ import android.content.pm.PackageManager;
import android.platform.test.annotations.Presubmit;
import android.test.InstrumentationTestCase;
-import com.android.frameworks.servicestests.R;
+import com.android.server.pm.test.service.server.R;
import org.mockito.Mock;
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageInstallerSessionTest.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/PackageInstallerSessionTest.java
index 648f895361b7..4da082e0370b 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageInstallerSessionTest.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/PackageInstallerSessionTest.java
@@ -167,7 +167,7 @@ public class PackageInstallerSessionTest {
params.isMultiPackage = true;
}
InstallSource installSource = InstallSource.create("testInstallInitiator",
- "testInstallOriginator", "testInstaller", "testAttributionTag",
+ "testInstallOriginator", "testInstaller", -1, "testAttributionTag",
PackageInstaller.PACKAGE_SOURCE_UNSPECIFIED);
return new PackageInstallerSession(
/* callback */ null,
@@ -335,8 +335,8 @@ public class PackageInstallerSessionTest {
}
private void assertInstallSourcesEquivalent(InstallSource expected, InstallSource actual) {
- assertEquals(expected.installerPackageName, actual.installerPackageName);
- assertEquals(expected.initiatingPackageName, actual.initiatingPackageName);
- assertEquals(expected.originatingPackageName, actual.originatingPackageName);
+ assertEquals(expected.mInstallerPackageName, actual.mInstallerPackageName);
+ assertEquals(expected.mInitiatingPackageName, actual.mInitiatingPackageName);
+ assertEquals(expected.mOriginatingPackageName, actual.mOriginatingPackageName);
}
}
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageManagerServiceTest.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/PackageManagerServiceTest.java
index 1877d45e5ce3..b82ffb4d0b39 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageManagerServiceTest.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/PackageManagerServiceTest.java
@@ -66,8 +66,6 @@ import java.util.List;
import java.util.regex.Pattern;
// atest PackageManagerServiceTest
-// runtest -c com.android.server.pm.PackageManagerServiceTest frameworks-services
-// bit FrameworksServicesTests:com.android.server.pm.PackageManagerServiceTest
@Postsubmit
@RunWith(AndroidJUnit4.class)
public class PackageManagerServiceTest {
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/PackageManagerSettingsTests.java
index 88932b06db82..3727d660f9a7 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/PackageManagerSettingsTests.java
@@ -25,6 +25,8 @@ import static android.content.pm.SuspendDialogInfo.BUTTON_ACTION_UNSUSPEND;
import static android.content.pm.parsing.FrameworkParsingPackageUtils.parsePublicKey;
import static android.content.res.Resources.ID_NULL;
+import static com.android.server.pm.PackageManagerService.WRITE_USER_PACKAGE_RESTRICTIONS;
+
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.not;
@@ -32,6 +34,7 @@ import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
@@ -45,6 +48,7 @@ import android.content.pm.PackageManager;
import android.content.pm.SuspendDialogInfo;
import android.content.pm.UserInfo;
import android.os.BaseBundle;
+import android.os.Message;
import android.os.PersistableBundle;
import android.os.Process;
import android.os.UserHandle;
@@ -69,6 +73,7 @@ import com.android.server.pm.pkg.PackageUserState;
import com.android.server.pm.pkg.PackageUserStateInternal;
import com.android.server.pm.pkg.SuspendParams;
import com.android.server.pm.verify.domain.DomainVerificationManagerInternal;
+import com.android.server.testutils.TestHandler;
import com.android.server.utils.Watchable;
import com.android.server.utils.WatchableTester;
import com.android.server.utils.WatchedArrayMap;
@@ -91,6 +96,7 @@ import java.security.PublicKey;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.PriorityQueue;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CountDownLatch;
@@ -116,6 +122,10 @@ public class PackageManagerSettingsTests {
final ArrayMap<String, Long> mOrigFirstInstallTimes = new ArrayMap<>();
+ final TestHandler mHandler = new TestHandler((@NonNull Message msg) -> {
+ return true;
+ });
+
@Before
public void initializeMocks() {
MockitoAnnotations.initMocks(this);
@@ -150,7 +160,7 @@ public class PackageManagerSettingsTests {
assertThat(settings.readLPw(computer, createFakeUsers()), is(true));
// write out, read back in and verify the same
- settings.writeLPr(computer);
+ settings.writeLPr(computer, /*sync=*/true);
assertThat(settings.readLPw(computer, createFakeUsers()), is(true));
verifyKeySetMetaData(settings);
}
@@ -180,7 +190,7 @@ public class PackageManagerSettingsTests {
writeOldFiles();
Settings settings = makeSettings();
assertThat(settings.readLPw(computer, createFakeUsers()), is(true));
- settings.writeLPr(computer);
+ settings.writeLPr(computer, /*sync=*/true);
// Create Settings again to make it read from the new files
settings = makeSettings();
@@ -326,14 +336,14 @@ public class PackageManagerSettingsTests {
.setNeutralButtonAction(BUTTON_ACTION_UNSUSPEND)
.build();
- ps1.modifyUserState(0).putSuspendParams( "suspendingPackage1",
+ ps1.modifyUserState(0).putSuspendParams("suspendingPackage1",
new SuspendParams(dialogInfo1, appExtras1, launcherExtras1));
- ps1.modifyUserState(0).putSuspendParams( "suspendingPackage2",
+ ps1.modifyUserState(0).putSuspendParams("suspendingPackage2",
new SuspendParams(dialogInfo2, appExtras2, launcherExtras2));
settingsUnderTest.mPackages.put(PACKAGE_NAME_1, ps1);
watcher.verifyChangeReported("put package 1");
- ps2.modifyUserState(0).putSuspendParams( "suspendingPackage3",
+ ps2.modifyUserState(0).putSuspendParams("suspendingPackage3",
new SuspendParams(null, appExtras1, null));
settingsUnderTest.mPackages.put(PACKAGE_NAME_2, ps2);
watcher.verifyChangeReported("put package 2");
@@ -342,7 +352,7 @@ public class PackageManagerSettingsTests {
settingsUnderTest.mPackages.put(PACKAGE_NAME_3, ps3);
watcher.verifyChangeReported("put package 3");
- settingsUnderTest.writePackageRestrictionsLPr(0);
+ settingsUnderTest.writePackageRestrictionsLPr(0, /*sync=*/true);
watcher.verifyChangeReported("writePackageRestrictions");
settingsUnderTest.mPackages.clear();
@@ -407,48 +417,232 @@ public class PackageManagerSettingsTests {
assertThat(defaultSetting.getUserStateOrDefault(0).isSuspended(), is(false));
}
- @Test
- public void testReadWritePackageRestrictions_distractionFlags() {
- final Settings settingsUnderTest = makeSettings();
+ private void populateDefaultSettings(Settings settings) {
+ settings.mPackages.clear();
+ settings.mPackages.put(PACKAGE_NAME_1, createPackageSetting(PACKAGE_NAME_1));
+ settings.mPackages.put(PACKAGE_NAME_2, createPackageSetting(PACKAGE_NAME_2));
+ settings.mPackages.put(PACKAGE_NAME_3, createPackageSetting(PACKAGE_NAME_3));
+ }
+
+ private void verifyDefaultDistractionFlags(Settings settings) {
+ final PackageUserState readPus1 = settings.mPackages.get(PACKAGE_NAME_1)
+ .readUserState(0);
+ assertThat(readPus1.getDistractionFlags(), is(0));
+
+ final PackageUserState readPus2 = settings.mPackages.get(PACKAGE_NAME_2)
+ .readUserState(0);
+ assertThat(readPus2.getDistractionFlags(), is(0));
+
+ final PackageUserState readPus3 = settings.mPackages.get(PACKAGE_NAME_3)
+ .readUserState(0);
+ assertThat(readPus3.getDistractionFlags(), is(0));
+ }
+
+ private void populateDistractionFlags(Settings settings) {
+ settings.mPackages.clear();
final PackageSetting ps1 = createPackageSetting(PACKAGE_NAME_1);
final PackageSetting ps2 = createPackageSetting(PACKAGE_NAME_2);
final PackageSetting ps3 = createPackageSetting(PACKAGE_NAME_3);
final int distractionFlags1 = PackageManager.RESTRICTION_HIDE_FROM_SUGGESTIONS;
ps1.setDistractionFlags(distractionFlags1, 0);
- settingsUnderTest.mPackages.put(PACKAGE_NAME_1, ps1);
+ settings.mPackages.put(PACKAGE_NAME_1, ps1);
final int distractionFlags2 = PackageManager.RESTRICTION_HIDE_NOTIFICATIONS
| PackageManager.RESTRICTION_HIDE_FROM_SUGGESTIONS;
ps2.setDistractionFlags(distractionFlags2, 0);
- settingsUnderTest.mPackages.put(PACKAGE_NAME_2, ps2);
+ settings.mPackages.put(PACKAGE_NAME_2, ps2);
final int distractionFlags3 = PackageManager.RESTRICTION_NONE;
ps3.setDistractionFlags(distractionFlags3, 0);
- settingsUnderTest.mPackages.put(PACKAGE_NAME_3, ps3);
+ settings.mPackages.put(PACKAGE_NAME_3, ps3);
+ }
- settingsUnderTest.writePackageRestrictionsLPr(0);
+ private void verifyDistractionFlags(Settings settings) {
+ final int distractionFlags1 = PackageManager.RESTRICTION_HIDE_FROM_SUGGESTIONS;
+ final int distractionFlags2 = PackageManager.RESTRICTION_HIDE_NOTIFICATIONS
+ | PackageManager.RESTRICTION_HIDE_FROM_SUGGESTIONS;
+ final int distractionFlags3 = PackageManager.RESTRICTION_NONE;
- settingsUnderTest.mPackages.clear();
- settingsUnderTest.mPackages.put(PACKAGE_NAME_1, createPackageSetting(PACKAGE_NAME_1));
- settingsUnderTest.mPackages.put(PACKAGE_NAME_2, createPackageSetting(PACKAGE_NAME_2));
- settingsUnderTest.mPackages.put(PACKAGE_NAME_3, createPackageSetting(PACKAGE_NAME_3));
- // now read and verify
- settingsUnderTest.readPackageRestrictionsLPr(0, mOrigFirstInstallTimes);
- final PackageUserState readPus1 = settingsUnderTest.mPackages.get(PACKAGE_NAME_1)
+ final PackageUserState readPus1 = settings.mPackages.get(PACKAGE_NAME_1)
.readUserState(0);
assertThat(readPus1.getDistractionFlags(), is(distractionFlags1));
- final PackageUserState readPus2 = settingsUnderTest.mPackages.get(PACKAGE_NAME_2)
+ final PackageUserState readPus2 = settings.mPackages.get(PACKAGE_NAME_2)
.readUserState(0);
assertThat(readPus2.getDistractionFlags(), is(distractionFlags2));
- final PackageUserState readPus3 = settingsUnderTest.mPackages.get(PACKAGE_NAME_3)
+ final PackageUserState readPus3 = settings.mPackages.get(PACKAGE_NAME_3)
.readUserState(0);
assertThat(readPus3.getDistractionFlags(), is(distractionFlags3));
}
@Test
+ public void testReadWritePackageRestrictions_distractionFlags() {
+ final Settings settingsUnderTest = makeSettings();
+
+ populateDistractionFlags(settingsUnderTest);
+ settingsUnderTest.writePackageRestrictionsLPr(0, /*sync=*/true);
+
+ // now read and verify
+ populateDefaultSettings(settingsUnderTest);
+ settingsUnderTest.readPackageRestrictionsLPr(0, mOrigFirstInstallTimes);
+ verifyDistractionFlags(settingsUnderTest);
+ }
+
+ @Test
+ public void testReadWritePackageRestrictionsAsync() {
+ final Settings settingsWrite = makeSettings();
+ final Settings settingsRead = makeSettings();
+ mHandler.clear();
+
+ // Initial empty state.
+ settingsWrite.removeUserLPw(0);
+
+ // Schedule 3 async writes.
+ settingsWrite.writePackageRestrictionsLPr(0, /*sync=*/false);
+ settingsWrite.writePackageRestrictionsLPr(0, /*sync=*/false);
+ settingsWrite.writePackageRestrictionsLPr(0, /*sync=*/false);
+
+ PriorityQueue<TestHandler.MsgInfo> messages = mHandler.getPendingMessages();
+ assertEquals(3, messages.size());
+ final Runnable asyncWrite1 = (Runnable) messages.poll().message.obj;
+ final Runnable asyncWrite2 = (Runnable) messages.poll().message.obj;
+ final Runnable asyncWrite3 = (Runnable) messages.poll().message.obj;
+ mHandler.clear();
+
+ // First read should read old data.
+ populateDefaultSettings(settingsRead);
+ settingsRead.readPackageRestrictionsLPr(0, mOrigFirstInstallTimes);
+ verifyDefaultDistractionFlags(settingsRead);
+
+ // 1st write: with flags.
+ populateDistractionFlags(settingsWrite);
+ asyncWrite1.run();
+
+ // New data.
+ populateDefaultSettings(settingsRead);
+ settingsRead.readPackageRestrictionsLPr(0, mOrigFirstInstallTimes);
+ verifyDistractionFlags(settingsRead);
+
+ // 2nd write: without.
+ populateDefaultSettings(settingsWrite);
+ asyncWrite2.run();
+
+ // Default data.
+ populateDefaultSettings(settingsRead);
+ settingsRead.readPackageRestrictionsLPr(0, mOrigFirstInstallTimes);
+ verifyDefaultDistractionFlags(settingsRead);
+
+ // 3rd write: with flags.
+ populateDistractionFlags(settingsWrite);
+ asyncWrite3.run();
+
+ // New data.
+ populateDefaultSettings(settingsRead);
+ settingsRead.readPackageRestrictionsLPr(0, mOrigFirstInstallTimes);
+ verifyDistractionFlags(settingsRead);
+ }
+
+ @Test
+ public void testReadWritePackageRestrictionsAsyncUserRemoval() {
+ final Settings settingsWrite = makeSettings();
+ final Settings settingsRead = makeSettings();
+ mHandler.clear();
+
+ // Initial empty state.
+ settingsWrite.removeUserLPw(0);
+
+ // 2 async writes.
+ populateDistractionFlags(settingsWrite);
+ settingsWrite.writePackageRestrictionsLPr(0, /*sync=*/false);
+ settingsWrite.writePackageRestrictionsLPr(0, /*sync=*/false);
+
+ PriorityQueue<TestHandler.MsgInfo> messages = mHandler.getPendingMessages();
+ assertEquals(2, messages.size());
+ final Runnable asyncWrite1 = (Runnable) messages.poll().message.obj;
+ final Runnable asyncWrite2 = (Runnable) messages.poll().message.obj;
+ mHandler.clear();
+
+ // First read should not read anything.
+ populateDefaultSettings(settingsRead);
+ settingsRead.readPackageRestrictionsLPr(0, mOrigFirstInstallTimes);
+ verifyDefaultDistractionFlags(settingsRead);
+
+ // 1st write.
+ asyncWrite1.run();
+
+ // Second read should read new data.
+ populateDefaultSettings(settingsRead);
+ settingsRead.readPackageRestrictionsLPr(0, mOrigFirstInstallTimes);
+ verifyDistractionFlags(settingsRead);
+
+ // Now remove the user.
+ settingsWrite.removeUserLPw(0);
+
+ // 2nd write.
+ asyncWrite2.run();
+
+ // Re-read and verify that nothing was read.
+ populateDefaultSettings(settingsRead);
+ settingsRead.readPackageRestrictionsLPr(0, mOrigFirstInstallTimes);
+ verifyDefaultDistractionFlags(settingsRead);
+ }
+
+ @Test
+ public void testReadWritePackageRestrictionsSyncAfterAsync() {
+ final Settings settingsWrite = makeSettings();
+ final Settings settingsRead = makeSettings();
+ mHandler.clear();
+
+ // Initial state, distraction flags populated.
+ populateDistractionFlags(settingsWrite);
+ settingsWrite.writePackageRestrictionsLPr(0, /*sync=*/true);
+
+ // 2 async writes of empty distraction flags.
+ populateDefaultSettings(settingsWrite);
+ settingsWrite.writePackageRestrictionsLPr(0, /*sync=*/false);
+ settingsWrite.writePackageRestrictionsLPr(0, /*sync=*/false);
+
+ PriorityQueue<TestHandler.MsgInfo> messages = mHandler.getPendingMessages();
+ assertEquals(2, messages.size());
+ final Runnable asyncWrite1 = (Runnable) messages.poll().message.obj;
+ final Runnable asyncWrite2 = (Runnable) messages.poll().message.obj;
+
+ // First read should use read initial data (with flags).
+ populateDefaultSettings(settingsRead);
+ settingsRead.readPackageRestrictionsLPr(0, mOrigFirstInstallTimes);
+ verifyDistractionFlags(settingsRead);
+
+ // 1st write.
+ asyncWrite1.run();
+
+ // Second read should read updated data.
+ populateDefaultSettings(settingsRead);
+ settingsRead.readPackageRestrictionsLPr(0, mOrigFirstInstallTimes);
+ verifyDefaultDistractionFlags(settingsRead);
+
+ // Sync write with flags - overrides all async writes.
+ populateDistractionFlags(settingsWrite);
+ settingsWrite.writeAllUsersPackageRestrictionsLPr(/*sync=*/true);
+
+ // Expect removeMessages call.
+ assertFalse(mHandler.hasMessages(WRITE_USER_PACKAGE_RESTRICTIONS));
+
+ populateDefaultSettings(settingsRead);
+ settingsRead.readPackageRestrictionsLPr(0, mOrigFirstInstallTimes);
+ verifyDistractionFlags(settingsRead);
+
+ // 2nd write.
+ asyncWrite2.run();
+
+ // Re-read and verify.
+ populateDefaultSettings(settingsRead);
+ settingsRead.readPackageRestrictionsLPr(0, mOrigFirstInstallTimes);
+ verifyDistractionFlags(settingsRead);
+ }
+
+ @Test
public void testWriteReadUsesStaticLibraries() {
final Settings settingsUnderTest = makeSettings();
final PackageSetting ps1 = createPackageSetting(PACKAGE_NAME_1);
@@ -473,7 +667,7 @@ public class PackageManagerSettingsTests {
ps2.setUsesStaticLibrariesVersions(new long[] { 34 });
settingsUnderTest.mPackages.put(PACKAGE_NAME_2, ps2);
- settingsUnderTest.writeLPr(computer);
+ settingsUnderTest.writeLPr(computer, /*sync=*/true);
settingsUnderTest.mPackages.clear();
settingsUnderTest.mDisabledSysPackages.clear();
@@ -538,7 +732,7 @@ public class PackageManagerSettingsTests {
ps2.setUsesSdkLibrariesVersionsMajor(new long[] { 34 });
settingsUnderTest.mPackages.put(PACKAGE_NAME_2, ps2);
- settingsUnderTest.writeLPr(computer);
+ settingsUnderTest.writeLPr(computer, /*sync=*/true);
settingsUnderTest.mPackages.clear();
settingsUnderTest.mDisabledSysPackages.clear();
@@ -1548,7 +1742,8 @@ public class PackageManagerSettingsTests {
private Settings makeSettings() {
return new Settings(InstrumentationRegistry.getContext().getFilesDir(),
mRuntimePermissionsPersistence, mPermissionDataProvider,
- mDomainVerificationManager, null, new PackageManagerTracedLock());
+ mDomainVerificationManager, mHandler,
+ new PackageManagerTracedLock());
}
private void verifyKeySetMetaData(Settings settings)
@@ -1610,4 +1805,5 @@ public class PackageManagerSettingsTests {
private AndroidPackage mockAndroidPackage(PackageSetting pkgSetting) {
return PackageImpl.forTesting(pkgSetting.getPackageName()).hideAsParsed().hideAsFinal();
}
+
}
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageManagerTests.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/PackageManagerTests.java
index a3f7ce504b92..92bdd64f2803 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageManagerTests.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/PackageManagerTests.java
@@ -69,7 +69,7 @@ import androidx.test.filters.LargeTest;
import androidx.test.filters.SmallTest;
import androidx.test.filters.Suppress;
-import com.android.frameworks.servicestests.R;
+import com.android.server.pm.test.service.server.R;
import com.android.internal.content.InstallLocationUtils;
import com.android.server.pm.parsing.pkg.ParsedPackage;
import com.android.server.pm.pkg.parsing.ParsingPackage;
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/PackageParserTest.java
index 59f27ec2766e..59f27ec2766e 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/PackageParserTest.java
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageSignaturesTest.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/PackageSignaturesTest.java
index 47f75a56638b..47f75a56638b 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageSignaturesTest.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/PackageSignaturesTest.java
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageUserStateTest.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/PackageUserStateTest.java
index 9ad503c3616e..9ad503c3616e 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageUserStateTest.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/PackageUserStateTest.java
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageVerificationStateTest.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/PackageVerificationStateTest.java
index 8715afda5cee..8715afda5cee 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageVerificationStateTest.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/PackageVerificationStateTest.java
diff --git a/services/tests/servicestests/src/com/android/server/pm/ParallelPackageParserTest.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/ParallelPackageParserTest.java
index 38d01d0c4c18..38d01d0c4c18 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ParallelPackageParserTest.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/ParallelPackageParserTest.java
diff --git a/services/tests/servicestests/src/com/android/server/pm/PreferredComponentTest.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/PreferredComponentTest.java
index 6650e59fa5fe..6650e59fa5fe 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PreferredComponentTest.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/PreferredComponentTest.java
diff --git a/services/tests/servicestests/src/com/android/server/pm/RestrictionsSetTest.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/RestrictionsSetTest.java
index e7adf7b757f1..e7adf7b757f1 100644
--- a/services/tests/servicestests/src/com/android/server/pm/RestrictionsSetTest.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/RestrictionsSetTest.java
diff --git a/services/tests/servicestests/src/com/android/server/pm/ScanRequestBuilder.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/ScanRequestBuilder.java
index 1c3673e84038..1c3673e84038 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ScanRequestBuilder.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/ScanRequestBuilder.java
diff --git a/services/tests/servicestests/src/com/android/server/pm/ScanTests.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/ScanTests.java
index 48d6d9037e95..ce0b3a2dc6f6 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ScanTests.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/ScanTests.java
@@ -493,7 +493,7 @@ public class ScanTests {
final ScanResult scanResult = executeScan(scanRequest);
- assertThat(scanResult.mPkgSetting.getInstallSource().isOrphaned, is(true));
+ assertThat(scanResult.mPkgSetting.getInstallSource().mIsOrphaned, is(true));
}
private static Matcher<Integer> hasFlag(final int flag) {
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserDataPreparerTest.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/UserDataPreparerTest.java
index b2f9002e7ec6..afbe352ad676 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserDataPreparerTest.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/UserDataPreparerTest.java
@@ -48,15 +48,7 @@ import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.Collections;
-/**
- * <p>Run with:<pre>
- * m FrameworksServicesTests &&
- * adb install \
- * -r out/target/product/hammerhead/data/app/FrameworksServicesTests/FrameworksServicesTests.apk &&
- * adb shell am instrument -e class com.android.server.pm.UserDataPreparerTest \
- * -w com.android.frameworks.servicestests/androidx.test.runner.AndroidJUnitRunner
- * </pre>
- */
+// atest PackageManagerServiceTest:com.android.server.pm.UserDataPreparerTest
@RunWith(AndroidJUnit4.class)
@Presubmit
@SmallTest
diff --git a/services/tests/servicestests/src/com/android/server/pm/WatchedIntentHandlingTest.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/WatchedIntentHandlingTest.java
index 6e03569efcc1..6e03569efcc1 100644
--- a/services/tests/servicestests/src/com/android/server/pm/WatchedIntentHandlingTest.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/WatchedIntentHandlingTest.java
diff --git a/services/tests/servicestests/src/com/android/server/pm/parsing/PackageParserLegacyCoreTest.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/parsing/PackageParserLegacyCoreTest.java
index 8e6c014d6a21..ebf309f4b796 100644
--- a/services/tests/servicestests/src/com/android/server/pm/parsing/PackageParserLegacyCoreTest.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/parsing/PackageParserLegacyCoreTest.java
@@ -38,7 +38,7 @@ import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
-import com.android.frameworks.servicestests.R;
+import com.android.server.pm.test.service.server.R;
import com.android.internal.util.ArrayUtils;
import com.android.server.pm.PackageManagerException;
import com.android.server.pm.parsing.pkg.ParsedPackage;
diff --git a/services/tests/servicestests/src/com/android/server/pm/parsing/PackageParsingDeferErrorTest.kt b/services/tests/PackageManagerServiceTests/server/src/com/android/server/parsing/PackageParsingDeferErrorTest.kt
index 9626fc3be3b3..3b926c266b16 100644
--- a/services/tests/servicestests/src/com/android/server/pm/parsing/PackageParsingDeferErrorTest.kt
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/parsing/PackageParsingDeferErrorTest.kt
@@ -23,8 +23,8 @@ import com.android.server.pm.pkg.parsing.ParsingPackageUtils
import android.content.pm.parsing.result.ParseResult
import android.platform.test.annotations.Presubmit
import androidx.test.InstrumentationRegistry
-import com.android.frameworks.servicestests.R
import com.android.server.pm.parsing.pkg.ParsedPackage
+import com.android.server.pm.test.service.server.R
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertWithMessage
import org.junit.Rule
diff --git a/services/tests/servicestests/src/com/android/server/pm/parsing/SystemPartitionParseTest.kt b/services/tests/PackageManagerServiceTests/server/src/com/android/server/parsing/SystemPartitionParseTest.kt
index 1f57b6c9f95f..1f57b6c9f95f 100644
--- a/services/tests/servicestests/src/com/android/server/pm/parsing/SystemPartitionParseTest.kt
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/parsing/SystemPartitionParseTest.kt
diff --git a/services/tests/servicestests/src/com/android/server/pm/parsing/library/AndroidHidlUpdaterTest.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/parsing/library/AndroidHidlUpdaterTest.java
index d3107b07d828..d3107b07d828 100644
--- a/services/tests/servicestests/src/com/android/server/pm/parsing/library/AndroidHidlUpdaterTest.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/parsing/library/AndroidHidlUpdaterTest.java
diff --git a/services/tests/servicestests/src/com/android/server/pm/parsing/library/AndroidNetIpSecIkeUpdaterTest.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/parsing/library/AndroidNetIpSecIkeUpdaterTest.java
index 36308d23e520..36308d23e520 100644
--- a/services/tests/servicestests/src/com/android/server/pm/parsing/library/AndroidNetIpSecIkeUpdaterTest.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/parsing/library/AndroidNetIpSecIkeUpdaterTest.java
diff --git a/services/tests/servicestests/src/com/android/server/pm/parsing/library/AndroidTestBaseUpdaterTest.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/parsing/library/AndroidTestBaseUpdaterTest.java
index 3782f5d1e20d..3782f5d1e20d 100644
--- a/services/tests/servicestests/src/com/android/server/pm/parsing/library/AndroidTestBaseUpdaterTest.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/parsing/library/AndroidTestBaseUpdaterTest.java
diff --git a/services/tests/servicestests/src/com/android/server/pm/parsing/library/AndroidTestRunnerSplitUpdaterTest.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/parsing/library/AndroidTestRunnerSplitUpdaterTest.java
index a739607bdb65..a739607bdb65 100644
--- a/services/tests/servicestests/src/com/android/server/pm/parsing/library/AndroidTestRunnerSplitUpdaterTest.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/parsing/library/AndroidTestRunnerSplitUpdaterTest.java
diff --git a/services/tests/servicestests/src/com/android/server/pm/parsing/library/ApexSharedLibraryUpdaterTest.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/parsing/library/ApexSharedLibraryUpdaterTest.java
index 3977d0dd7cc3..3977d0dd7cc3 100644
--- a/services/tests/servicestests/src/com/android/server/pm/parsing/library/ApexSharedLibraryUpdaterTest.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/parsing/library/ApexSharedLibraryUpdaterTest.java
diff --git a/services/tests/servicestests/src/com/android/server/pm/parsing/library/ComGoogleAndroidMapsUpdaterTest.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/parsing/library/ComGoogleAndroidMapsUpdaterTest.java
index a31c7817ab02..a31c7817ab02 100644
--- a/services/tests/servicestests/src/com/android/server/pm/parsing/library/ComGoogleAndroidMapsUpdaterTest.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/parsing/library/ComGoogleAndroidMapsUpdaterTest.java
diff --git a/services/tests/servicestests/src/com/android/server/pm/parsing/library/OptionalClassRunner.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/parsing/library/OptionalClassRunner.java
index 0ebfe1a0eecb..0ebfe1a0eecb 100644
--- a/services/tests/servicestests/src/com/android/server/pm/parsing/library/OptionalClassRunner.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/parsing/library/OptionalClassRunner.java
diff --git a/services/tests/servicestests/src/com/android/server/pm/parsing/library/OrgApacheHttpLegacyUpdaterTest.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/parsing/library/OrgApacheHttpLegacyUpdaterTest.java
index f5e3f4ed5e71..f5e3f4ed5e71 100644
--- a/services/tests/servicestests/src/com/android/server/pm/parsing/library/OrgApacheHttpLegacyUpdaterTest.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/parsing/library/OrgApacheHttpLegacyUpdaterTest.java
diff --git a/services/tests/servicestests/src/com/android/server/pm/parsing/library/PackageBackwardCompatibilityTest.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/parsing/library/PackageBackwardCompatibilityTest.java
index b3648b1fe072..b3648b1fe072 100644
--- a/services/tests/servicestests/src/com/android/server/pm/parsing/library/PackageBackwardCompatibilityTest.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/parsing/library/PackageBackwardCompatibilityTest.java
diff --git a/services/tests/servicestests/src/com/android/server/pm/parsing/library/PackageSharedLibraryUpdaterTest.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/parsing/library/PackageSharedLibraryUpdaterTest.java
index 2450a14bd5ef..2450a14bd5ef 100644
--- a/services/tests/servicestests/src/com/android/server/pm/parsing/library/PackageSharedLibraryUpdaterTest.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/parsing/library/PackageSharedLibraryUpdaterTest.java
diff --git a/services/tests/servicestests/src/com/android/server/pm/parsing/library/RemoveUnnecessaryAndroidTestBaseLibraryTest.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/parsing/library/RemoveUnnecessaryAndroidTestBaseLibraryTest.java
index 2825c69daeff..2825c69daeff 100644
--- a/services/tests/servicestests/src/com/android/server/pm/parsing/library/RemoveUnnecessaryAndroidTestBaseLibraryTest.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/parsing/library/RemoveUnnecessaryAndroidTestBaseLibraryTest.java
diff --git a/services/tests/servicestests/src/com/android/server/pm/parsing/library/RemoveUnnecessaryOrgApacheHttpLegacyLibraryTest.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/parsing/library/RemoveUnnecessaryOrgApacheHttpLegacyLibraryTest.java
index c0da8a7ed0c1..c0da8a7ed0c1 100644
--- a/services/tests/servicestests/src/com/android/server/pm/parsing/library/RemoveUnnecessaryOrgApacheHttpLegacyLibraryTest.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/parsing/library/RemoveUnnecessaryOrgApacheHttpLegacyLibraryTest.java
diff --git a/services/tests/PackageManagerServiceTests/server/src/com/android/server/utils/OWNERS b/services/tests/PackageManagerServiceTests/server/src/com/android/server/utils/OWNERS
new file mode 100644
index 000000000000..1853220b9433
--- /dev/null
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/utils/OWNERS
@@ -0,0 +1,4 @@
+per-file WatchableTester.java = file:/services/core/java/com/android/server/pm/OWNERS
+per-file WatchableTester.java = shombert@google.com
+per-file WatcherTest.java = file:/services/core/java/com/android/server/pm/OWNERS
+per-file WatcherTest.java = shombert@google.com
diff --git a/services/tests/servicestests/src/com/android/server/utils/WatchableTester.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/utils/WatchableTester.java
index 590df3c18f5a..590df3c18f5a 100644
--- a/services/tests/servicestests/src/com/android/server/utils/WatchableTester.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/utils/WatchableTester.java
diff --git a/services/tests/servicestests/src/com/android/server/utils/WatcherTest.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/utils/WatcherTest.java
index 37c95f735d89..74d491dbf87c 100644
--- a/services/tests/servicestests/src/com/android/server/utils/WatcherTest.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/utils/WatcherTest.java
@@ -44,7 +44,7 @@ import java.util.Random;
* {@link WatchedSparseBooleanArray}.
*
* Build/Install/Run:
- * atest FrameworksServicesTests:WatcherTest
+ * atest PackageManagerServiceTest:WatcherTest
*/
@SmallTest
public class WatcherTest {
diff --git a/services/tests/mockingservicestests/res/xml/game_manager_service_metadata_config_interventions_enabled_battery_opt_in.xml b/services/tests/mockingservicestests/res/xml/game_manager_service_metadata_config_interventions_enabled_battery_opt_in.xml
new file mode 100644
index 000000000000..4f41ee6f5977
--- /dev/null
+++ b/services/tests/mockingservicestests/res/xml/game_manager_service_metadata_config_interventions_enabled_battery_opt_in.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<game-mode-config
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:supportsPerformanceGameMode="false"
+ android:supportsBatteryGameMode="true"
+ android:allowGameAngleDriver="true"
+ android:allowGameDownscaling="true"
+ android:allowGameFpsOverride="true"
+/> \ No newline at end of file
diff --git a/services/tests/mockingservicestests/res/xml/game_manager_service_metadata_config_interventions_enabled_performance_opt_in.xml b/services/tests/mockingservicestests/res/xml/game_manager_service_metadata_config_interventions_enabled_performance_opt_in.xml
new file mode 100644
index 000000000000..0242aec8ffcb
--- /dev/null
+++ b/services/tests/mockingservicestests/res/xml/game_manager_service_metadata_config_interventions_enabled_performance_opt_in.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<game-mode-config
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:supportsPerformanceGameMode="true"
+ android:supportsBatteryGameMode="false"
+ android:allowGameAngleDriver="true"
+ android:allowGameDownscaling="true"
+ android:allowGameFpsOverride="true"
+/> \ No newline at end of file
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java
index 2f6b07bfb6f7..66e7ec00b6d3 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java
@@ -586,7 +586,7 @@ public class BroadcastQueueModernImplTest {
final BroadcastOptions optionsMusicVolumeChanged = BroadcastOptions.makeBasic();
optionsMusicVolumeChanged.setDeliveryGroupPolicy(
BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT);
- optionsMusicVolumeChanged.setDeliveryGroupKey("audio",
+ optionsMusicVolumeChanged.setDeliveryGroupMatchingKey("audio",
String.valueOf(AudioManager.STREAM_MUSIC));
final Intent alarmVolumeChanged = new Intent(AudioManager.VOLUME_CHANGED_ACTION);
@@ -595,7 +595,7 @@ public class BroadcastQueueModernImplTest {
final BroadcastOptions optionsAlarmVolumeChanged = BroadcastOptions.makeBasic();
optionsAlarmVolumeChanged.setDeliveryGroupPolicy(
BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT);
- optionsAlarmVolumeChanged.setDeliveryGroupKey("audio",
+ optionsAlarmVolumeChanged.setDeliveryGroupMatchingKey("audio",
String.valueOf(AudioManager.STREAM_ALARM));
// Halt all processing so that we get a consistent view
@@ -651,7 +651,8 @@ public class BroadcastQueueModernImplTest {
final BroadcastOptions optionsPackageChangedForUid = BroadcastOptions.makeBasic();
optionsPackageChangedForUid.setDeliveryGroupPolicy(
BroadcastOptions.DELIVERY_GROUP_POLICY_MERGED);
- optionsPackageChangedForUid.setDeliveryGroupKey("package", String.valueOf(TEST_UID));
+ optionsPackageChangedForUid.setDeliveryGroupMatchingKey("package",
+ String.valueOf(TEST_UID));
optionsPackageChangedForUid.setDeliveryGroupExtrasMerger(extrasMerger);
final Intent secondPackageChangedForUid = createPackageChangedIntent(TEST_UID,
@@ -662,7 +663,8 @@ public class BroadcastQueueModernImplTest {
final BroadcastOptions optionsPackageChangedForUid2 = BroadcastOptions.makeBasic();
optionsPackageChangedForUid.setDeliveryGroupPolicy(
BroadcastOptions.DELIVERY_GROUP_POLICY_MERGED);
- optionsPackageChangedForUid.setDeliveryGroupKey("package", String.valueOf(TEST_UID2));
+ optionsPackageChangedForUid.setDeliveryGroupMatchingKey("package",
+ String.valueOf(TEST_UID2));
optionsPackageChangedForUid.setDeliveryGroupExtrasMerger(extrasMerger);
// Halt all processing so that we get a consistent view
@@ -685,6 +687,75 @@ public class BroadcastQueueModernImplTest {
verifyPendingRecords(queue, List.of(packageChangedForUid2, expectedPackageChangedForUid));
}
+ @Test
+ public void testDeliveryGroupPolicy_matchingFilter() {
+ final Intent timeTick = new Intent(Intent.ACTION_TIME_TICK);
+ final BroadcastOptions optionsTimeTick = BroadcastOptions.makeBasic();
+ optionsTimeTick.setDeliveryGroupPolicy(BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT);
+
+ final Intent musicVolumeChanged = new Intent(AudioManager.VOLUME_CHANGED_ACTION);
+ musicVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE,
+ AudioManager.STREAM_MUSIC);
+ final IntentFilter filterMusicVolumeChanged = new IntentFilter(
+ AudioManager.VOLUME_CHANGED_ACTION);
+ filterMusicVolumeChanged.addExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE,
+ AudioManager.STREAM_MUSIC);
+ final BroadcastOptions optionsMusicVolumeChanged = BroadcastOptions.makeBasic();
+ optionsMusicVolumeChanged.setDeliveryGroupPolicy(
+ BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT);
+ optionsMusicVolumeChanged.setDeliveryGroupMatchingFilter(filterMusicVolumeChanged);
+
+ final Intent alarmVolumeChanged = new Intent(AudioManager.VOLUME_CHANGED_ACTION);
+ alarmVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE,
+ AudioManager.STREAM_ALARM);
+ final IntentFilter filterAlarmVolumeChanged = new IntentFilter(
+ AudioManager.VOLUME_CHANGED_ACTION);
+ filterAlarmVolumeChanged.addExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE,
+ AudioManager.STREAM_ALARM);
+ final BroadcastOptions optionsAlarmVolumeChanged = BroadcastOptions.makeBasic();
+ optionsAlarmVolumeChanged.setDeliveryGroupPolicy(
+ BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT);
+ optionsAlarmVolumeChanged.setDeliveryGroupMatchingFilter(filterAlarmVolumeChanged);
+
+ // Halt all processing so that we get a consistent view
+ mHandlerThread.getLooper().getQueue().postSyncBarrier();
+
+ mImpl.enqueueBroadcastLocked(makeBroadcastRecord(timeTick, optionsTimeTick));
+ mImpl.enqueueBroadcastLocked(makeBroadcastRecord(musicVolumeChanged,
+ optionsMusicVolumeChanged));
+ mImpl.enqueueBroadcastLocked(makeBroadcastRecord(alarmVolumeChanged,
+ optionsAlarmVolumeChanged));
+ mImpl.enqueueBroadcastLocked(makeBroadcastRecord(musicVolumeChanged,
+ optionsMusicVolumeChanged));
+
+ final BroadcastProcessQueue queue = mImpl.getProcessQueue(PACKAGE_GREEN,
+ getUidForPackage(PACKAGE_GREEN));
+ // Verify that the older musicVolumeChanged has been removed.
+ verifyPendingRecords(queue,
+ List.of(timeTick, alarmVolumeChanged, musicVolumeChanged));
+
+ mImpl.enqueueBroadcastLocked(makeBroadcastRecord(timeTick, optionsTimeTick));
+ mImpl.enqueueBroadcastLocked(makeBroadcastRecord(alarmVolumeChanged,
+ optionsAlarmVolumeChanged));
+ mImpl.enqueueBroadcastLocked(makeBroadcastRecord(musicVolumeChanged,
+ optionsMusicVolumeChanged));
+ mImpl.enqueueBroadcastLocked(makeBroadcastRecord(alarmVolumeChanged,
+ optionsAlarmVolumeChanged));
+ // Verify that the older alarmVolumeChanged has been removed.
+ verifyPendingRecords(queue,
+ List.of(timeTick, musicVolumeChanged, alarmVolumeChanged));
+
+ mImpl.enqueueBroadcastLocked(makeBroadcastRecord(timeTick, optionsTimeTick));
+ mImpl.enqueueBroadcastLocked(makeBroadcastRecord(musicVolumeChanged,
+ optionsMusicVolumeChanged));
+ mImpl.enqueueBroadcastLocked(makeBroadcastRecord(alarmVolumeChanged,
+ optionsAlarmVolumeChanged));
+ mImpl.enqueueBroadcastLocked(makeBroadcastRecord(timeTick, optionsTimeTick));
+ // Verify that the older timeTick has been removed.
+ verifyPendingRecords(queue,
+ List.of(musicVolumeChanged, alarmVolumeChanged, timeTick));
+ }
+
private Intent createPackageChangedIntent(int uid, List<String> componentNameList) {
final Intent packageChangedIntent = new Intent(Intent.ACTION_PACKAGE_CHANGED);
packageChangedIntent.putExtra(Intent.EXTRA_UID, uid);
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastRecordTest.java b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastRecordTest.java
index 05ed0e236b4d..3864c88d71e4 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastRecordTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastRecordTest.java
@@ -36,13 +36,17 @@ import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
import android.app.ActivityManagerInternal;
+import android.app.BroadcastOptions;
import android.content.Intent;
+import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
+import android.os.PersistableBundle;
import android.os.Process;
import android.os.UserHandle;
+import android.telephony.SubscriptionManager;
import android.util.SparseArray;
import androidx.test.filters.SmallTest;
@@ -176,9 +180,8 @@ public class BroadcastRecordTest {
intent.putExtra(Intent.EXTRA_INDEX, 42);
final BroadcastRecord r = createBroadcastRecord(
List.of(createResolveInfo(PACKAGE1, getAppId(1))), UserHandle.USER_ALL, intent,
- (uid, extras) -> {
- return Bundle.EMPTY;
- });
+ (uid, extras) -> Bundle.EMPTY,
+ null /* options */);
final Intent actual = r.getReceiverIntent(r.receivers.get(0));
assertEquals(PACKAGE1, actual.getComponent().getPackageName());
assertEquals(-1, actual.getIntExtra(Intent.EXTRA_INDEX, -1));
@@ -192,9 +195,8 @@ public class BroadcastRecordTest {
intent.putExtra(Intent.EXTRA_INDEX, 42);
final BroadcastRecord r = createBroadcastRecord(
List.of(createResolveInfo(PACKAGE1, getAppId(1))), UserHandle.USER_ALL, intent,
- (uid, extras) -> {
- return null;
- });
+ (uid, extras) -> null,
+ null /* options */);
final Intent actual = r.getReceiverIntent(r.receivers.get(0));
assertNull(actual);
assertNull(r.intent.getComponent());
@@ -290,6 +292,122 @@ public class BroadcastRecordTest {
assertEquals(origReceiversSize, br.receivers.size());
}
+ @Test
+ public void testMatchesDeliveryGroup() {
+ final List<ResolveInfo> receivers = List.of(createResolveInfo(PACKAGE1, getAppId(1)));
+
+ final Intent intent1 = new Intent(Intent.ACTION_SERVICE_STATE);
+ intent1.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, 0);
+ intent1.putExtra(SubscriptionManager.EXTRA_SLOT_INDEX, 1);
+ final BroadcastOptions options1 = BroadcastOptions.makeBasic();
+ final BroadcastRecord record1 = createBroadcastRecord(receivers, UserHandle.USER_ALL,
+ intent1, options1);
+
+ final Intent intent2 = new Intent(Intent.ACTION_SERVICE_STATE);
+ intent2.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, 0);
+ intent2.putExtra(SubscriptionManager.EXTRA_SLOT_INDEX, 2);
+ final BroadcastOptions options2 = BroadcastOptions.makeBasic();
+ final BroadcastRecord record2 = createBroadcastRecord(receivers, UserHandle.USER_ALL,
+ intent2, options2);
+
+ assertTrue(record2.matchesDeliveryGroup(record1));
+ }
+
+ @Test
+ public void testMatchesDeliveryGroup_withMatchingKey() {
+ final List<ResolveInfo> receivers = List.of(createResolveInfo(PACKAGE1, getAppId(1)));
+
+ final Intent intent1 = new Intent(Intent.ACTION_SERVICE_STATE);
+ intent1.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, 0);
+ intent1.putExtra(SubscriptionManager.EXTRA_SLOT_INDEX, 1);
+ final BroadcastOptions options1 = BroadcastOptions.makeBasic();
+ options1.setDeliveryGroupMatchingKey(Intent.ACTION_SERVICE_STATE, "key1");
+ final BroadcastRecord record1 = createBroadcastRecord(receivers, UserHandle.USER_ALL,
+ intent1, options1);
+
+ final Intent intent2 = new Intent(Intent.ACTION_SERVICE_STATE);
+ intent2.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, 0);
+ intent2.putExtra(SubscriptionManager.EXTRA_SLOT_INDEX, 2);
+ final BroadcastOptions options2 = BroadcastOptions.makeBasic();
+ options2.setDeliveryGroupMatchingKey(Intent.ACTION_SERVICE_STATE, "key2");
+ final BroadcastRecord record2 = createBroadcastRecord(receivers, UserHandle.USER_ALL,
+ intent2, options2);
+
+ final Intent intent3 = new Intent(Intent.ACTION_SERVICE_STATE);
+ intent3.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, 1);
+ intent3.putExtra(SubscriptionManager.EXTRA_SLOT_INDEX, 3);
+ final BroadcastOptions options3 = BroadcastOptions.makeBasic();
+ options3.setDeliveryGroupMatchingKey(Intent.ACTION_SERVICE_STATE, "key1");
+ final BroadcastRecord record3 = createBroadcastRecord(receivers, UserHandle.USER_ALL,
+ intent3, options3);
+
+ // record2 and record1 have different matching keys, so their delivery groups
+ // shouldn't match
+ assertFalse(record2.matchesDeliveryGroup(record1));
+ // record3 and record2 have different matching keys, so their delivery groups
+ // shouldn't match
+ assertFalse(record3.matchesDeliveryGroup(record2));
+ // record3 and record1 have same matching keys, so their delivery groups should match even
+ // if the intent has different extras.
+ assertTrue(record3.matchesDeliveryGroup(record1));
+ }
+
+ @Test
+ public void testMatchesDeliveryGroup_withMatchingFilter() {
+ final List<ResolveInfo> receivers = List.of(createResolveInfo(PACKAGE1, getAppId(1)));
+
+ final Intent intent1 = new Intent(Intent.ACTION_SERVICE_STATE);
+ intent1.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, 0);
+ intent1.putExtra(SubscriptionManager.EXTRA_SLOT_INDEX, 1);
+ intent1.putExtra(Intent.EXTRA_REASON, "reason1");
+ final IntentFilter filter1 = new IntentFilter(Intent.ACTION_SERVICE_STATE);
+ final PersistableBundle bundle1 = new PersistableBundle();
+ bundle1.putInt(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, 0);
+ bundle1.putInt(SubscriptionManager.EXTRA_SLOT_INDEX, 1);
+ filter1.setExtras(bundle1);
+ final BroadcastOptions options1 = BroadcastOptions.makeBasic();
+ options1.setDeliveryGroupMatchingFilter(filter1);
+ final BroadcastRecord record1 = createBroadcastRecord(receivers, UserHandle.USER_ALL,
+ intent1, options1);
+
+ final Intent intent2 = new Intent(Intent.ACTION_SERVICE_STATE);
+ intent2.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, 0);
+ intent2.putExtra(SubscriptionManager.EXTRA_SLOT_INDEX, 2);
+ intent2.putExtra(Intent.EXTRA_REASON, "reason2");
+ final IntentFilter filter2 = new IntentFilter(Intent.ACTION_SERVICE_STATE);
+ final PersistableBundle bundle2 = new PersistableBundle();
+ bundle2.putInt(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, 0);
+ bundle2.putInt(SubscriptionManager.EXTRA_SLOT_INDEX, 2);
+ filter2.setExtras(bundle2);
+ final BroadcastOptions options2 = BroadcastOptions.makeBasic();
+ options2.setDeliveryGroupMatchingFilter(filter2);
+ final BroadcastRecord record2 = createBroadcastRecord(receivers, UserHandle.USER_ALL,
+ intent2, options2);
+
+ final Intent intent3 = new Intent(Intent.ACTION_SERVICE_STATE);
+ intent3.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, 1);
+ intent3.putExtra(SubscriptionManager.EXTRA_SLOT_INDEX, 3);
+ intent3.putExtra(Intent.EXTRA_REASON, "reason3");
+ final IntentFilter filter3 = new IntentFilter(Intent.ACTION_SERVICE_STATE);
+ final PersistableBundle bundle3 = new PersistableBundle();
+ bundle3.putInt(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, 0);
+ bundle3.putInt(SubscriptionManager.EXTRA_SLOT_INDEX, 1);
+ filter3.setExtras(bundle3);
+ final BroadcastOptions options3 = BroadcastOptions.makeBasic();
+ options3.setDeliveryGroupMatchingFilter(filter3);
+ final BroadcastRecord record3 = createBroadcastRecord(receivers, UserHandle.USER_ALL,
+ intent3, options3);
+
+ // record2's matchingFilter doesn't match record1's intent, so their delivery groups
+ // shouldn't match
+ assertFalse(record2.matchesDeliveryGroup(record1));
+ // record3's matchingFilter doesn't match record2's intent, so their delivery groups
+ // shouldn't match
+ assertFalse(record3.matchesDeliveryGroup(record2));
+ // record3's matchingFilter matches record1's intent, so their delivery groups should match.
+ assertTrue(record3.matchesDeliveryGroup(record1));
+ }
+
private BroadcastRecord createBootCompletedBroadcastRecord(String action) {
final List<ResolveInfo> receivers = createReceiverInfos(PACKAGE_LIST, USER_LIST);
final BroadcastRecord br = createBroadcastRecord(receivers, UserHandle.USER_ALL,
@@ -539,11 +657,19 @@ public class BroadcastRecordTest {
private BroadcastRecord createBroadcastRecord(List<ResolveInfo> receivers, int userId,
Intent intent) {
- return createBroadcastRecord(receivers, userId, intent, null);
+ return createBroadcastRecord(receivers, userId, intent, null /* filterExtrasForReceiver */,
+ null /* options */);
+ }
+
+ private BroadcastRecord createBroadcastRecord(List<ResolveInfo> receivers, int userId,
+ Intent intent, BroadcastOptions options) {
+ return createBroadcastRecord(receivers, userId, intent, null /* filterExtrasForReceiver */,
+ options);
}
private BroadcastRecord createBroadcastRecord(List<ResolveInfo> receivers, int userId,
- Intent intent, BiFunction<Integer, Bundle, Bundle> filterExtrasForReceiver) {
+ Intent intent, BiFunction<Integer, Bundle, Bundle> filterExtrasForReceiver,
+ BroadcastOptions options) {
return new BroadcastRecord(
mQueue /* queue */,
intent,
@@ -558,7 +684,7 @@ public class BroadcastRecordTest {
null /* excludedPermissions */,
null /* excludedPackages */,
0 /* appOp */,
- null /* options */,
+ options,
new ArrayList<>(receivers), // Make a copy to not affect the original list.
null /* resultToApp */,
null /* resultTo */,
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
index 1c345484bd41..55d116043f15 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
@@ -17,6 +17,7 @@
package com.android.server.am;
import static android.app.ActivityManager.PROCESS_CAPABILITY_ALL;
+import static android.app.ActivityManager.PROCESS_CAPABILITY_NETWORK;
import static android.app.ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
import static android.app.ActivityManager.PROCESS_STATE_BOUND_TOP;
import static android.app.ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
@@ -94,7 +95,6 @@ import android.os.SystemClock;
import android.os.UserHandle;
import android.platform.test.annotations.Presubmit;
import android.util.ArrayMap;
-import android.util.ArraySet;
import android.util.SparseArray;
import com.android.server.LocalServices;
@@ -414,7 +414,8 @@ public class MockingOomAdjusterTests {
public void testUpdateOomAdj_DoOne_FgServiceLocation() {
ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID,
MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, true));
- app.mServices.setHasForegroundServices(true, ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION);
+ app.mServices.setHasForegroundServices(true, ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION,
+ /* hasNoneType=*/false);
sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
sService.mOomAdjuster.updateOomAdjLocked(app, OomAdjuster.OOM_ADJ_REASON_NONE);
@@ -427,7 +428,7 @@ public class MockingOomAdjusterTests {
public void testUpdateOomAdj_DoOne_FgService() {
ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID,
MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, true));
- app.mServices.setHasForegroundServices(true, 0);
+ app.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true);
sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
sService.mOomAdjuster.updateOomAdjLocked(app, OomAdjuster.OOM_ADJ_REASON_NONE);
@@ -437,6 +438,43 @@ public class MockingOomAdjusterTests {
@SuppressWarnings("GuardedBy")
@Test
+ public void testUpdateOomAdj_DoOne_FgService_ShortFgs() {
+ // SHORT_SERVICE FGS will get IMP_FG and a slightly different recent-adjustment.
+ {
+ ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID,
+ MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, true));
+ app.mServices.setHasForegroundServices(true,
+ ServiceInfo.FOREGROUND_SERVICE_TYPE_SHORT_SERVICE, /* hasNoneType=*/false);
+ app.mState.setLastTopTime(SystemClock.uptimeMillis());
+ sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
+ sService.mOomAdjuster.updateOomAdjLocked(app, OomAdjuster.OOM_ADJ_REASON_NONE);
+
+ assertProcStates(app, PROCESS_STATE_IMPORTANT_FOREGROUND,
+ PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ + 1, SCHED_GROUP_DEFAULT);
+ // Should get network access.
+ assertTrue((app.mState.getSetCapability() & PROCESS_CAPABILITY_NETWORK) != 0);
+ }
+
+ // SHORT_SERVICE, but no longer recent.
+ {
+ ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID,
+ MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, true));
+ app.mServices.setHasForegroundServices(true,
+ ServiceInfo.FOREGROUND_SERVICE_TYPE_SHORT_SERVICE, /* hasNoneType=*/false);
+ app.mState.setLastTopTime(SystemClock.uptimeMillis()
+ - sService.mConstants.TOP_TO_FGS_GRACE_DURATION);
+ sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
+ sService.mOomAdjuster.updateOomAdjLocked(app, OomAdjuster.OOM_ADJ_REASON_NONE);
+
+ assertProcStates(app, PROCESS_STATE_IMPORTANT_FOREGROUND,
+ PERCEPTIBLE_MEDIUM_APP_ADJ + 1, SCHED_GROUP_DEFAULT);
+ // Still should get network access.
+ assertTrue((app.mState.getSetCapability() & PROCESS_CAPABILITY_NETWORK) != 0);
+ }
+ }
+
+ @SuppressWarnings("GuardedBy")
+ @Test
public void testUpdateOomAdj_DoOne_OverlayUi() {
ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID,
MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, true));
@@ -453,7 +491,7 @@ public class MockingOomAdjusterTests {
public void testUpdateOomAdj_DoOne_PerceptibleRecent_FgService() {
ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID,
MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, true));
- app.mServices.setHasForegroundServices(true, 0);
+ app.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true);
app.mState.setLastTopTime(SystemClock.uptimeMillis());
sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
sService.mOomAdjuster.updateOomAdjLocked(app, OomAdjuster.OOM_ADJ_REASON_NONE);
@@ -482,7 +520,7 @@ public class MockingOomAdjusterTests {
sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
sService.mOomAdjuster.updateOomAdjLocked(app, OomAdjuster.OOM_ADJ_REASON_NONE);
- assertEquals(PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ, app.mState.getSetAdj());
+ assertEquals(PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ + 2, app.mState.getSetAdj());
}
// Out of grace period but valid binding allows the adjustment.
@@ -495,14 +533,14 @@ public class MockingOomAdjusterTests {
app.mState.setLastTopTime(nowUptime);
// Simulate the system starting and binding to a service in the app.
ServiceRecord s = bindService(app, system,
- null, Context.BIND_ALMOST_PERCEPTIBLE, mock(IBinder.class));
+ null, Context.BIND_ALMOST_PERCEPTIBLE + 2, mock(IBinder.class));
s.lastTopAlmostPerceptibleBindRequestUptimeMs =
nowUptime - 2 * sService.mConstants.mServiceBindAlmostPerceptibleTimeoutMs;
app.mServices.updateHasTopStartedAlmostPerceptibleServices();
sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
sService.mOomAdjuster.updateOomAdjLocked(app, OomAdjuster.OOM_ADJ_REASON_NONE);
- assertEquals(PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ, app.mState.getSetAdj());
+ assertEquals(PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ + 2, app.mState.getSetAdj());
}
// Out of grace period and no valid binding so no adjustment.
@@ -523,7 +561,7 @@ public class MockingOomAdjusterTests {
sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
sService.mOomAdjuster.updateOomAdjLocked(app, OomAdjuster.OOM_ADJ_REASON_NONE);
- assertNotEquals(PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ, app.mState.getSetAdj());
+ assertNotEquals(PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ + 2, app.mState.getSetAdj());
}
}
@SuppressWarnings("GuardedBy")
@@ -876,7 +914,7 @@ public class MockingOomAdjusterTests {
ProcessRecord client = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID,
MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false));
bindService(app, client, null, 0, mock(IBinder.class));
- client.mServices.setHasForegroundServices(true, 0);
+ client.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true);
sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
sService.mOomAdjuster.updateOomAdjLocked(app, OomAdjuster.OOM_ADJ_REASON_NONE);
@@ -964,7 +1002,7 @@ public class MockingOomAdjusterTests {
sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
sService.mOomAdjuster.updateOomAdjLocked(app, OomAdjuster.OOM_ADJ_REASON_NONE);
- assertEquals(PERCEPTIBLE_MEDIUM_APP_ADJ, app.mState.getSetAdj());
+ assertEquals(PERCEPTIBLE_MEDIUM_APP_ADJ + 2, app.mState.getSetAdj());
}
{
@@ -980,7 +1018,7 @@ public class MockingOomAdjusterTests {
sService.mOomAdjuster.updateOomAdjLocked(app, OomAdjuster.OOM_ADJ_REASON_NONE);
doReturn(false).when(wpc).isHeavyWeightProcess();
- assertEquals(PERCEPTIBLE_MEDIUM_APP_ADJ, app.mState.getSetAdj());
+ assertEquals(PERCEPTIBLE_MEDIUM_APP_ADJ + 2, app.mState.getSetAdj());
}
}
@@ -1068,7 +1106,7 @@ public class MockingOomAdjusterTests {
MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false));
ProcessRecord client = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID,
MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false));
- client.mServices.setHasForegroundServices(true, 0);
+ client.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true);
bindProvider(app, client, null, null, false);
sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
sService.mOomAdjuster.updateOomAdjLocked(app, OomAdjuster.OOM_ADJ_REASON_NONE);
@@ -1137,7 +1175,7 @@ public class MockingOomAdjusterTests {
ProcessRecord client2 = spy(makeDefaultProcessRecord(MOCKAPP3_PID, MOCKAPP3_UID,
MOCKAPP3_PROCESSNAME, MOCKAPP3_PACKAGENAME, false));
bindService(app, client2, null, 0, mock(IBinder.class));
- client2.mServices.setHasForegroundServices(true, 0);
+ client2.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true);
sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
sService.mOomAdjuster.updateOomAdjLocked(app, OomAdjuster.OOM_ADJ_REASON_NONE);
@@ -1156,7 +1194,7 @@ public class MockingOomAdjusterTests {
ProcessRecord client2 = spy(makeDefaultProcessRecord(MOCKAPP3_PID, MOCKAPP3_UID,
MOCKAPP3_PROCESSNAME, MOCKAPP3_PACKAGENAME, false));
bindService(client, client2, null, 0, mock(IBinder.class));
- client2.mServices.setHasForegroundServices(true, 0);
+ client2.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true);
sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
sService.mOomAdjuster.updateOomAdjLocked(app, OomAdjuster.OOM_ADJ_REASON_NONE);
@@ -1175,7 +1213,7 @@ public class MockingOomAdjusterTests {
ProcessRecord client2 = spy(makeDefaultProcessRecord(MOCKAPP3_PID, MOCKAPP3_UID,
MOCKAPP3_PROCESSNAME, MOCKAPP3_PACKAGENAME, false));
bindService(client, client2, null, 0, mock(IBinder.class));
- client2.mServices.setHasForegroundServices(true, 0);
+ client2.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true);
bindService(client2, app, null, 0, mock(IBinder.class));
ArrayList<ProcessRecord> lru = sService.mProcessList.getLruProcessesLOSP();
lru.clear();
@@ -1192,7 +1230,7 @@ public class MockingOomAdjusterTests {
assertProcStates(client2, PROCESS_STATE_FOREGROUND_SERVICE, PERCEPTIBLE_APP_ADJ,
SCHED_GROUP_DEFAULT);
- client2.mServices.setHasForegroundServices(false, 0);
+ client2.mServices.setHasForegroundServices(false, 0, /* hasNoneType=*/false);
sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
sService.mOomAdjuster.updateOomAdjLocked(client2, OomAdjuster.OOM_ADJ_REASON_NONE);
@@ -1213,7 +1251,7 @@ public class MockingOomAdjusterTests {
ProcessRecord client2 = spy(makeDefaultProcessRecord(MOCKAPP3_PID, MOCKAPP3_UID,
MOCKAPP3_PROCESSNAME, MOCKAPP3_PACKAGENAME, false));
bindService(client2, client, null, 0, mock(IBinder.class));
- client.mServices.setHasForegroundServices(true, 0);
+ client.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true);
ArrayList<ProcessRecord> lru = sService.mProcessList.getLruProcessesLOSP();
lru.clear();
lru.add(app);
@@ -1242,7 +1280,7 @@ public class MockingOomAdjusterTests {
MOCKAPP3_PROCESSNAME, MOCKAPP3_PACKAGENAME, false));
bindService(client, client2, null, 0, mock(IBinder.class));
bindService(client2, client, null, 0, mock(IBinder.class));
- client.mServices.setHasForegroundServices(true, 0);
+ client.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true);
ArrayList<ProcessRecord> lru = sService.mProcessList.getLruProcessesLOSP();
lru.clear();
lru.add(app);
@@ -1278,7 +1316,7 @@ public class MockingOomAdjusterTests {
MOCKAPP5_PROCESSNAME, MOCKAPP5_PACKAGENAME, false));
bindService(client3, client4, null, 0, mock(IBinder.class));
bindService(client4, client3, null, 0, mock(IBinder.class));
- client.mServices.setHasForegroundServices(true, 0);
+ client.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true);
ArrayList<ProcessRecord> lru = sService.mProcessList.getLruProcessesLOSP();
lru.clear();
lru.add(app);
@@ -1312,7 +1350,7 @@ public class MockingOomAdjusterTests {
ProcessRecord client2 = spy(makeDefaultProcessRecord(MOCKAPP3_PID, MOCKAPP3_UID,
MOCKAPP3_PROCESSNAME, MOCKAPP3_PACKAGENAME, false));
bindService(client, client2, null, 0, mock(IBinder.class));
- client2.mServices.setHasForegroundServices(true, 0);
+ client2.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true);
bindService(client2, app, null, 0, mock(IBinder.class));
ProcessRecord client3 = spy(makeDefaultProcessRecord(MOCKAPP4_PID, MOCKAPP4_UID,
MOCKAPP4_PROCESSNAME, MOCKAPP4_PACKAGENAME, false));
@@ -1416,7 +1454,7 @@ public class MockingOomAdjusterTests {
bindService(app, client3, null, 0, mock(IBinder.class));
ProcessRecord client4 = spy(makeDefaultProcessRecord(MOCKAPP5_PID, MOCKAPP5_UID,
MOCKAPP5_PROCESSNAME, MOCKAPP5_PACKAGENAME, false));
- client4.mServices.setHasForegroundServices(true, 0);
+ client4.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true);
bindService(app, client4, null, 0, mock(IBinder.class));
ArrayList<ProcessRecord> lru = sService.mProcessList.getLruProcessesLOSP();
lru.clear();
@@ -1445,7 +1483,7 @@ public class MockingOomAdjusterTests {
ProcessRecord client2 = spy(makeDefaultProcessRecord(MOCKAPP3_PID, MOCKAPP3_UID,
MOCKAPP3_PROCESSNAME, MOCKAPP3_PACKAGENAME, false));
bindService(app, client2, null, 0, mock(IBinder.class));
- client2.mServices.setHasForegroundServices(true, 0);
+ client2.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true);
ProcessRecord client3 = spy(makeDefaultProcessRecord(MOCKAPP4_PID, MOCKAPP4_UID,
MOCKAPP4_PROCESSNAME, MOCKAPP4_PACKAGENAME, false));
client3.mState.setForcingToImportant(new Object());
@@ -1468,7 +1506,7 @@ public class MockingOomAdjusterTests {
ProcessRecord client2 = spy(makeDefaultProcessRecord(MOCKAPP3_PID, MOCKAPP3_UID,
MOCKAPP3_PROCESSNAME, MOCKAPP3_PACKAGENAME, false));
bindProvider(client, client2, null, null, false);
- client2.mServices.setHasForegroundServices(true, 0);
+ client2.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true);
sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
sService.mOomAdjuster.updateOomAdjLocked(app, OomAdjuster.OOM_ADJ_REASON_NONE);
@@ -1487,7 +1525,7 @@ public class MockingOomAdjusterTests {
ProcessRecord client2 = spy(makeDefaultProcessRecord(MOCKAPP3_PID, MOCKAPP3_UID,
MOCKAPP3_PROCESSNAME, MOCKAPP3_PACKAGENAME, false));
bindProvider(client, client2, null, null, false);
- client2.mServices.setHasForegroundServices(true, 0);
+ client2.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true);
bindService(client2, app, null, 0, mock(IBinder.class));
ArrayList<ProcessRecord> lru = sService.mProcessList.getLruProcessesLOSP();
lru.clear();
@@ -1512,7 +1550,7 @@ public class MockingOomAdjusterTests {
ProcessRecord client2 = spy(makeDefaultProcessRecord(MOCKAPP3_PID, MOCKAPP3_UID,
MOCKAPP3_PROCESSNAME, MOCKAPP3_PACKAGENAME, false));
bindProvider(client, client2, null, null, false);
- client2.mServices.setHasForegroundServices(true, 0);
+ client2.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true);
sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
sService.mOomAdjuster.updateOomAdjLocked(app, OomAdjuster.OOM_ADJ_REASON_NONE);
@@ -1531,7 +1569,7 @@ public class MockingOomAdjusterTests {
ProcessRecord client2 = spy(makeDefaultProcessRecord(MOCKAPP3_PID, MOCKAPP3_UID,
MOCKAPP3_PROCESSNAME, MOCKAPP3_PACKAGENAME, false));
bindProvider(client, client2, null, null, false);
- client2.mServices.setHasForegroundServices(true, 0);
+ client2.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true);
bindProvider(client2, app, null, null, false);
ArrayList<ProcessRecord> lru = sService.mProcessList.getLruProcessesLOSP();
lru.clear();
@@ -1562,7 +1600,7 @@ public class MockingOomAdjusterTests {
bindService(app2, client2, null, Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE,
mock(IBinder.class));
client1.mState.setMaxAdj(PERSISTENT_PROC_ADJ);
- client2.mServices.setHasForegroundServices(true, 0);
+ client2.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true);
sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
sService.mOomAdjuster.updateOomAdjLocked(app1, OomAdjuster.OOM_ADJ_REASON_NONE);
@@ -1629,7 +1667,7 @@ public class MockingOomAdjusterTests {
s2.getConnections().clear();
client1.mState.setMaxAdj(UNKNOWN_ADJ);
client2.mState.setMaxAdj(UNKNOWN_ADJ);
- client1.mServices.setHasForegroundServices(true, 0);
+ client1.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true);
client2.mState.setHasOverlayUi(true);
bindService(app1, client1, s1, Context.BIND_TREAT_LIKE_VISIBLE_FOREGROUND_SERVICE,
@@ -1657,6 +1695,46 @@ public class MockingOomAdjusterTests {
@SuppressWarnings("GuardedBy")
@Test
+ public void testUpdateOomAdj_DoOne_BindNotPerceptibleFGS() {
+ final ProcessRecord app1 = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID,
+ MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false));
+ final ProcessRecord client1 = spy(makeDefaultProcessRecord(MOCKAPP3_PID, MOCKAPP3_UID,
+ MOCKAPP3_PROCESSNAME, MOCKAPP3_PACKAGENAME, false));
+ client1.mState.setMaxAdj(PERSISTENT_PROC_ADJ);
+
+ app1.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true);
+ sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
+
+ bindService(app1, client1, null, Context.BIND_NOT_PERCEPTIBLE, mock(IBinder.class));
+
+ sService.mOomAdjuster.updateOomAdjLocked(app1, OomAdjuster.OOM_ADJ_REASON_NONE);
+
+ assertProcStates(app1, PROCESS_STATE_FOREGROUND_SERVICE, PERCEPTIBLE_APP_ADJ,
+ SCHED_GROUP_DEFAULT);
+ }
+
+ @SuppressWarnings("GuardedBy")
+ @Test
+ public void testUpdateOomAdj_DoOne_BindAlmostPerceptibleFGS() {
+ final ProcessRecord app1 = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID,
+ MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false));
+ final ProcessRecord client1 = spy(makeDefaultProcessRecord(MOCKAPP3_PID, MOCKAPP3_UID,
+ MOCKAPP3_PROCESSNAME, MOCKAPP3_PACKAGENAME, false));
+ client1.mState.setMaxAdj(PERSISTENT_PROC_ADJ);
+
+ app1.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true);
+ sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
+
+ bindService(app1, client1, null, Context.BIND_ALMOST_PERCEPTIBLE, mock(IBinder.class));
+
+ sService.mOomAdjuster.updateOomAdjLocked(app1, OomAdjuster.OOM_ADJ_REASON_NONE);
+
+ assertProcStates(app1, PROCESS_STATE_FOREGROUND_SERVICE, PERCEPTIBLE_APP_ADJ,
+ SCHED_GROUP_DEFAULT);
+ }
+
+ @SuppressWarnings("GuardedBy")
+ @Test
public void testUpdateOomAdj_UidIdle_StopService() {
final ProcessRecord app1 = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID,
MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false));
@@ -1678,7 +1756,7 @@ public class MockingOomAdjusterTests {
client1.setUidRecord(clientUidRecord);
client2.setUidRecord(clientUidRecord);
- client1.mServices.setHasForegroundServices(true, 0);
+ client1.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true);
client2.mState.setForcingToImportant(new Object());
ArrayList<ProcessRecord> lru = sService.mProcessList.getLruProcessesLOSP();
lru.clear();
@@ -1735,7 +1813,7 @@ public class MockingOomAdjusterTests {
assertEquals(PROCESS_STATE_TRANSIENT_BACKGROUND, app2.mState.getSetProcState());
assertEquals(PROCESS_STATE_TRANSIENT_BACKGROUND, client2.mState.getSetProcState());
- client1.mServices.setHasForegroundServices(false, 0);
+ client1.mServices.setHasForegroundServices(false, 0, /* hasNoneType=*/false);
client2.mState.setForcingToImportant(null);
app1UidRecord.reset();
app2UidRecord.reset();
@@ -1772,7 +1850,7 @@ public class MockingOomAdjusterTests {
app.mState.setForcingToImportant(new Object());
ProcessRecord app2 = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID,
MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false));
- app2.mServices.setHasForegroundServices(true, 0);
+ app2.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true);
ArrayList<ProcessRecord> lru = sService.mProcessList.getLruProcessesLOSP();
lru.clear();
lru.add(app);
@@ -1795,7 +1873,7 @@ public class MockingOomAdjusterTests {
app.mState.setForcingToImportant(new Object());
ProcessRecord app2 = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID,
MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false));
- app2.mServices.setHasForegroundServices(true, 0);
+ app2.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true);
bindService(app, app2, null, 0, mock(IBinder.class));
ArrayList<ProcessRecord> lru = sService.mProcessList.getLruProcessesLOSP();
lru.clear();
@@ -1822,7 +1900,7 @@ public class MockingOomAdjusterTests {
ProcessRecord app3 = spy(makeDefaultProcessRecord(MOCKAPP3_PID, MOCKAPP3_UID,
MOCKAPP3_PROCESSNAME, MOCKAPP3_PACKAGENAME, false));
bindService(app2, app3, null, 0, mock(IBinder.class));
- app3.mServices.setHasForegroundServices(true, 0);
+ app3.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true);
bindService(app3, app, null, 0, mock(IBinder.class));
ArrayList<ProcessRecord> lru = sService.mProcessList.getLruProcessesLOSP();
lru.clear();
@@ -1870,7 +1948,7 @@ public class MockingOomAdjusterTests {
bindService(app, app4, s, 0, mock(IBinder.class));
ProcessRecord app5 = spy(makeDefaultProcessRecord(MOCKAPP5_PID, MOCKAPP5_UID,
MOCKAPP5_PROCESSNAME, MOCKAPP5_PACKAGENAME, false));
- app5.mServices.setHasForegroundServices(true, 0);
+ app5.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true);
bindService(app, app5, s, 0, mock(IBinder.class));
ArrayList<ProcessRecord> lru = sService.mProcessList.getLruProcessesLOSP();
lru.clear();
@@ -1915,7 +1993,7 @@ public class MockingOomAdjusterTests {
bindService(app, app4, s, 0, mock(IBinder.class));
ProcessRecord app5 = spy(makeDefaultProcessRecord(MOCKAPP5_PID, MOCKAPP5_UID,
MOCKAPP5_PROCESSNAME, MOCKAPP5_PACKAGENAME, false));
- app5.mServices.setHasForegroundServices(true, 0);
+ app5.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true);
bindService(app, app5, s, 0, mock(IBinder.class));
ArrayList<ProcessRecord> lru = sService.mProcessList.getLruProcessesLOSP();
lru.clear();
@@ -1960,7 +2038,7 @@ public class MockingOomAdjusterTests {
bindService(app, app4, s, 0, mock(IBinder.class));
ProcessRecord app5 = spy(makeDefaultProcessRecord(MOCKAPP5_PID, MOCKAPP5_UID,
MOCKAPP5_PROCESSNAME, MOCKAPP5_PACKAGENAME, false));
- app5.mServices.setHasForegroundServices(true, 0);
+ app5.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true);
bindService(app, app5, s, 0, mock(IBinder.class));
ArrayList<ProcessRecord> lru = sService.mProcessList.getLruProcessesLOSP();
lru.clear();
@@ -2035,7 +2113,7 @@ public class MockingOomAdjusterTests {
bindProvider(app, app4, cr, null, false);
ProcessRecord app5 = spy(makeDefaultProcessRecord(MOCKAPP5_PID, MOCKAPP5_UID,
MOCKAPP5_PROCESSNAME, MOCKAPP5_PACKAGENAME, false));
- app5.mServices.setHasForegroundServices(true, 0);
+ app5.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true);
bindProvider(app, app5, cr, null, false);
ArrayList<ProcessRecord> lru = sService.mProcessList.getLruProcessesLOSP();
lru.clear();
@@ -2282,7 +2360,8 @@ public class MockingOomAdjusterTests {
services.setConnectionGroup(connectionGroup);
services.setConnectionImportance(connectionImportance);
services.setHasClientActivities(hasClientActivities);
- services.setHasForegroundServices(hasForegroundServices, fgServiceTypes);
+ services.setHasForegroundServices(hasForegroundServices, fgServiceTypes,
+ /* hasNoneType=*/false);
services.setHasAboveClient(hasAboveClient);
services.setTreatLikeActivity(treatLikeActivity);
services.setExecServicesFg(execServicesFg);
diff --git a/services/tests/mockingservicestests/src/com/android/server/app/GameManagerServiceTests.java b/services/tests/mockingservicestests/src/com/android/server/app/GameManagerServiceTests.java
index 24e5175ecbdc..dc77762795c7 100644
--- a/services/tests/mockingservicestests/src/com/android/server/app/GameManagerServiceTests.java
+++ b/services/tests/mockingservicestests/src/com/android/server/app/GameManagerServiceTests.java
@@ -19,6 +19,7 @@ package com.android.server.app;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
import static com.android.server.app.GameManagerService.WRITE_SETTINGS;
+import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
@@ -32,6 +33,7 @@ import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -39,8 +41,10 @@ import static org.mockito.Mockito.when;
import android.Manifest;
import android.annotation.Nullable;
import android.app.GameManager;
+import android.app.GameModeConfiguration;
import android.app.GameModeInfo;
import android.app.GameState;
+import android.app.IGameModeListener;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.ContextWrapper;
@@ -55,12 +59,13 @@ import android.content.res.Resources;
import android.content.res.XmlResourceParser;
import android.hardware.power.Mode;
import android.os.Bundle;
+import android.os.IBinder;
import android.os.PowerManagerInternal;
+import android.os.RemoteException;
import android.os.UserManager;
import android.os.test.TestLooper;
import android.platform.test.annotations.Presubmit;
import android.provider.DeviceConfig;
-import android.util.ArraySet;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
@@ -73,7 +78,9 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
import org.mockito.ArgumentMatchers;
+import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoSession;
@@ -82,6 +89,7 @@ import org.mockito.quality.Strictness;
import java.io.File;
import java.nio.file.Files;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.function.Supplier;
@@ -108,6 +116,9 @@ public class GameManagerServiceTests {
private UserManager mMockUserManager;
private BroadcastReceiver mShutDownActionReceiver;
+ @Captor
+ ArgumentCaptor<IBinder.DeathRecipient> mDeathRecipientCaptor;
+
// Stolen from ConnectivityServiceTest.MockContext
class MockContext extends ContextWrapper {
private static final String TAG = "MockContext";
@@ -178,7 +189,7 @@ public class GameManagerServiceTests {
@Override
public Intent registerReceiver(@Nullable BroadcastReceiver receiver, IntentFilter filter) {
- mShutDownActionReceiver = receiver;
+ mShutDownActionReceiver = receiver;
return null;
}
}
@@ -387,6 +398,17 @@ public class GameManagerServiceTests {
.thenReturn(applicationInfo);
}
+ private void mockInterventionsEnabledBatteryOptInFromXml() throws Exception {
+ seedGameManagerServiceMetaDataFromFile(mPackageName, 123, "res/xml/"
+ + "game_manager_service_metadata_config_interventions_enabled_battery_opt_in.xml");
+ }
+
+ private void mockInterventionsEnabledPerformanceOptInFromXml() throws Exception {
+ seedGameManagerServiceMetaDataFromFile(mPackageName, 123, "res/xml/"
+ + "game_manager_service_metadata_config_interventions_enabled_performance_opt_in"
+ + ".xml");
+ }
+
private void mockInterventionsEnabledNoOptInFromXml() throws Exception {
seedGameManagerServiceMetaDataFromFile(mPackageName, 123,
"res/xml/game_manager_service_metadata_config_interventions_enabled_no_opt_in.xml");
@@ -431,7 +453,7 @@ public class GameManagerServiceTests {
}
/**
- * By default game mode is not supported.
+ * By default game mode is set to STANDARD
*/
@Test
public void testGameModeDefaultValue() {
@@ -441,7 +463,7 @@ public class GameManagerServiceTests {
startUser(gameManagerService, USER_ID_1);
mockModifyGameModeGranted();
- assertEquals(GameManager.GAME_MODE_UNSUPPORTED,
+ assertEquals(GameManager.GAME_MODE_STANDARD,
gameManagerService.getGameMode(mPackageName, USER_ID_1));
}
@@ -457,7 +479,7 @@ public class GameManagerServiceTests {
mockModifyGameModeGranted();
gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_STANDARD, USER_ID_2);
- assertEquals(GameManager.GAME_MODE_UNSUPPORTED,
+ assertEquals(GameManager.GAME_MODE_STANDARD,
gameManagerService.getGameMode(mPackageName, USER_ID_2));
}
@@ -473,7 +495,7 @@ public class GameManagerServiceTests {
startUser(gameManagerService, USER_ID_1);
gameManagerService.updateConfigsForUser(USER_ID_1, true, mPackageName);
mockModifyGameModeGranted();
- assertEquals(GameManager.GAME_MODE_UNSUPPORTED,
+ assertEquals(GameManager.GAME_MODE_STANDARD,
gameManagerService.getGameMode(mPackageName, USER_ID_1));
// We need to make sure the mode is supported before setting it.
mockDeviceConfigAll();
@@ -580,31 +602,42 @@ public class GameManagerServiceTests {
gameManagerService.getGameMode(mPackageName, USER_ID_2));
}
- private void checkReportedModes(GameManagerService gameManagerService, int ...requiredModes) {
- if (gameManagerService == null) {
- gameManagerService = new GameManagerService(mMockContext, mTestLooper.getLooper());
- startUser(gameManagerService, USER_ID_1);
- gameManagerService.updateConfigsForUser(USER_ID_1, true, mPackageName);
- }
- ArraySet<Integer> reportedModes = new ArraySet<>();
- int[] modes = gameManagerService.getAvailableGameModes(mPackageName);
- for (int mode : modes) {
- reportedModes.add(mode);
- }
- assertEquals(requiredModes.length, reportedModes.size());
- for (int requiredMode : requiredModes) {
- assertTrue("Required game mode not supported: " + requiredMode,
- reportedModes.contains(requiredMode));
- }
+ private GameManagerService createServiceAndStartUser(int userId) {
+ GameManagerService gameManagerService = new GameManagerService(mMockContext,
+ mTestLooper.getLooper());
+ startUser(gameManagerService, userId);
+ return gameManagerService;
+ }
+
+ private void checkReportedAvailableGameModes(GameManagerService gameManagerService,
+ int... requiredAvailableModes) {
+ Arrays.sort(requiredAvailableModes);
+ // check getAvailableGameModes
+ int[] reportedAvailableModes = gameManagerService.getAvailableGameModes(mPackageName);
+ Arrays.sort(reportedAvailableModes);
+ assertArrayEquals(requiredAvailableModes, reportedAvailableModes);
+
+ // check GetModeInfo.getAvailableGameModes
+ GameModeInfo info = gameManagerService.getGameModeInfo(mPackageName, USER_ID_1);
+ assertNotNull(info);
+ reportedAvailableModes = info.getAvailableGameModes();
+ Arrays.sort(reportedAvailableModes);
+ assertArrayEquals(requiredAvailableModes, reportedAvailableModes);
+ }
+
+ private void checkReportedOptedInGameModes(GameManagerService gameManagerService,
+ int... requiredOptedInModes) {
+ Arrays.sort(requiredOptedInModes);
+ // check GetModeInfo.getOptedInGameModes
+ GameModeInfo info = gameManagerService.getGameModeInfo(mPackageName, USER_ID_1);
+ assertNotNull(info);
+ int[] optedInModes = info.getOptedInGameModes();
+ Arrays.sort(optedInModes);
+ assertArrayEquals(requiredOptedInModes, optedInModes);
}
private void checkDownscaling(GameManagerService gameManagerService,
- int gameMode, float scaling) {
- if (gameManagerService == null) {
- gameManagerService = new GameManagerService(mMockContext, mTestLooper.getLooper());
- startUser(gameManagerService, USER_ID_1);
- gameManagerService.updateConfigsForUser(USER_ID_1, true, mPackageName);
- }
+ int gameMode, float scaling) {
GameManagerService.GamePackageConfiguration config =
gameManagerService.getConfig(mPackageName, USER_ID_1);
assertEquals(scaling, config.getGameModeConfiguration(gameMode).getScaling(), 0.01f);
@@ -625,8 +658,6 @@ public class GameManagerServiceTests {
private void checkLoadingBoost(GameManagerService gameManagerService, int gameMode,
int loadingBoost) {
- gameManagerService.updateConfigsForUser(USER_ID_1, true, mPackageName);
-
// Validate GamePackageConfiguration returns the correct value.
GameManagerService.GamePackageConfiguration config =
gameManagerService.getConfig(mPackageName, USER_ID_1);
@@ -639,11 +670,6 @@ public class GameManagerServiceTests {
}
private void checkFps(GameManagerService gameManagerService, int gameMode, int fps) {
- if (gameManagerService == null) {
- gameManagerService = new GameManagerService(mMockContext, mTestLooper.getLooper());
- startUser(gameManagerService, USER_ID_1);
- gameManagerService.updateConfigsForUser(USER_ID_1, true, mPackageName);
- }
GameManagerService.GamePackageConfiguration config =
gameManagerService.getConfig(mPackageName, USER_ID_1);
assertEquals(fps, config.getGameModeConfiguration(gameMode).getFps());
@@ -662,7 +688,8 @@ public class GameManagerServiceTests {
public void testDeviceConfigDefault() {
mockDeviceConfigDefault();
mockModifyGameModeGranted();
- checkReportedModes(null);
+ checkReportedAvailableGameModes(createServiceAndStartUser(USER_ID_1),
+ GameManager.GAME_MODE_STANDARD, GameManager.GAME_MODE_CUSTOM);
}
/**
@@ -672,38 +699,8 @@ public class GameManagerServiceTests {
public void testDeviceConfigNone() {
mockDeviceConfigNone();
mockModifyGameModeGranted();
- checkReportedModes(null);
- }
-
- /**
- * Phenotype device config for performance mode exists and is valid.
- */
- @Test
- public void testDeviceConfigPerformance() {
- mockDeviceConfigPerformance();
- mockModifyGameModeGranted();
- checkReportedModes(null, GameManager.GAME_MODE_PERFORMANCE, GameManager.GAME_MODE_STANDARD);
- }
-
- /**
- * Phenotype device config for battery mode exists and is valid.
- */
- @Test
- public void testDeviceConfigBattery() {
- mockDeviceConfigBattery();
- mockModifyGameModeGranted();
- checkReportedModes(null, GameManager.GAME_MODE_BATTERY, GameManager.GAME_MODE_STANDARD);
- }
-
- /**
- * Phenotype device configs for both battery and performance modes exists and are valid.
- */
- @Test
- public void testDeviceConfigAll() {
- mockDeviceConfigAll();
- mockModifyGameModeGranted();
- checkReportedModes(null, GameManager.GAME_MODE_PERFORMANCE, GameManager.GAME_MODE_BATTERY,
- GameManager.GAME_MODE_STANDARD);
+ checkReportedAvailableGameModes(createServiceAndStartUser(USER_ID_1),
+ GameManager.GAME_MODE_STANDARD, GameManager.GAME_MODE_CUSTOM);
}
/**
@@ -713,7 +710,8 @@ public class GameManagerServiceTests {
public void testDeviceConfigInvalid() {
mockDeviceConfigInvalid();
mockModifyGameModeGranted();
- checkReportedModes(null);
+ checkReportedAvailableGameModes(createServiceAndStartUser(USER_ID_1),
+ GameManager.GAME_MODE_STANDARD, GameManager.GAME_MODE_CUSTOM);
}
/**
@@ -723,7 +721,8 @@ public class GameManagerServiceTests {
public void testDeviceConfigMalformed() {
mockDeviceConfigMalformed();
mockModifyGameModeGranted();
- checkReportedModes(null);
+ checkReportedAvailableGameModes(createServiceAndStartUser(USER_ID_1),
+ GameManager.GAME_MODE_STANDARD, GameManager.GAME_MODE_CUSTOM);
}
/**
@@ -740,8 +739,8 @@ public class GameManagerServiceTests {
gameManagerService.setGameModeConfigOverride(mPackageName, USER_ID_1,
GameManager.GAME_MODE_PERFORMANCE, "120", "0.3");
- checkReportedModes(gameManagerService, GameManager.GAME_MODE_PERFORMANCE,
- GameManager.GAME_MODE_STANDARD);
+ checkReportedAvailableGameModes(gameManagerService, GameManager.GAME_MODE_PERFORMANCE,
+ GameManager.GAME_MODE_STANDARD, GameManager.GAME_MODE_CUSTOM);
checkDownscaling(gameManagerService, GameManager.GAME_MODE_PERFORMANCE, 0.3f);
checkFps(gameManagerService, GameManager.GAME_MODE_PERFORMANCE, 120);
}
@@ -760,8 +759,8 @@ public class GameManagerServiceTests {
gameManagerService.setGameModeConfigOverride(mPackageName, USER_ID_1,
GameManager.GAME_MODE_BATTERY, "60", "0.5");
- checkReportedModes(gameManagerService, GameManager.GAME_MODE_BATTERY,
- GameManager.GAME_MODE_STANDARD);
+ checkReportedAvailableGameModes(gameManagerService, GameManager.GAME_MODE_BATTERY,
+ GameManager.GAME_MODE_STANDARD, GameManager.GAME_MODE_CUSTOM);
checkDownscaling(gameManagerService, GameManager.GAME_MODE_BATTERY, 0.5f);
checkFps(gameManagerService, GameManager.GAME_MODE_BATTERY, 60);
}
@@ -782,8 +781,9 @@ public class GameManagerServiceTests {
gameManagerService.setGameModeConfigOverride(mPackageName, USER_ID_1,
GameManager.GAME_MODE_BATTERY, "60", "0.5");
- checkReportedModes(gameManagerService, GameManager.GAME_MODE_PERFORMANCE,
- GameManager.GAME_MODE_BATTERY, GameManager.GAME_MODE_STANDARD);
+ checkReportedAvailableGameModes(gameManagerService, GameManager.GAME_MODE_PERFORMANCE,
+ GameManager.GAME_MODE_BATTERY, GameManager.GAME_MODE_STANDARD,
+ GameManager.GAME_MODE_CUSTOM);
checkDownscaling(gameManagerService, GameManager.GAME_MODE_PERFORMANCE, 0.3f);
checkFps(gameManagerService, GameManager.GAME_MODE_PERFORMANCE, 120);
checkDownscaling(gameManagerService, GameManager.GAME_MODE_BATTERY, 0.5f);
@@ -876,8 +876,8 @@ public class GameManagerServiceTests {
gameManagerService.resetGameModeConfigOverride(mPackageName, USER_ID_1,
GameManager.GAME_MODE_PERFORMANCE);
- checkReportedModes(gameManagerService, GameManager.GAME_MODE_PERFORMANCE,
- GameManager.GAME_MODE_STANDARD);
+ checkReportedAvailableGameModes(gameManagerService, GameManager.GAME_MODE_PERFORMANCE,
+ GameManager.GAME_MODE_STANDARD, GameManager.GAME_MODE_CUSTOM);
checkDownscaling(gameManagerService, GameManager.GAME_MODE_PERFORMANCE, 0.5f);
checkFps(gameManagerService, GameManager.GAME_MODE_PERFORMANCE, 90);
}
@@ -899,8 +899,8 @@ public class GameManagerServiceTests {
gameManagerService.resetGameModeConfigOverride(mPackageName, USER_ID_1,
GameManager.GAME_MODE_BATTERY);
- checkReportedModes(gameManagerService, GameManager.GAME_MODE_BATTERY,
- GameManager.GAME_MODE_STANDARD);
+ checkReportedAvailableGameModes(gameManagerService, GameManager.GAME_MODE_BATTERY,
+ GameManager.GAME_MODE_STANDARD, GameManager.GAME_MODE_CUSTOM);
checkDownscaling(gameManagerService, GameManager.GAME_MODE_BATTERY, 0.7f);
checkFps(gameManagerService, GameManager.GAME_MODE_BATTERY, 30);
}
@@ -923,8 +923,9 @@ public class GameManagerServiceTests {
gameManagerService.resetGameModeConfigOverride(mPackageName, USER_ID_1, -1);
- checkReportedModes(gameManagerService, GameManager.GAME_MODE_PERFORMANCE,
- GameManager.GAME_MODE_BATTERY, GameManager.GAME_MODE_STANDARD);
+ checkReportedAvailableGameModes(gameManagerService, GameManager.GAME_MODE_PERFORMANCE,
+ GameManager.GAME_MODE_BATTERY, GameManager.GAME_MODE_STANDARD,
+ GameManager.GAME_MODE_CUSTOM);
checkDownscaling(gameManagerService, GameManager.GAME_MODE_PERFORMANCE, 0.5f);
checkFps(gameManagerService, GameManager.GAME_MODE_PERFORMANCE, 90);
checkDownscaling(gameManagerService, GameManager.GAME_MODE_BATTERY, 0.7f);
@@ -952,8 +953,9 @@ public class GameManagerServiceTests {
gameManagerService.resetGameModeConfigOverride(mPackageName, USER_ID_1,
GameManager.GAME_MODE_BATTERY);
- checkReportedModes(gameManagerService, GameManager.GAME_MODE_PERFORMANCE,
- GameManager.GAME_MODE_BATTERY, GameManager.GAME_MODE_STANDARD);
+ checkReportedAvailableGameModes(gameManagerService, GameManager.GAME_MODE_PERFORMANCE,
+ GameManager.GAME_MODE_BATTERY, GameManager.GAME_MODE_STANDARD,
+ GameManager.GAME_MODE_CUSTOM);
checkDownscaling(gameManagerService, GameManager.GAME_MODE_PERFORMANCE, 0.3f);
checkFps(gameManagerService, GameManager.GAME_MODE_PERFORMANCE, 120);
checkDownscaling(gameManagerService, GameManager.GAME_MODE_BATTERY, 0.7f);
@@ -968,12 +970,12 @@ public class GameManagerServiceTests {
mockGameModeOptInAll();
mockDeviceConfigNone();
mockModifyGameModeGranted();
- checkReportedModes(null, GameManager.GAME_MODE_PERFORMANCE, GameManager.GAME_MODE_BATTERY,
- GameManager.GAME_MODE_STANDARD);
+ checkReportedAvailableGameModes(createServiceAndStartUser(USER_ID_1),
+ GameManager.GAME_MODE_PERFORMANCE, GameManager.GAME_MODE_BATTERY,
+ GameManager.GAME_MODE_STANDARD, GameManager.GAME_MODE_CUSTOM);
}
-
/**
* BATTERY game mode is available through the app manifest opt-in.
*/
@@ -982,7 +984,9 @@ public class GameManagerServiceTests {
mockGameModeOptInBattery();
mockDeviceConfigNone();
mockModifyGameModeGranted();
- checkReportedModes(null, GameManager.GAME_MODE_BATTERY, GameManager.GAME_MODE_STANDARD);
+ checkReportedAvailableGameModes(createServiceAndStartUser(USER_ID_1),
+ GameManager.GAME_MODE_BATTERY, GameManager.GAME_MODE_STANDARD,
+ GameManager.GAME_MODE_CUSTOM);
}
/**
@@ -993,7 +997,9 @@ public class GameManagerServiceTests {
mockGameModeOptInPerformance();
mockDeviceConfigNone();
mockModifyGameModeGranted();
- checkReportedModes(null, GameManager.GAME_MODE_PERFORMANCE, GameManager.GAME_MODE_STANDARD);
+ checkReportedAvailableGameModes(createServiceAndStartUser(USER_ID_1),
+ GameManager.GAME_MODE_PERFORMANCE, GameManager.GAME_MODE_STANDARD,
+ GameManager.GAME_MODE_CUSTOM);
}
/**
@@ -1005,8 +1011,9 @@ public class GameManagerServiceTests {
mockGameModeOptInBattery();
mockDeviceConfigPerformance();
mockModifyGameModeGranted();
- checkReportedModes(null, GameManager.GAME_MODE_PERFORMANCE, GameManager.GAME_MODE_BATTERY,
- GameManager.GAME_MODE_STANDARD);
+ checkReportedAvailableGameModes(createServiceAndStartUser(USER_ID_1),
+ GameManager.GAME_MODE_PERFORMANCE, GameManager.GAME_MODE_BATTERY,
+ GameManager.GAME_MODE_STANDARD, GameManager.GAME_MODE_CUSTOM);
}
/**
@@ -1018,8 +1025,9 @@ public class GameManagerServiceTests {
mockGameModeOptInPerformance();
mockDeviceConfigBattery();
mockModifyGameModeGranted();
- checkReportedModes(null, GameManager.GAME_MODE_PERFORMANCE, GameManager.GAME_MODE_BATTERY,
- GameManager.GAME_MODE_STANDARD);
+ checkReportedAvailableGameModes(createServiceAndStartUser(USER_ID_1),
+ GameManager.GAME_MODE_PERFORMANCE, GameManager.GAME_MODE_BATTERY,
+ GameManager.GAME_MODE_STANDARD, GameManager.GAME_MODE_CUSTOM);
}
/**
@@ -1029,7 +1037,8 @@ public class GameManagerServiceTests {
public void testInterventionAllowScalingDefault() throws Exception {
mockDeviceConfigPerformance();
mockModifyGameModeGranted();
- checkDownscaling(null, GameManager.GAME_MODE_PERFORMANCE, 0.5f);
+ checkDownscaling(createServiceAndStartUser(USER_ID_1), GameManager.GAME_MODE_PERFORMANCE,
+ 0.5f);
}
/**
@@ -1040,7 +1049,8 @@ public class GameManagerServiceTests {
mockDeviceConfigPerformance();
mockInterventionAllowDownscaleFalse();
mockModifyGameModeGranted();
- checkDownscaling(null, GameManager.GAME_MODE_PERFORMANCE, -1.0f);
+ checkDownscaling(createServiceAndStartUser(USER_ID_1), GameManager.GAME_MODE_PERFORMANCE,
+ -1.0f);
}
/**
@@ -1052,7 +1062,8 @@ public class GameManagerServiceTests {
mockDeviceConfigPerformance();
mockInterventionAllowDownscaleTrue();
mockModifyGameModeGranted();
- checkDownscaling(null, GameManager.GAME_MODE_PERFORMANCE, 0.5f);
+ checkDownscaling(createServiceAndStartUser(USER_ID_1), GameManager.GAME_MODE_PERFORMANCE,
+ 0.5f);
}
/**
@@ -1060,12 +1071,9 @@ public class GameManagerServiceTests {
*/
@Test
public void testInterventionAllowAngleDefault() throws Exception {
- GameManagerService gameManagerService = new GameManagerService(
- mMockContext, mTestLooper.getLooper());
-
- startUser(gameManagerService, USER_ID_1);
mockDeviceConfigPerformance();
mockModifyGameModeGranted();
+ GameManagerService gameManagerService = createServiceAndStartUser(USER_ID_1);
checkAngleEnabled(gameManagerService, GameManager.GAME_MODE_PERFORMANCE, false);
}
@@ -1075,12 +1083,9 @@ public class GameManagerServiceTests {
*/
@Test
public void testInterventionAllowLoadingBoostDefault() throws Exception {
- GameManagerService gameManagerService = new GameManagerService(
- mMockContext, mTestLooper.getLooper());
-
- startUser(gameManagerService, USER_ID_1);
mockDeviceConfigPerformance();
mockModifyGameModeGranted();
+ GameManagerService gameManagerService = createServiceAndStartUser(USER_ID_1);
checkLoadingBoost(gameManagerService, GameManager.GAME_MODE_PERFORMANCE, -1);
}
@@ -1089,12 +1094,10 @@ public class GameManagerServiceTests {
*/
@Test
public void testInterventionAllowAngleFalse() throws Exception {
- GameManagerService gameManagerService =
- new GameManagerService(mMockContext, mTestLooper.getLooper());
- startUser(gameManagerService, USER_ID_1);
mockDeviceConfigPerformanceEnableAngle();
mockInterventionAllowAngleFalse();
mockModifyGameModeGranted();
+ GameManagerService gameManagerService = createServiceAndStartUser(USER_ID_1);
checkAngleEnabled(gameManagerService, GameManager.GAME_MODE_PERFORMANCE, false);
}
@@ -1171,8 +1174,9 @@ public class GameManagerServiceTests {
public void testInterventionFps() throws Exception {
mockDeviceConfigAll();
mockModifyGameModeGranted();
- checkFps(null, GameManager.GAME_MODE_PERFORMANCE, 90);
- checkFps(null, GameManager.GAME_MODE_BATTERY, 30);
+ GameManagerService service = createServiceAndStartUser(USER_ID_1);
+ checkFps(service, GameManager.GAME_MODE_PERFORMANCE, 90);
+ checkFps(service, GameManager.GAME_MODE_BATTERY, 30);
}
/**
@@ -1195,7 +1199,7 @@ public class GameManagerServiceTests {
/**
* Ensure that, if a game no longer supports any game modes, we set the game mode to
- * UNSUPPORTED
+ * STANDARD
*/
@Test
public void testUnsetInvalidGameMode() throws Exception {
@@ -1206,7 +1210,7 @@ public class GameManagerServiceTests {
startUser(gameManagerService, USER_ID_1);
gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_PERFORMANCE, USER_ID_1);
gameManagerService.updateConfigsForUser(USER_ID_1, true, mPackageName);
- assertEquals(GameManager.GAME_MODE_UNSUPPORTED,
+ assertEquals(GameManager.GAME_MODE_STANDARD,
gameManagerService.getGameMode(mPackageName, USER_ID_1));
}
@@ -1247,6 +1251,7 @@ public class GameManagerServiceTests {
static {
System.loadLibrary("mockingservicestestjni");
}
+
@Test
public void testGetGameModeInfoPermissionDenied() {
mockDeviceConfigAll();
@@ -1261,30 +1266,30 @@ public class GameManagerServiceTests {
}
@Test
- public void testGetGameModeInfoWithAllGameModesDefault() {
+ public void testGetGameModeInfoWithAllGameModes() {
mockDeviceConfigAll();
mockModifyGameModeGranted();
GameManagerService gameManagerService =
new GameManagerService(mMockContext, mTestLooper.getLooper());
startUser(gameManagerService, USER_ID_1);
GameModeInfo gameModeInfo = gameManagerService.getGameModeInfo(mPackageName, USER_ID_1);
-
assertEquals(GameManager.GAME_MODE_STANDARD, gameModeInfo.getActiveGameMode());
- assertEquals(3, gameModeInfo.getAvailableGameModes().length);
- }
+ assertTrue(gameModeInfo.isDownscalingAllowed());
+ assertTrue(gameModeInfo.isFpsOverrideAllowed());
- @Test
- public void testGetGameModeInfoWithAllGameModes() {
- mockDeviceConfigAll();
- mockModifyGameModeGranted();
- GameManagerService gameManagerService =
- new GameManagerService(mMockContext, mTestLooper.getLooper());
- startUser(gameManagerService, USER_ID_1);
- gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_PERFORMANCE, USER_ID_1);
- GameModeInfo gameModeInfo = gameManagerService.getGameModeInfo(mPackageName, USER_ID_1);
+ checkReportedAvailableGameModes(gameManagerService, GameManager.GAME_MODE_PERFORMANCE,
+ GameManager.GAME_MODE_BATTERY, GameManager.GAME_MODE_STANDARD,
+ GameManager.GAME_MODE_CUSTOM);
+ checkReportedOptedInGameModes(gameManagerService);
- assertEquals(GameManager.GAME_MODE_PERFORMANCE, gameModeInfo.getActiveGameMode());
- assertEquals(3, gameModeInfo.getAvailableGameModes().length);
+ assertEquals(new GameModeConfiguration.Builder()
+ .setFpsOverride(30)
+ .setScalingFactor(0.7f)
+ .build(), gameModeInfo.getGameModeConfiguration(GameManager.GAME_MODE_BATTERY));
+ assertEquals(new GameModeConfiguration.Builder()
+ .setFpsOverride(90)
+ .setScalingFactor(0.5f)
+ .build(), gameModeInfo.getGameModeConfiguration(GameManager.GAME_MODE_PERFORMANCE));
}
@Test
@@ -1298,7 +1303,14 @@ public class GameManagerServiceTests {
GameModeInfo gameModeInfo = gameManagerService.getGameModeInfo(mPackageName, USER_ID_1);
assertEquals(GameManager.GAME_MODE_BATTERY, gameModeInfo.getActiveGameMode());
- assertEquals(2, gameModeInfo.getAvailableGameModes().length);
+
+ checkReportedAvailableGameModes(gameManagerService,
+ GameManager.GAME_MODE_BATTERY, GameManager.GAME_MODE_STANDARD,
+ GameManager.GAME_MODE_CUSTOM);
+ checkReportedOptedInGameModes(gameManagerService);
+
+ assertNotNull(gameModeInfo.getGameModeConfiguration(GameManager.GAME_MODE_BATTERY));
+ assertNull(gameModeInfo.getGameModeConfiguration(GameManager.GAME_MODE_PERFORMANCE));
}
@Test
@@ -1312,11 +1324,17 @@ public class GameManagerServiceTests {
GameModeInfo gameModeInfo = gameManagerService.getGameModeInfo(mPackageName, USER_ID_1);
assertEquals(GameManager.GAME_MODE_PERFORMANCE, gameModeInfo.getActiveGameMode());
- assertEquals(2, gameModeInfo.getAvailableGameModes().length);
+ checkReportedAvailableGameModes(gameManagerService,
+ GameManager.GAME_MODE_PERFORMANCE, GameManager.GAME_MODE_STANDARD,
+ GameManager.GAME_MODE_CUSTOM);
+ checkReportedOptedInGameModes(gameManagerService);
+
+ assertNotNull(gameModeInfo.getGameModeConfiguration(GameManager.GAME_MODE_PERFORMANCE));
+ assertNull(gameModeInfo.getGameModeConfiguration(GameManager.GAME_MODE_BATTERY));
}
@Test
- public void testGetGameModeInfoWithUnsupportedGameMode() {
+ public void testGetGameModeInfoWithDefaultGameModes() {
mockDeviceConfigNone();
mockModifyGameModeGranted();
GameManagerService gameManagerService =
@@ -1324,8 +1342,103 @@ public class GameManagerServiceTests {
startUser(gameManagerService, USER_ID_1);
GameModeInfo gameModeInfo = gameManagerService.getGameModeInfo(mPackageName, USER_ID_1);
- assertEquals(GameManager.GAME_MODE_UNSUPPORTED, gameModeInfo.getActiveGameMode());
- assertEquals(0, gameModeInfo.getAvailableGameModes().length);
+ assertEquals(GameManager.GAME_MODE_STANDARD, gameModeInfo.getActiveGameMode());
+ checkReportedAvailableGameModes(gameManagerService, GameManager.GAME_MODE_STANDARD,
+ GameManager.GAME_MODE_CUSTOM);
+ assertNull(gameModeInfo.getGameModeConfiguration(GameManager.GAME_MODE_CUSTOM));
+ assertNull(gameModeInfo.getGameModeConfiguration(GameManager.GAME_MODE_STANDARD));
+ assertNull(gameModeInfo.getGameModeConfiguration(GameManager.GAME_MODE_BATTERY));
+ assertNull(gameModeInfo.getGameModeConfiguration(GameManager.GAME_MODE_PERFORMANCE));
+ }
+
+ @Test
+ public void testGetGameModeInfoWithAllGameModesOptedIn_noDeviceConfig()
+ throws Exception {
+ mockModifyGameModeGranted();
+ mockInterventionsEnabledAllOptInFromXml();
+ mockDeviceConfigNone();
+ GameManagerService gameManagerService = createServiceAndStartUser(USER_ID_1);
+ GameModeInfo gameModeInfo = gameManagerService.getGameModeInfo(mPackageName, USER_ID_1);
+ assertEquals(GameManager.GAME_MODE_STANDARD, gameModeInfo.getActiveGameMode());
+ verifyAllModesOptedInAndInterventionsAvailable(gameManagerService, gameModeInfo);
+
+ assertNull(gameModeInfo.getGameModeConfiguration(GameManager.GAME_MODE_BATTERY));
+ assertNull(gameModeInfo.getGameModeConfiguration(GameManager.GAME_MODE_PERFORMANCE));
+ }
+
+ @Test
+ public void testGetGameModeInfoWithAllGameModesOptedIn_allDeviceConfig()
+ throws Exception {
+ mockModifyGameModeGranted();
+ mockInterventionsEnabledAllOptInFromXml();
+ mockDeviceConfigAll();
+ GameManagerService gameManagerService = createServiceAndStartUser(USER_ID_1);
+ GameModeInfo gameModeInfo = gameManagerService.getGameModeInfo(mPackageName, USER_ID_1);
+ assertEquals(GameManager.GAME_MODE_STANDARD, gameModeInfo.getActiveGameMode());
+ verifyAllModesOptedInAndInterventionsAvailable(gameManagerService, gameModeInfo);
+
+ assertNull(gameModeInfo.getGameModeConfiguration(GameManager.GAME_MODE_BATTERY));
+ assertNull(gameModeInfo.getGameModeConfiguration(GameManager.GAME_MODE_PERFORMANCE));
+ }
+
+ private void verifyAllModesOptedInAndInterventionsAvailable(
+ GameManagerService gameManagerService,
+ GameModeInfo gameModeInfo) {
+ checkReportedAvailableGameModes(gameManagerService,
+ GameManager.GAME_MODE_PERFORMANCE, GameManager.GAME_MODE_BATTERY,
+ GameManager.GAME_MODE_STANDARD, GameManager.GAME_MODE_CUSTOM);
+ checkReportedOptedInGameModes(gameManagerService,
+ GameManager.GAME_MODE_PERFORMANCE, GameManager.GAME_MODE_BATTERY);
+ assertTrue(gameModeInfo.isFpsOverrideAllowed());
+ assertTrue(gameModeInfo.isDownscalingAllowed());
+ }
+
+ @Test
+ public void testGetGameModeInfoWithBatteryModeOptedIn_withBatteryDeviceConfig()
+ throws Exception {
+ mockModifyGameModeGranted();
+ mockInterventionsEnabledBatteryOptInFromXml();
+ mockDeviceConfigBattery();
+ GameManagerService gameManagerService = createServiceAndStartUser(USER_ID_1);
+ GameModeInfo gameModeInfo = gameManagerService.getGameModeInfo(mPackageName, USER_ID_1);
+ assertEquals(GameManager.GAME_MODE_STANDARD, gameModeInfo.getActiveGameMode());
+
+ checkReportedAvailableGameModes(gameManagerService, GameManager.GAME_MODE_BATTERY,
+ GameManager.GAME_MODE_STANDARD, GameManager.GAME_MODE_CUSTOM);
+ checkReportedOptedInGameModes(gameManagerService, GameManager.GAME_MODE_BATTERY);
+
+ assertNull(gameModeInfo.getGameModeConfiguration(GameManager.GAME_MODE_BATTERY));
+ assertNull(gameModeInfo.getGameModeConfiguration(GameManager.GAME_MODE_PERFORMANCE));
+ }
+
+ @Test
+ public void testGetGameModeInfoWithPerformanceModeOptedIn_withAllDeviceConfig()
+ throws Exception {
+ mockModifyGameModeGranted();
+ mockInterventionsEnabledPerformanceOptInFromXml();
+ mockDeviceConfigAll();
+ GameManagerService gameManagerService = createServiceAndStartUser(USER_ID_1);
+ GameModeInfo gameModeInfo = gameManagerService.getGameModeInfo(mPackageName, USER_ID_1);
+ assertEquals(GameManager.GAME_MODE_STANDARD, gameModeInfo.getActiveGameMode());
+
+ checkReportedAvailableGameModes(gameManagerService, GameManager.GAME_MODE_PERFORMANCE,
+ GameManager.GAME_MODE_BATTERY, GameManager.GAME_MODE_STANDARD,
+ GameManager.GAME_MODE_CUSTOM);
+ checkReportedOptedInGameModes(gameManagerService, GameManager.GAME_MODE_PERFORMANCE);
+
+ assertNotNull(gameModeInfo.getGameModeConfiguration(GameManager.GAME_MODE_BATTERY));
+ assertNull(gameModeInfo.getGameModeConfiguration(GameManager.GAME_MODE_PERFORMANCE));
+ }
+
+ @Test
+ public void testGetGameModeInfoWithInterventionsDisabled() throws Exception {
+ mockModifyGameModeGranted();
+ mockInterventionsDisabledAllOptInFromXml();
+ mockDeviceConfigAll();
+ GameManagerService gameManagerService = createServiceAndStartUser(USER_ID_1);
+ GameModeInfo gameModeInfo = gameManagerService.getGameModeInfo(mPackageName, USER_ID_1);
+ assertFalse(gameModeInfo.isFpsOverrideAllowed());
+ assertFalse(gameModeInfo.isDownscalingAllowed());
}
@Test
@@ -1381,7 +1494,7 @@ public class GameManagerServiceTests {
}
private void mockInterventionListForMultipleUsers() {
- final String[] packageNames = new String[] {"com.android.app0",
+ final String[] packageNames = new String[]{"com.android.app0",
"com.android.app1", "com.android.app2"};
final ApplicationInfo[] applicationInfos = new ApplicationInfo[3];
@@ -1424,8 +1537,8 @@ public class GameManagerServiceTests {
final Context context = InstrumentationRegistry.getContext();
GameManagerService gameManagerService =
new GameManagerService(mMockContext,
- mTestLooper.getLooper(),
- context.getFilesDir());
+ mTestLooper.getLooper(),
+ context.getFilesDir());
startUser(gameManagerService, USER_ID_1);
startUser(gameManagerService, USER_ID_2);
@@ -1437,14 +1550,14 @@ public class GameManagerServiceTests {
/* Expected fileOutput (order may vary)
# user 1001:
- com.android.app2 <UID> 0 2 angle=0,scaling=0.5,fps=90 3 angle=0,scaling=0.5,fps=60
+ com.android.app2 <UID> 1 2 angle=0,scaling=0.5,fps=90 3 angle=0,scaling=0.5,fps=60
com.android.app1 <UID> 1 2 angle=0,scaling=0.5,fps=90 3 angle=0,scaling=0.7,fps=30
- com.android.app0 <UID> 0 2 angle=0,scaling=0.6,fps=120 3 angle=0,scaling=0.7,fps=30
+ com.android.app0 <UID> 1 2 angle=0,scaling=0.6,fps=120 3 angle=0,scaling=0.7,fps=30
# user 1002:
- com.android.app2 <UID> 0 2 angle=0,scaling=0.5,fps=90 3 angle=0,scaling=0.7,fps=30
+ com.android.app2 <UID> 1 2 angle=0,scaling=0.5,fps=90 3 angle=0,scaling=0.7,fps=30
com.android.app1 <UID> 1 2 angle=0,scaling=0.5,fps=90 3 angle=0,scaling=0.7,fps=30
- com.android.app0 <UID> 0 2 angle=0,scaling=0.5,fps=90 3 angle=0,scaling=0.7,fps=30
+ com.android.app0 <UID> 1 2 angle=0,scaling=0.5,fps=90 3 angle=0,scaling=0.7,fps=30
The current game mode would only be set to non-zero if the current user have that game
installed.
*/
@@ -1461,7 +1574,7 @@ public class GameManagerServiceTests {
assertEquals(splitLine[6], "angle=0,scaling=0.5,fps=60");
splitLine = fileOutput.get(1).split("\\s+");
assertEquals(splitLine[0], "com.android.app1");
- assertEquals(splitLine[2], "0");
+ assertEquals(splitLine[2], "1");
assertEquals(splitLine[3], "2");
assertEquals(splitLine[4], "angle=0,scaling=0.5,fps=90");
assertEquals(splitLine[5], "3");
@@ -1484,7 +1597,7 @@ public class GameManagerServiceTests {
splitLine = fileOutput.get(0).split("\\s+");
assertEquals(splitLine[0], "com.android.app2");
- assertEquals(splitLine[2], "0");
+ assertEquals(splitLine[2], "1");
assertEquals(splitLine[3], "2");
assertEquals(splitLine[4], "angle=0,scaling=0.5,fps=90");
assertEquals(splitLine[5], "3");
@@ -1498,7 +1611,7 @@ public class GameManagerServiceTests {
assertEquals(splitLine[6], "angle=0,scaling=0.7,fps=30");
splitLine = fileOutput.get(2).split("\\s+");
assertEquals(splitLine[0], "com.android.app0");
- assertEquals(splitLine[2], "0");
+ assertEquals(splitLine[2], "1");
assertEquals(splitLine[3], "2");
assertEquals(splitLine[4], "angle=0,scaling=0.5,fps=90");
assertEquals(splitLine[5], "3");
@@ -1518,8 +1631,8 @@ public class GameManagerServiceTests {
startUser(gameManagerService, USER_ID_1);
startUser(gameManagerService, USER_ID_2);
gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_BATTERY, USER_ID_1);
- checkReportedModes(gameManagerService, GameManager.GAME_MODE_STANDARD,
- GameManager.GAME_MODE_BATTERY);
+ checkReportedAvailableGameModes(gameManagerService, GameManager.GAME_MODE_STANDARD,
+ GameManager.GAME_MODE_BATTERY, GameManager.GAME_MODE_CUSTOM);
assertEquals(gameManagerService.getGameMode(mPackageName, USER_ID_1),
GameManager.GAME_MODE_BATTERY);
@@ -1527,16 +1640,16 @@ public class GameManagerServiceTests {
switchUser(gameManagerService, USER_ID_1, USER_ID_2);
assertEquals(gameManagerService.getGameMode(mPackageName, USER_ID_2),
GameManager.GAME_MODE_STANDARD);
- checkReportedModes(gameManagerService, GameManager.GAME_MODE_STANDARD,
- GameManager.GAME_MODE_BATTERY, GameManager.GAME_MODE_PERFORMANCE);
- gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_PERFORMANCE, USER_ID_2);
- gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_BATTERY, USER_ID_1);
+ checkReportedAvailableGameModes(gameManagerService, GameManager.GAME_MODE_STANDARD,
+ GameManager.GAME_MODE_BATTERY, GameManager.GAME_MODE_PERFORMANCE,
+ GameManager.GAME_MODE_CUSTOM);
switchUser(gameManagerService, USER_ID_2, USER_ID_1);
- checkReportedModes(gameManagerService, GameManager.GAME_MODE_STANDARD,
- GameManager.GAME_MODE_BATTERY, GameManager.GAME_MODE_PERFORMANCE);
- gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_PERFORMANCE, USER_ID_2);
- gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_BATTERY, USER_ID_1);
+ assertEquals(gameManagerService.getGameMode(mPackageName, USER_ID_1),
+ GameManager.GAME_MODE_BATTERY);
+ checkReportedAvailableGameModes(gameManagerService, GameManager.GAME_MODE_STANDARD,
+ GameManager.GAME_MODE_BATTERY, GameManager.GAME_MODE_PERFORMANCE,
+ GameManager.GAME_MODE_CUSTOM);
}
@Test
@@ -1640,6 +1753,33 @@ public class GameManagerServiceTests {
}
@Test
+ public void testUpdateCustomGameModeConfiguration_permissionDenied() {
+ mockModifyGameModeDenied();
+ mockDeviceConfigAll();
+ GameManagerService gameManagerService =
+ new GameManagerService(mMockContext, mTestLooper.getLooper());
+ startUser(gameManagerService, USER_ID_1);
+ assertThrows(SecurityException.class, () -> {
+ gameManagerService.updateCustomGameModeConfiguration(mPackageName,
+ new GameModeConfiguration.Builder().setScalingFactor(0.5f).build(),
+ USER_ID_1);
+ });
+ }
+
+ @Test
+ public void testUpdateCustomGameModeConfiguration_noUserId() {
+ mockModifyGameModeGranted();
+ GameManagerService gameManagerService =
+ new GameManagerService(mMockContext, mTestLooper.getLooper());
+ startUser(gameManagerService, USER_ID_2);
+ assertThrows(IllegalArgumentException.class, () -> {
+ gameManagerService.updateCustomGameModeConfiguration(mPackageName,
+ new GameModeConfiguration.Builder().setScalingFactor(0.5f).build(),
+ USER_ID_1);
+ });
+ }
+
+ @Test
public void testWritingSettingFile_onShutdown() throws InterruptedException {
mockModifyGameModeGranted();
mockDeviceConfigAll();
@@ -1743,6 +1883,53 @@ public class GameManagerServiceTests {
ArgumentMatchers.eq(0.0f));
}
+ @Test
+ public void testAddGameModeListener() throws RemoteException {
+ GameManagerService gameManagerService =
+ new GameManagerService(mMockContext, mTestLooper.getLooper());
+ mockDeviceConfigAll();
+ startUser(gameManagerService, USER_ID_1);
+ mockModifyGameModeGranted();
+
+ IGameModeListener mockListener = Mockito.mock(IGameModeListener.class);
+ IBinder binder = Mockito.mock(IBinder.class);
+ when(mockListener.asBinder()).thenReturn(binder);
+ gameManagerService.addGameModeListener(mockListener);
+ verify(binder).linkToDeath(mDeathRecipientCaptor.capture(), anyInt());
+
+ gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_PERFORMANCE, USER_ID_1);
+ verify(mockListener).onGameModeChanged(mPackageName, GameManager.GAME_MODE_STANDARD,
+ GameManager.GAME_MODE_PERFORMANCE, USER_ID_1);
+ reset(mockListener);
+ gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_BATTERY, USER_ID_1);
+ verify(mockListener).onGameModeChanged(mPackageName, GameManager.GAME_MODE_PERFORMANCE,
+ GameManager.GAME_MODE_BATTERY, USER_ID_1);
+ reset(mockListener);
+
+ mDeathRecipientCaptor.getValue().binderDied();
+ verify(binder).unlinkToDeath(eq(mDeathRecipientCaptor.getValue()), anyInt());
+ gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_CUSTOM, USER_ID_1);
+ verify(mockListener, never()).onGameModeChanged(anyString(), anyInt(), anyInt(), anyInt());
+ }
+
+ @Test
+ public void testRemoveGameModeListener() throws RemoteException {
+ GameManagerService gameManagerService =
+ new GameManagerService(mMockContext, mTestLooper.getLooper());
+ mockDeviceConfigAll();
+ startUser(gameManagerService, USER_ID_1);
+ mockModifyGameModeGranted();
+
+ IGameModeListener mockListener = Mockito.mock(IGameModeListener.class);
+ IBinder binder = Mockito.mock(IBinder.class);
+ when(mockListener.asBinder()).thenReturn(binder);
+
+ gameManagerService.addGameModeListener(mockListener);
+ gameManagerService.removeGameModeListener(mockListener);
+ gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_PERFORMANCE, USER_ID_1);
+ verify(mockListener, never()).onGameModeChanged(anyString(), anyInt(), anyInt(), anyInt());
+ }
+
private static void deleteFolder(File folder) {
File[] files = folder.listFiles();
if (files != null) {
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/AsyncUserVisibilityListener.java b/services/tests/mockingservicestests/src/com/android/server/pm/AsyncUserVisibilityListener.java
index 1a4a7bd4ff72..afcedd6f41bf 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/AsyncUserVisibilityListener.java
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/AsyncUserVisibilityListener.java
@@ -40,7 +40,8 @@ public final class AsyncUserVisibilityListener implements UserVisibilityListener
private static final String TAG = AsyncUserVisibilityListener.class.getSimpleName();
private static final long WAIT_TIMEOUT_MS = 2_000;
- private static final long WAIT_NO_EVENTS_TIMEOUT_MS = 1_000;
+
+ private static final long WAIT_NO_EVENTS_TIMEOUT_MS = 100;
private static int sNextId;
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/StagingManagerTest.java b/services/tests/mockingservicestests/src/com/android/server/pm/StagingManagerTest.java
index 1464405cca08..cfd5279a0fa9 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/StagingManagerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/StagingManagerTest.java
@@ -723,7 +723,7 @@ public class StagingManagerTest {
params.isStaged = true;
InstallSource installSource = InstallSource.create("testInstallInitiator",
- "testInstallOriginator", "testInstaller", "testAttributionTag",
+ "testInstallOriginator", "testInstaller", 100, "testAttributionTag",
PackageInstaller.PACKAGE_SOURCE_UNSPECIFIED);
PackageInstallerSession session = new PackageInstallerSession(
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorTestCase.java b/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorTestCase.java
index 17ee90927977..6ceb38adf875 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorTestCase.java
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorTestCase.java
@@ -36,16 +36,14 @@ import static com.google.common.truth.Truth.assertWithMessage;
import static org.junit.Assert.assertThrows;
import android.annotation.UserIdInt;
-import android.os.HandlerThread;
+import android.os.Handler;
import android.util.IntArray;
import android.util.Log;
import com.android.internal.util.Preconditions;
import com.android.server.ExtendedMockitoTestCase;
-import org.junit.AfterClass;
import org.junit.Before;
-import org.junit.BeforeClass;
import org.junit.Test;
import java.util.Arrays;
@@ -103,10 +101,8 @@ abstract class UserVisibilityMediatorTestCase extends ExtendedMockitoTestCase {
protected static final boolean FG = true;
protected static final boolean BG = false;
- private static final HandlerThread sHandlerThread = new HandlerThread(TAG);
-
- protected final AsyncUserVisibilityListener.Factory mListenerFactory =
- new AsyncUserVisibilityListener.Factory(mExpect, sHandlerThread);
+ private Handler mHandler;
+ protected AsyncUserVisibilityListener.Factory mListenerFactory;
private final boolean mUsersOnSecondaryDisplaysEnabled;
@@ -116,24 +112,13 @@ abstract class UserVisibilityMediatorTestCase extends ExtendedMockitoTestCase {
mUsersOnSecondaryDisplaysEnabled = usersOnSecondaryDisplaysEnabled;
}
- @BeforeClass
- public static final void startHandlerThread() {
- Log.d(TAG, "Starting handler thread " + sHandlerThread);
- sHandlerThread.start();
- }
-
- @AfterClass
- public static final void quitHandlerThread() {
- Log.d(TAG, "Quitting handler thread " + sHandlerThread);
- if (!sHandlerThread.quit()) {
- Log.w(TAG, "sHandlerThread(" + sHandlerThread + ").quit() returned false");
- }
- }
-
@Before
public final void setFixtures() {
- mMediator = new UserVisibilityMediator(mUsersOnSecondaryDisplaysEnabled,
- sHandlerThread.getThreadHandler());
+ mHandler = Handler.getMain();
+ Thread thread = mHandler.getLooper().getThread();
+ Log.i(TAG, "setFixtures(): using thread " + thread + " (from handler " + mHandler + ")");
+ mListenerFactory = new AsyncUserVisibilityListener.Factory(mExpect, thread);
+ mMediator = new UserVisibilityMediator(mUsersOnSecondaryDisplaysEnabled, mHandler);
mDumpableDumperRule.addDumpable(mMediator);
}
diff --git a/services/tests/servicestests/Android.bp b/services/tests/servicestests/Android.bp
index 9386a23958d1..fbd12936ed93 100644
--- a/services/tests/servicestests/Android.bp
+++ b/services/tests/servicestests/Android.bp
@@ -118,12 +118,6 @@ android_test {
],
java_resources: [
- ":PackageParserTestApp1",
- ":PackageParserTestApp2",
- ":PackageParserTestApp3",
- ":PackageParserTestApp4",
- ":PackageParserTestApp5",
- ":PackageParserTestApp6",
":com.android.apex.cts.shim.v1_prebuilt",
":com.android.apex.cts.shim.v2_different_certificate_prebuilt",
":com.android.apex.cts.shim.v2_unsigned_apk_container_prebuilt",
@@ -137,6 +131,7 @@ java_library {
"src/com/android/server/am/DeviceConfigSession.java",
"src/com/android/server/display/TestUtils.java",
"src/com/android/server/pm/PackageSettingBuilder.java",
+ "src/com/android/server/pm/parsing/TestPackageParser2.kt",
],
static_libs: [
"services.core",
@@ -145,6 +140,33 @@ java_library {
}
java_library {
+ name: "servicestests-dpm-utils",
+ srcs: [
+ "src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java",
+ "src/com/android/server/devicepolicy/DevicePolicyManagerTestable.java",
+ "src/com/android/server/devicepolicy/DpmMockContext.java",
+ "src/com/android/server/devicepolicy/DpmTestBase.java",
+ "src/com/android/server/devicepolicy/DpmTestUtils.java",
+ "src/com/android/server/devicepolicy/DummyDeviceAdmins.java",
+ "src/com/android/server/devicepolicy/MockSystemServices.java",
+ "src/com/android/server/devicepolicy/MockUtils.java",
+ ],
+ libs: [
+ "android.test.mock",
+ "android.test.base",
+ "mockito-target-minus-junit4",
+ ],
+ static_libs: [
+ "frameworks-base-testutils",
+ "androidx.test.core",
+ "androidx.test.ext.truth",
+ "androidx.test.rules",
+ "services.core",
+ "services.devicepolicy",
+ ],
+}
+
+java_library {
name: "servicestests-utils",
srcs: [
"utils/**/*.java",
@@ -187,41 +209,8 @@ filegroup {
java_genrule {
name: "FrameworksServicesTests_apks_as_resources",
srcs: [
- ":FrameworksServicesTests_install",
- ":FrameworksServicesTests_install_bad_dex",
- ":FrameworksServicesTests_install_complete_package_info",
- ":FrameworksServicesTests_install_decl_perm",
- ":FrameworksServicesTests_install_intent_filters",
- ":FrameworksServicesTests_install_loc_auto",
- ":FrameworksServicesTests_install_loc_internal",
- ":FrameworksServicesTests_install_loc_sdcard",
- ":FrameworksServicesTests_install_loc_unspecified",
":FrameworksServicesTests_install_split_base",
":FrameworksServicesTests_install_split_feature_a",
- ":FrameworksServicesTests_install_use_perm_good",
- ":FrameworksServicesTests_install_uses_feature",
- ":FrameworksServicesTests_install_uses_sdk_0",
- ":FrameworksServicesTests_install_uses_sdk_q0",
- ":FrameworksServicesTests_install_uses_sdk_q0_r0",
- ":FrameworksServicesTests_install_uses_sdk_r0",
- ":FrameworksServicesTests_install_uses_sdk_r1000",
- ":FrameworksServicesTests_install_uses_sdk_r_none",
- ":FrameworksServicesTests_install_uses_sdk_r0_s0",
- ":FrameworksServicesTests_install_uses_sdk_r0_s1000",
- ":FrameworksServicesTests_keyset_permdef_sa_unone",
- ":FrameworksServicesTests_keyset_permuse_sa_ua_ub",
- ":FrameworksServicesTests_keyset_permuse_sb_ua_ub",
- ":FrameworksServicesTests_keyset_sa_ua",
- ":FrameworksServicesTests_keyset_sa_ua_ub",
- ":FrameworksServicesTests_keyset_sa_uab",
- ":FrameworksServicesTests_keyset_sa_ub",
- ":FrameworksServicesTests_keyset_sa_unone",
- ":FrameworksServicesTests_keyset_sab_ua",
- ":FrameworksServicesTests_keyset_sau_ub",
- ":FrameworksServicesTests_keyset_sb_ua",
- ":FrameworksServicesTests_keyset_sb_ub",
- ":FrameworksServicesTests_keyset_splat_api",
- ":FrameworksServicesTests_keyset_splata_api",
],
out: ["FrameworkServicesTests_apks_as_resources.res.zip"],
tools: ["soong_zip"],
diff --git a/services/tests/servicestests/AndroidManifest.xml b/services/tests/servicestests/AndroidManifest.xml
index 6349b21183fe..0be321ac5249 100644
--- a/services/tests/servicestests/AndroidManifest.xml
+++ b/services/tests/servicestests/AndroidManifest.xml
@@ -104,12 +104,12 @@
<uses-permission android:name="android.permission.PACKAGE_VERIFICATION_AGENT" />
<uses-permission android:name="android.permission.OBSERVE_ROLE_HOLDERS" />
<uses-permission android:name="android.permission.BATTERY_STATS" />
+ <uses-permission android:name="android.permission.UPDATE_LOCK_TASK_PACKAGES" />
+ <uses-permission android:name="android.permission.ACCESS_CONTEXT_HUB" />
+ <uses-permission android:name="android.permission.USE_BIOMETRIC_INTERNAL" />
<queries>
<package android:name="com.android.servicestests.apps.suspendtestapp" />
- <intent>
- <action android:name="android.media.browse.MediaBrowserService" />
- </intent>
</queries>
<!-- Uses API introduced in O (26) -->
@@ -304,11 +304,4 @@
<instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
android:targetPackage="com.android.frameworks.servicestests"
android:label="Frameworks Services Tests"/>
- <key-sets>
- <key-set android:name="A" >
- <public-key android:name="keyA"
- android:value="MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsMpNthdOxud7roPDZMMomOqXgJJdRfIWpkKEqmC61Mv+Nf6QY3TorEwJeghjSmqj7IbBKrtvfQq4E2XJO1HuspmQO4Ng2gvn+r+6EwNfKc9k55d6s+27SR867jKurBbHNtZMG+tjL1yH4r+tNzcuJCsgyAFqLmxFdcxEwzNvREyRpoYc5RDR0mmTwkMCUhJ6CId1EYEKiCEdNzxv+fWPEb21u+/MWpleGCILs8kglRVb2q/WOzAAvGr4FY5plfaE6N+lr7+UschQ+aMi1+uqewo2o0qPFVmZP5hnwj55K4UMzu/NhhDqQQsX4cSGES1KgHo5MTqRqZjN/I7emw5pFQIDAQAB"/>
- </key-set>
- <upgrade-key-set android:name="A"/>
- </key-sets>
</manifest>
diff --git a/services/tests/servicestests/AndroidTest.xml b/services/tests/servicestests/AndroidTest.xml
index 9c7ce835632a..9052f58b2a8b 100644
--- a/services/tests/servicestests/AndroidTest.xml
+++ b/services/tests/servicestests/AndroidTest.xml
@@ -33,7 +33,6 @@
<option name="test-file-name" value="SimpleServiceTestApp1.apk" />
<option name="test-file-name" value="SimpleServiceTestApp2.apk" />
<option name="test-file-name" value="SimpleServiceTestApp3.apk" />
- <option name="test-file-name" value="FakeMediaApp.apk" />
</target_preparer>
<!-- Create place to store apks -->
diff --git a/services/tests/servicestests/src/com/android/server/app/GameManagerServiceSettingsTests.java b/services/tests/servicestests/src/com/android/server/app/GameManagerServiceSettingsTests.java
index e8dd541b0531..582c78bce54c 100644
--- a/services/tests/servicestests/src/com/android/server/app/GameManagerServiceSettingsTests.java
+++ b/services/tests/servicestests/src/com/android/server/app/GameManagerServiceSettingsTests.java
@@ -192,7 +192,7 @@ public class GameManagerServiceSettingsTests {
final Context context = InstrumentationRegistry.getContext();
GameManagerSettings settings = new GameManagerSettings(context.getFilesDir());
assertTrue(settings.readPersistentDataLocked());
- assertEquals(0, settings.getGameModeLocked(PACKAGE_NAME_1));
+ assertEquals(1, settings.getGameModeLocked(PACKAGE_NAME_1));
assertEquals(2, settings.getGameModeLocked(PACKAGE_NAME_2));
assertEquals(3, settings.getGameModeLocked(PACKAGE_NAME_3));
diff --git a/services/tests/servicestests/src/com/android/server/backup/UserBackupManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/backup/UserBackupManagerServiceTest.java
index 9ae892286e55..60165588f578 100644
--- a/services/tests/servicestests/src/com/android/server/backup/UserBackupManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/backup/UserBackupManagerServiceTest.java
@@ -38,6 +38,7 @@ import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.platform.test.annotations.Presubmit;
+import androidx.test.filters.FlakyTest;
import androidx.test.runner.AndroidJUnit4;
import com.android.server.backup.internal.LifecycleOperationStorage;
@@ -174,6 +175,7 @@ public class UserBackupManagerServiceTest {
}
@Test
+ @FlakyTest
public void testAgentDisconnected_cancelsCurrentOperations() throws Exception {
when(mOperationStorage.operationTokensForPackage(eq("com.android.foo"))).thenReturn(
ImmutableSet.of(123, 456, 789)
diff --git a/services/tests/servicestests/src/com/android/server/backup/utils/BackupManagerMonitorUtilsTest.java b/services/tests/servicestests/src/com/android/server/backup/utils/BackupManagerMonitorUtilsTest.java
index d3fd89c3018a..cadc890f64fd 100644
--- a/services/tests/servicestests/src/com/android/server/backup/utils/BackupManagerMonitorUtilsTest.java
+++ b/services/tests/servicestests/src/com/android/server/backup/utils/BackupManagerMonitorUtilsTest.java
@@ -21,13 +21,20 @@ import static android.app.backup.BackupManagerMonitor.EXTRA_LOG_EVENT_ID;
import static android.app.backup.BackupManagerMonitor.EXTRA_LOG_EVENT_PACKAGE_LONG_VERSION;
import static android.app.backup.BackupManagerMonitor.EXTRA_LOG_EVENT_PACKAGE_NAME;
import static android.app.backup.BackupManagerMonitor.EXTRA_LOG_EVENT_PACKAGE_VERSION;
+import static android.app.backup.BackupManagerMonitor.LOG_EVENT_CATEGORY_AGENT;
+import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_AGENT_LOGGING_RESULTS;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
+import android.app.IBackupAgent;
+import android.app.backup.BackupManagerMonitor;
+import android.app.backup.BackupRestoreEventLogger;
import android.app.backup.IBackupManagerMonitor;
import android.content.pm.PackageInfo;
import android.os.Bundle;
@@ -37,6 +44,8 @@ import android.platform.test.annotations.Presubmit;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
+import com.android.internal.infra.AndroidFuture;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -44,6 +53,9 @@ import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.util.ArrayList;
+import java.util.List;
+
@SmallTest
@Presubmit
@RunWith(AndroidJUnit4.class)
@@ -143,6 +155,44 @@ public class BackupManagerMonitorUtilsTest {
}
@Test
+ public void monitorAgentLoggingResults_fillsBundleCorrectly() throws Exception {
+ PackageInfo packageInfo = new PackageInfo();
+ packageInfo.packageName = "test.package";
+ // Mock an agent that returns a logging result.
+ IBackupAgent agent = spy(IBackupAgent.class);
+ List<BackupRestoreEventLogger.DataTypeResult> loggingResults = new ArrayList<>();
+ loggingResults.add(new BackupRestoreEventLogger.DataTypeResult("testLoggingResult"));
+ doAnswer(
+ invocation -> {
+ AndroidFuture<List<BackupRestoreEventLogger.DataTypeResult>> in =
+ invocation.getArgument(0);
+ in.complete(loggingResults);
+ return null;
+ })
+ .when(agent)
+ .getLoggerResults(any());
+
+ IBackupManagerMonitor result =
+ BackupManagerMonitorUtils.monitorAgentLoggingResults(
+ mMonitorMock, packageInfo, agent);
+
+ assertThat(result).isEqualTo(mMonitorMock);
+ ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
+ verify(mMonitorMock).onEvent(bundleCaptor.capture());
+ Bundle eventBundle = bundleCaptor.getValue();
+ assertThat(eventBundle.getInt(EXTRA_LOG_EVENT_ID))
+ .isEqualTo(LOG_EVENT_ID_AGENT_LOGGING_RESULTS);
+ assertThat(eventBundle.getInt(EXTRA_LOG_EVENT_CATEGORY))
+ .isEqualTo(LOG_EVENT_CATEGORY_AGENT);
+ assertThat(eventBundle.getString(EXTRA_LOG_EVENT_PACKAGE_NAME)).isEqualTo("test.package");
+ List<BackupRestoreEventLogger.DataTypeResult> filledLoggingResults =
+ eventBundle.getParcelableArrayList(
+ BackupManagerMonitor.EXTRA_LOG_AGENT_LOGGING_RESULTS,
+ BackupRestoreEventLogger.DataTypeResult.class);
+ assertThat(filledLoggingResults.get(0).getDataType()).isEqualTo("testLoggingResult");
+ }
+
+ @Test
public void putMonitoringExtraString_bundleExists_fillsBundleCorrectly() throws Exception {
Bundle bundle = new Bundle();
@@ -204,5 +254,4 @@ public class BackupManagerMonitorUtilsTest {
assertThat(result.size()).isEqualTo(1);
assertThat(result.getBoolean("key")).isTrue();
}
-
} \ No newline at end of file
diff --git a/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java
index c715a217f221..09dc367cceb4 100644
--- a/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java
@@ -472,6 +472,35 @@ public class VirtualDeviceManagerServiceTest {
}
@Test
+ public void createVirtualTouchscreen_zeroDisplayDimension_failsIllegalArgumentException() {
+ mDeviceImpl.mVirtualDisplayIds.add(DISPLAY_ID);
+ Point size = new Point(0, 0);
+ assertThrows(IllegalArgumentException.class,
+ () -> mDeviceImpl.createVirtualTouchscreen(DISPLAY_ID, DEVICE_NAME, VENDOR_ID,
+ PRODUCT_ID, BINDER, size));
+ }
+
+ @Test
+ public void createVirtualTouchscreen_negativeDisplayDimension_failsIllegalArgumentException() {
+ mDeviceImpl.mVirtualDisplayIds.add(DISPLAY_ID);
+ Point size = new Point(-100, -100);
+ assertThrows(IllegalArgumentException.class,
+ () -> mDeviceImpl.createVirtualTouchscreen(DISPLAY_ID, DEVICE_NAME, VENDOR_ID,
+ PRODUCT_ID, BINDER, size));
+ }
+
+ @Test
+ public void createVirtualTouchscreen_positiveDisplayDimension_successful() {
+ mDeviceImpl.mVirtualDisplayIds.add(DISPLAY_ID);
+ Point size = new Point(600, 800);
+ mDeviceImpl.createVirtualTouchscreen(DISPLAY_ID, DEVICE_NAME, VENDOR_ID, PRODUCT_ID, BINDER,
+ size);
+ assertWithMessage(
+ "Virtual touchscreen should create input device descriptor on successful creation.")
+ .that(mInputController.mInputDeviceDescriptors).isNotEmpty();
+ }
+
+ @Test
public void onAudioSessionStarting_noDisplay_failsSecurityException() {
assertThrows(SecurityException.class,
() -> mDeviceImpl.onAudioSessionStarting(
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java
index 3f0022de1386..f0013a6f98b9 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java
@@ -35,6 +35,7 @@ import android.media.IAudioService;
import android.net.IIpConnectivityMetrics;
import android.net.Uri;
import android.os.Bundle;
+import android.os.Environment;
import android.os.Looper;
import android.os.PowerManagerInternal;
import android.os.UserHandle;
@@ -58,6 +59,7 @@ import com.android.server.net.NetworkPolicyManagerInternal;
import com.android.server.pm.UserManagerInternal;
import com.android.server.wm.ActivityTaskManagerInternal;
+import java.io.File;
import java.io.IOException;
import java.util.Map;
@@ -449,7 +451,7 @@ public class DevicePolicyManagerServiceTestable extends DevicePolicyManagerServi
@Override
public TransferOwnershipMetadataManager newTransferOwnershipMetadataManager() {
return new TransferOwnershipMetadataManager(
- new TransferOwnershipMetadataManagerTest.MockInjector());
+ new TransferOwnershipMetadataManagerMockInjector());
}
@Override
@@ -502,4 +504,12 @@ public class DevicePolicyManagerServiceTestable extends DevicePolicyManagerServi
return context;
}
}
+
+ static class TransferOwnershipMetadataManagerMockInjector extends
+ TransferOwnershipMetadataManager.Injector {
+ @Override
+ public File getOwnerTransferMetadataDir() {
+ return Environment.getExternalStorageDirectory();
+ }
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
index 8e669f0fd40d..a02b0f165383 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -133,7 +133,6 @@ import android.os.IpcDataCache;
import android.os.Process;
import android.os.UserHandle;
import android.os.UserManager;
-import android.platform.test.annotations.FlakyTest;
import android.platform.test.annotations.Presubmit;
import android.provider.Settings;
import android.security.KeyChain;
@@ -145,6 +144,7 @@ import android.util.ArraySet;
import android.util.Log;
import android.util.Pair;
+import androidx.test.filters.FlakyTest;
import androidx.test.filters.SmallTest;
import com.android.internal.R;
@@ -4782,6 +4782,7 @@ public class DevicePolicyManagerTest extends DpmTestBase {
}
@Test
+ @FlakyTest(bugId = 260145949)
public void testLockTaskPolicyForProfileOwner() throws Exception {
mockPolicyExemptApps();
mockVendorPolicyExemptApps();
@@ -4817,6 +4818,7 @@ public class DevicePolicyManagerTest extends DpmTestBase {
}
@Test
+ @FlakyTest(bugId = 260145949)
public void testLockTaskFeatures_IllegalArgumentException() throws Exception {
// Setup a device owner.
mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
@@ -7812,6 +7814,7 @@ public class DevicePolicyManagerTest extends DpmTestBase {
}
@Test
+ @FlakyTest(bugId = 260145949)
public void testSetLockTaskFeatures_financeDo_validLockTaskFeatures_lockTaskFeaturesSet()
throws Exception {
int validLockTaskFeatures = LOCK_TASK_FEATURE_SYSTEM_INFO | LOCK_TASK_FEATURE_KEYGUARD
@@ -7827,6 +7830,7 @@ public class DevicePolicyManagerTest extends DpmTestBase {
}
@Test
+ @FlakyTest(bugId = 260145949)
public void testSetLockTaskFeatures_financeDo_invalidLockTaskFeatures_throwsException()
throws Exception {
int invalidLockTaskFeatures = LOCK_TASK_FEATURE_NONE | LOCK_TASK_FEATURE_OVERVIEW
@@ -7843,6 +7847,7 @@ public class DevicePolicyManagerTest extends DpmTestBase {
}
@Test
+ @FlakyTest(bugId = 260145949)
public void testIsUninstallBlocked_financeDo_success() throws Exception {
String packageName = "com.android.foo.package";
setDeviceOwner();
@@ -7943,6 +7948,7 @@ public class DevicePolicyManagerTest extends DpmTestBase {
}
@Test
+ @FlakyTest(bugId = 260145949)
public void testSetLockTaskPackages_financeDo_success() throws Exception {
String[] packages = {"com.android.foo.package"};
mockEmptyPolicyExemptApps();
diff --git a/services/tests/servicestests/src/com/android/server/media/MediaButtonReceiverHolderTest.java b/services/tests/servicestests/src/com/android/server/media/MediaButtonReceiverHolderTest.java
deleted file mode 100644
index 1c4ee691fc77..000000000000
--- a/services/tests/servicestests/src/com/android/server/media/MediaButtonReceiverHolderTest.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.media;
-
-import android.app.PendingIntent;
-import android.content.Context;
-import android.content.Intent;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.platform.app.InstrumentationRegistry;
-
-import com.google.common.truth.Truth;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidJUnit4.class)
-public class MediaButtonReceiverHolderTest {
-
- @Test
- public void createMediaButtonReceiverHolder_resolvesNullComponentName() {
- Context context = InstrumentationRegistry.getInstrumentation().getContext();
- Intent intent = new Intent(Intent.ACTION_MEDIA_BUTTON);
- PendingIntent pi = PendingIntent.getBroadcast(context, /* requestCode= */ 0, intent,
- PendingIntent.FLAG_IMMUTABLE);
- MediaButtonReceiverHolder a = MediaButtonReceiverHolder.create(/* userId= */ 0, pi,
- context.getPackageName());
- Truth.assertWithMessage("Component name must match PendingIntent creator package.").that(
- a.getComponentName()).isNull();
- }
-}
diff --git a/services/tests/servicestests/src/com/android/server/media/OWNERS b/services/tests/servicestests/src/com/android/server/media/OWNERS
deleted file mode 100644
index 55ffde223374..000000000000
--- a/services/tests/servicestests/src/com/android/server/media/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 137631
-include platform/frameworks/av:/media/janitors/media_solutions_OWNERS \ No newline at end of file
diff --git a/services/tests/servicestests/src/com/android/server/utils/OWNERS b/services/tests/servicestests/src/com/android/server/utils/OWNERS
index d1a36bb22e97..5e2482825c74 100644
--- a/services/tests/servicestests/src/com/android/server/utils/OWNERS
+++ b/services/tests/servicestests/src/com/android/server/utils/OWNERS
@@ -1,6 +1,2 @@
-per-file WatchableTester.java = file:/services/core/java/com/android/server/pm/OWNERS
-per-file WatchableTester.java = shombert@google.com
-per-file WatcherTest.java = file:/services/core/java/com/android/server/pm/OWNERS
-per-file WatcherTest.java = shombert@google.com
per-file EventLoggerTest.java = file:/platform/frameworks/av:/media/janitors/media_solutions_OWNERS
per-file EventLoggerTest.java = jmtrivi@google.com
diff --git a/services/tests/servicestests/test-apps/FakeMediaApp/Android.bp b/services/tests/servicestests/test-apps/FakeMediaApp/Android.bp
deleted file mode 100644
index a4041b79e0ff..000000000000
--- a/services/tests/servicestests/test-apps/FakeMediaApp/Android.bp
+++ /dev/null
@@ -1,37 +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 {
- // See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "frameworks_base_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["frameworks_base_license"],
-}
-
-android_test_helper_app {
- name: "FakeMediaApp",
-
- sdk_version: "current",
-
- srcs: ["**/*.java"],
-
- dex_preopt: {
- enabled: false,
- },
- optimize: {
- enabled: false,
- },
-}
diff --git a/services/tests/servicestests/test-apps/FakeMediaApp/OWNERS b/services/tests/servicestests/test-apps/FakeMediaApp/OWNERS
deleted file mode 100644
index 55ffde223374..000000000000
--- a/services/tests/servicestests/test-apps/FakeMediaApp/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 137631
-include platform/frameworks/av:/media/janitors/media_solutions_OWNERS \ No newline at end of file
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 042d21b3d6f5..1ab7d7e0c81b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -2958,8 +2958,7 @@ public class ActivityRecordTests extends WindowTestsBase {
removeGlobalMinSizeRestriction();
final Task task = new TaskBuilder(mSupervisor).setCreateParentTask(true).build();
final Task rootTask = task.getRootTask();
- final TaskFragment taskFragment = createTaskFragmentWithParentTask(task,
- false /* createEmbeddedTask */);
+ final TaskFragment taskFragment = createTaskFragmentWithActivity(task);
final ActivityRecord activity = taskFragment.getTopNonFinishingActivity();
final Rect stackBounds = new Rect(0, 0, 1000, 600);
final Rect taskBounds = new Rect(100, 400, 600, 800);
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
index fc1989e84ac5..0743ef471d81 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
@@ -505,12 +505,12 @@ public class ActivityStarterTests extends WindowTestsBase {
// The fullscreen windowing mode activity will be moved to split-secondary by
// TestSplitOrganizer when a split-primary task appears.
final ActivityRecord splitPrimaryActivity = new TaskBuilder(mSupervisor)
- .setParentTaskFragment(splitOrg.mPrimary)
+ .setParentTask(splitOrg.mPrimary)
.setCreateActivity(true)
.build()
.getTopMostActivity();
final ActivityRecord splitSecondActivity = new TaskBuilder(mSupervisor)
- .setParentTaskFragment(splitOrg.mSecondary)
+ .setParentTask(splitOrg.mSecondary)
.setCreateActivity(true)
.build()
.getTopMostActivity();
@@ -1055,7 +1055,7 @@ public class ActivityStarterTests extends WindowTestsBase {
// Create another activity on top of the secondary display.
final Task topStack = secondaryTaskContainer.createRootTask(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_STANDARD, true /* onTop */);
- final Task topTask = new TaskBuilder(mSupervisor).setParentTaskFragment(topStack).build();
+ final Task topTask = new TaskBuilder(mSupervisor).setParentTask(topStack).build();
new ActivityBuilder(mAtm).setTask(topTask).build();
doReturn(mActivityMetricsLogger).when(mSupervisor).getActivityMetricsLogger();
@@ -1251,7 +1251,7 @@ public class ActivityStarterTests extends WindowTestsBase {
final ActivityStarter starter = prepareStarter(0 /* flags */);
starter.mStartActivity = new ActivityBuilder(mAtm).build();
final Task task = new TaskBuilder(mAtm.mTaskSupervisor)
- .setParentTaskFragment(createTask(mDisplayContent, WINDOWING_MODE_FULLSCREEN,
+ .setParentTask(createTask(mDisplayContent, WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_STANDARD))
.setUserId(10)
.build();
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
index 43e79f9cbb15..fb94147c5e49 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
@@ -593,7 +593,7 @@ public class AppTransitionControllerTest extends WindowTestsBase {
final Task singleTopRoot = createTask(mDisplayContent);
final TaskBuilder builder = new TaskBuilder(mSupervisor)
.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW)
- .setParentTaskFragment(singleTopRoot)
+ .setParentTask(singleTopRoot)
.setCreatedByOrganizer(true);
final Task splitRoot1 = builder.build();
final Task splitRoot2 = builder.build();
@@ -622,45 +622,12 @@ public class AppTransitionControllerTest extends WindowTestsBase {
// [DefaultTDA] - [Task] -+- [TaskFragment1] - [ActivityRecord1] (opening, invisible)
// +- [TaskFragment2] - [ActivityRecord2] (closing, visible)
final Task parentTask = createTask(mDisplayContent);
- final TaskFragment taskFragment1 = createTaskFragmentWithParentTask(parentTask,
- false /* createEmbeddedTask */);
+ final TaskFragment taskFragment1 = createTaskFragmentWithActivity(parentTask);
final ActivityRecord activity1 = taskFragment1.getTopMostActivity();
activity1.setVisible(false);
activity1.mVisibleRequested = true;
- final TaskFragment taskFragment2 = createTaskFragmentWithParentTask(parentTask,
- false /* createEmbeddedTask */);
- final ActivityRecord activity2 = taskFragment2.getTopMostActivity();
- activity2.setVisible(true);
- activity2.mVisibleRequested = false;
-
- final ArraySet<ActivityRecord> opening = new ArraySet<>();
- opening.add(activity1);
- final ArraySet<ActivityRecord> closing = new ArraySet<>();
- closing.add(activity2);
-
- // Promote animation targets up to TaskFragment level, not beyond.
- assertEquals(new ArraySet<>(new WindowContainer[]{taskFragment1}),
- AppTransitionController.getAnimationTargets(
- opening, closing, true /* visible */));
- assertEquals(new ArraySet<>(new WindowContainer[]{taskFragment2}),
- AppTransitionController.getAnimationTargets(
- opening, closing, false /* visible */));
- }
-
- @Test
- public void testGetAnimationTargets_openingClosingTaskFragmentWithEmbeddedTask() {
- // [DefaultTDA] - [Task] -+- [TaskFragment1] - [ActivityRecord1] (opening, invisible)
- // +- [TaskFragment2] - [ActivityRecord2] (closing, visible)
- final Task parentTask = createTask(mDisplayContent);
- final TaskFragment taskFragment1 = createTaskFragmentWithParentTask(parentTask,
- true /* createEmbeddedTask */);
- final ActivityRecord activity1 = taskFragment1.getTopMostActivity();
- activity1.setVisible(false);
- activity1.mVisibleRequested = true;
-
- final TaskFragment taskFragment2 = createTaskFragmentWithParentTask(parentTask,
- true /* createEmbeddedTask */);
+ final TaskFragment taskFragment2 = createTaskFragmentWithActivity(parentTask);
final ActivityRecord activity2 = taskFragment2.getTopMostActivity();
activity2.setVisible(true);
activity2.mVisibleRequested = false;
@@ -684,8 +651,7 @@ public class AppTransitionControllerTest extends WindowTestsBase {
// [DefaultTDA] -+- [Task1] - [TaskFragment1] - [ActivityRecord1] (opening, invisible)
// +- [Task2] - [ActivityRecord2] (closing, visible)
final Task task1 = createTask(mDisplayContent);
- final TaskFragment taskFragment1 = createTaskFragmentWithParentTask(task1,
- false /* createEmbeddedTask */);
+ final TaskFragment taskFragment1 = createTaskFragmentWithActivity(task1);
final ActivityRecord activity1 = taskFragment1.getTopMostActivity();
activity1.setVisible(false);
activity1.mVisibleRequested = true;
@@ -714,8 +680,7 @@ public class AppTransitionControllerTest extends WindowTestsBase {
// [DefaultTDA] -+- [Task1] - [TaskFragment1] - [ActivityRecord1] (closing, visible)
// +- [Task2] - [ActivityRecord2] (opening, invisible)
final Task task1 = createTask(mDisplayContent);
- final TaskFragment taskFragment1 = createTaskFragmentWithParentTask(task1,
- false /* createEmbeddedTask */);
+ final TaskFragment taskFragment1 = createTaskFragmentWithActivity(task1);
final ActivityRecord activity1 = taskFragment1.getTopMostActivity();
activity1.setVisible(true);
activity1.mVisibleRequested = false;
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java
index 8cfe503d61d7..437eeb1093ca 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java
@@ -228,23 +228,7 @@ public class AppTransitionTests extends WindowTestsBase {
@Test
public void testTaskFragmentOpeningTransition() {
- final ActivityRecord activity = createHierarchyForTaskFragmentTest(
- false /* createEmbeddedTask */);
- activity.setVisible(false);
-
- mDisplayContent.prepareAppTransition(TRANSIT_OPEN);
- mDisplayContent.mOpeningApps.add(activity);
- assertEquals(TRANSIT_OLD_TASK_FRAGMENT_OPEN,
- AppTransitionController.getTransitCompatType(mDisplayContent.mAppTransition,
- mDisplayContent.mOpeningApps, mDisplayContent.mClosingApps,
- mDisplayContent.mChangingContainers, null /* wallpaperTarget */,
- null /* oldWallpaper */, false /* skipAppTransitionAnimation */));
- }
-
- @Test
- public void testEmbeddedTaskOpeningTransition() {
- final ActivityRecord activity = createHierarchyForTaskFragmentTest(
- true /* createEmbeddedTask */);
+ final ActivityRecord activity = createHierarchyForTaskFragmentTest();
activity.setVisible(false);
mDisplayContent.prepareAppTransition(TRANSIT_OPEN);
@@ -258,23 +242,7 @@ public class AppTransitionTests extends WindowTestsBase {
@Test
public void testTaskFragmentClosingTransition() {
- final ActivityRecord activity = createHierarchyForTaskFragmentTest(
- false /* createEmbeddedTask */);
- activity.setVisible(true);
-
- mDisplayContent.prepareAppTransition(TRANSIT_CLOSE);
- mDisplayContent.mClosingApps.add(activity);
- assertEquals(TRANSIT_OLD_TASK_FRAGMENT_CLOSE,
- AppTransitionController.getTransitCompatType(mDisplayContent.mAppTransition,
- mDisplayContent.mOpeningApps, mDisplayContent.mClosingApps,
- mDisplayContent.mChangingContainers, null /* wallpaperTarget */,
- null /* oldWallpaper */, false /* skipAppTransitionAnimation */));
- }
-
- @Test
- public void testEmbeddedTaskClosingTransition() {
- final ActivityRecord activity = createHierarchyForTaskFragmentTest(
- true /* createEmbeddedTask */);
+ final ActivityRecord activity = createHierarchyForTaskFragmentTest();
activity.setVisible(true);
mDisplayContent.prepareAppTransition(TRANSIT_CLOSE);
@@ -292,19 +260,16 @@ public class AppTransitionTests extends WindowTestsBase {
* {@link AppTransitionController#getAnimationTargets(ArraySet, ArraySet, boolean) the animation
* target} to promote to Task or above.
*
- * @param createEmbeddedTask {@code true} to create embedded Task for verified TaskFragment
* @return The Activity to be put in either opening or closing Activity
*/
- private ActivityRecord createHierarchyForTaskFragmentTest(boolean createEmbeddedTask) {
+ private ActivityRecord createHierarchyForTaskFragmentTest() {
final Task parentTask = createTask(mDisplayContent);
- final TaskFragment bottomTaskFragment = createTaskFragmentWithParentTask(parentTask,
- false /* createEmbeddedTask */);
+ final TaskFragment bottomTaskFragment = createTaskFragmentWithActivity(parentTask);
final ActivityRecord bottomActivity = bottomTaskFragment.getTopMostActivity();
bottomActivity.setOccludesParent(true);
bottomActivity.setVisible(true);
- final TaskFragment verifiedTaskFragment = createTaskFragmentWithParentTask(parentTask,
- createEmbeddedTask);
+ final TaskFragment verifiedTaskFragment = createTaskFragmentWithActivity(parentTask);
final ActivityRecord activity = verifiedTaskFragment.getTopMostActivity();
activity.setOccludesParent(true);
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 37ab9a00737f..d1511880451e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -2693,10 +2693,10 @@ public class DisplayContentTests extends WindowTestsBase {
ACTIVITY_TYPE_STANDARD, ON_TOP);
final Task rootTask4 = taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_STANDARD, ON_TOP);
- final Task task1 = new TaskBuilder(mSupervisor).setParentTaskFragment(rootTask1).build();
- final Task task2 = new TaskBuilder(mSupervisor).setParentTaskFragment(rootTask2).build();
- final Task task3 = new TaskBuilder(mSupervisor).setParentTaskFragment(rootTask3).build();
- final Task task4 = new TaskBuilder(mSupervisor).setParentTaskFragment(rootTask4).build();
+ final Task task1 = new TaskBuilder(mSupervisor).setParentTask(rootTask1).build();
+ final Task task2 = new TaskBuilder(mSupervisor).setParentTask(rootTask2).build();
+ final Task task3 = new TaskBuilder(mSupervisor).setParentTask(rootTask3).build();
+ final Task task4 = new TaskBuilder(mSupervisor).setParentTask(rootTask4).build();
// Reordering root tasks while removing root tasks.
doAnswer(invocation -> {
diff --git a/services/tests/wmtests/src/com/android/server/wm/LaunchParamsPersisterTests.java b/services/tests/wmtests/src/com/android/server/wm/LaunchParamsPersisterTests.java
index 8a6db2c62a10..7cb7c79d63a0 100644
--- a/services/tests/wmtests/src/com/android/server/wm/LaunchParamsPersisterTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/LaunchParamsPersisterTests.java
@@ -117,7 +117,7 @@ public class LaunchParamsPersisterTests extends WindowTestsBase {
Task rootTask = mTestDisplay.getDefaultTaskDisplayArea()
.createRootTask(TEST_WINDOWING_MODE, ACTIVITY_TYPE_STANDARD, /* onTop */ true);
mTestTask = new TaskBuilder(mSupervisor).setComponent(TEST_COMPONENT)
- .setParentTaskFragment(rootTask).build();
+ .setParentTask(rootTask).build();
mTestTask.mUserId = TEST_USER_ID;
mTestTask.mLastNonFullscreenBounds = TEST_BOUNDS;
mTestTask.setHasBeenVisible(true);
@@ -353,7 +353,7 @@ public class LaunchParamsPersisterTests extends WindowTestsBase {
final Task anotherTaskOfTheSameUser = new TaskBuilder(mSupervisor)
.setComponent(ALTERNATIVE_COMPONENT)
.setUserId(TEST_USER_ID)
- .setParentTaskFragment(stack)
+ .setParentTask(stack)
.build();
anotherTaskOfTheSameUser.setWindowingMode(WINDOWING_MODE_FREEFORM);
anotherTaskOfTheSameUser.setBounds(200, 300, 400, 500);
@@ -365,7 +365,7 @@ public class LaunchParamsPersisterTests extends WindowTestsBase {
final Task anotherTaskOfDifferentUser = new TaskBuilder(mSupervisor)
.setComponent(TEST_COMPONENT)
.setUserId(ALTERNATIVE_USER_ID)
- .setParentTaskFragment(stack)
+ .setParentTask(stack)
.build();
anotherTaskOfDifferentUser.setWindowingMode(WINDOWING_MODE_FREEFORM);
anotherTaskOfDifferentUser.setBounds(300, 400, 500, 600);
diff --git a/services/tests/wmtests/src/com/android/server/wm/ProtoLogIntegrationTest.java b/services/tests/wmtests/src/com/android/server/wm/ProtoLogIntegrationTest.java
index 578a43cba33d..af0d32c764a4 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ProtoLogIntegrationTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ProtoLogIntegrationTest.java
@@ -50,17 +50,17 @@ public class ProtoLogIntegrationTest {
ProtoLogImpl mockedProtoLog = mock(ProtoLogImpl.class);
runWith(mockedProtoLog, this::testProtoLog);
verify(mockedProtoLog).log(eq(ProtoLogImpl.LogLevel.ERROR), eq(ProtoLogGroup.TEST_GROUP),
- anyInt(), eq(0b0010101001010111),
+ anyInt(), eq(0b0010010111),
eq(com.android.internal.protolog.ProtoLogGroup.TEST_GROUP.isLogToLogcat()
- ? "Test completed successfully: %b %d %o %x %e %g %f %% %s"
+ ? "Test completed successfully: %b %d %x %f %% %s"
: null),
- eq(new Object[]{true, 1L, 2L, 3L, 0.4, 0.5, 0.6, "ok"}));
+ eq(new Object[]{true, 1L, 2L, 0.3, "ok"}));
}
private void testProtoLog() {
ProtoLog.e(ProtoLogGroup.TEST_GROUP,
- "Test completed successfully: %b %d %o %x %e %g %f %% %s.",
- true, 1, 2, 3, 0.4, 0.5, 0.6, "ok");
+ "Test completed successfully: %b %d %x %f %% %s",
+ true, 1, 2, 0.3, "ok");
}
/**
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
index 5def7039f987..ac2df62d6305 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
@@ -332,7 +332,7 @@ public class RecentTasksTest extends WindowTestsBase {
// other task
Task task1 = createTaskBuilder(".Task1")
.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK)
- .setParentTaskFragment(mTaskContainer.getRootHomeTask()).build();
+ .setParentTask(mTaskContainer.getRootHomeTask()).build();
Task task2 = createTaskBuilder(".Task1")
.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK)
.build();
@@ -472,8 +472,8 @@ public class RecentTasksTest extends WindowTestsBase {
final Task root = createTaskBuilder(".CreatedByOrganizerRoot").build();
root.mCreatedByOrganizer = true;
// Add organized and non-organized child.
- final Task child1 = createTaskBuilder(".Task1").setParentTaskFragment(root).build();
- final Task child2 = createTaskBuilder(".Task2").setParentTaskFragment(root).build();
+ final Task child1 = createTaskBuilder(".Task1").setParentTask(root).build();
+ final Task child2 = createTaskBuilder(".Task2").setParentTask(root).build();
doReturn(true).when(child1).isOrganized();
doReturn(false).when(child2).isOrganized();
mRecentTasks.add(root);
@@ -510,7 +510,7 @@ public class RecentTasksTest extends WindowTestsBase {
mRecentTasks.add(task1);
// Go home to trigger the removal of untracked tasks.
mRecentTasks.add(createTaskBuilder(".Home")
- .setParentTaskFragment(mTaskContainer.getRootHomeTask())
+ .setParentTask(mTaskContainer.getRootHomeTask())
.build());
triggerIdleToTrim();
@@ -677,7 +677,7 @@ public class RecentTasksTest extends WindowTestsBase {
public void testVisibleTasks_excludedFromRecents_firstTaskNotVisible() {
// Create some set of tasks, some of which are visible and some are not
Task homeTask = createTaskBuilder("com.android.pkg1", ".HomeTask")
- .setParentTaskFragment(mTaskContainer.getRootHomeTask())
+ .setParentTask(mTaskContainer.getRootHomeTask())
.build();
homeTask.mUserSetupComplete = true;
mRecentTasks.add(homeTask);
@@ -712,7 +712,7 @@ public class RecentTasksTest extends WindowTestsBase {
t1.mUserSetupComplete = true;
mRecentTasks.add(t1);
Task homeTask = createTaskBuilder("com.android.pkg1", ".HomeTask")
- .setParentTaskFragment(mTaskContainer.getRootHomeTask())
+ .setParentTask(mTaskContainer.getRootHomeTask())
.build();
homeTask.mUserSetupComplete = true;
mRecentTasks.add(homeTask);
@@ -976,10 +976,10 @@ public class RecentTasksTest extends WindowTestsBase {
// Add a number of tasks (beyond the max) but ensure that nothing is trimmed because all
// the tasks belong in stacks above the home stack
- mRecentTasks.add(createTaskBuilder(".HomeTask1").setParentTaskFragment(homeStack).build());
- mRecentTasks.add(createTaskBuilder(".Task1").setParentTaskFragment(aboveHomeStack).build());
- mRecentTasks.add(createTaskBuilder(".Task2").setParentTaskFragment(aboveHomeStack).build());
- mRecentTasks.add(createTaskBuilder(".Task3").setParentTaskFragment(aboveHomeStack).build());
+ mRecentTasks.add(createTaskBuilder(".HomeTask1").setParentTask(homeStack).build());
+ mRecentTasks.add(createTaskBuilder(".Task1").setParentTask(aboveHomeStack).build());
+ mRecentTasks.add(createTaskBuilder(".Task2").setParentTask(aboveHomeStack).build());
+ mRecentTasks.add(createTaskBuilder(".Task3").setParentTask(aboveHomeStack).build());
triggerTrimAndAssertNoTasksTrimmed();
}
@@ -997,11 +997,11 @@ public class RecentTasksTest extends WindowTestsBase {
// Add a number of tasks (beyond the max) but ensure that only the task in the stack behind
// the home stack is trimmed once a new task is added
final Task behindHomeTask = createTaskBuilder(".Task1")
- .setParentTaskFragment(behindHomeStack)
+ .setParentTask(behindHomeStack)
.build();
mRecentTasks.add(behindHomeTask);
- mRecentTasks.add(createTaskBuilder(".HomeTask1").setParentTaskFragment(homeStack).build());
- mRecentTasks.add(createTaskBuilder(".Task2").setParentTaskFragment(aboveHomeStack).build());
+ mRecentTasks.add(createTaskBuilder(".HomeTask1").setParentTask(homeStack).build());
+ mRecentTasks.add(createTaskBuilder(".Task2").setParentTask(aboveHomeStack).build());
triggerTrimAndAssertTrimmed(behindHomeTask);
}
@@ -1017,12 +1017,12 @@ public class RecentTasksTest extends WindowTestsBase {
// Add a number of tasks (beyond the max) on each display, ensure that the tasks are not
// removed
- mRecentTasks.add(createTaskBuilder(".HomeTask1").setParentTaskFragment(homeTask).build());
- mRecentTasks.add(createTaskBuilder(".Task1").setParentTaskFragment(otherDisplayRootTask)
+ mRecentTasks.add(createTaskBuilder(".HomeTask1").setParentTask(homeTask).build());
+ mRecentTasks.add(createTaskBuilder(".Task1").setParentTask(otherDisplayRootTask)
.build());
- mRecentTasks.add(createTaskBuilder(".Task2").setParentTaskFragment(otherDisplayRootTask)
+ mRecentTasks.add(createTaskBuilder(".Task2").setParentTask(otherDisplayRootTask)
.build());
- mRecentTasks.add(createTaskBuilder(".HomeTask2").setParentTaskFragment(homeTask).build());
+ mRecentTasks.add(createTaskBuilder(".HomeTask2").setParentTask(homeTask).build());
triggerTrimAndAssertNoTasksTrimmed();
}
@@ -1052,7 +1052,7 @@ public class RecentTasksTest extends WindowTestsBase {
Task t1 = createTaskBuilder("com.android.pkg1", ".Task1").build();
mRecentTasks.add(t1);
mRecentTasks.add(createTaskBuilder("com.android.pkg1", ".HomeTask")
- .setParentTaskFragment(mTaskContainer.getRootHomeTask()).build());
+ .setParentTask(mTaskContainer.getRootHomeTask()).build());
Task t2 = createTaskBuilder("com.android.pkg2", ".Task2").build();
mRecentTasks.add(t2);
mRecentTasks.add(createTaskBuilder("com.android.pkg1", ".PipTask")
diff --git a/services/tests/wmtests/src/com/android/server/wm/RootTaskTests.java b/services/tests/wmtests/src/com/android/server/wm/RootTaskTests.java
index b46e90da3944..881cc5f94f44 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootTaskTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootTaskTests.java
@@ -422,7 +422,7 @@ public class RootTaskTests extends WindowTestsBase {
final ComponentName alias = new ComponentName(DEFAULT_COMPONENT_PACKAGE_NAME,
aliasActivity);
final Task parentTask = new TaskBuilder(mSupervisor).build();
- final Task task = new TaskBuilder(mSupervisor).setParentTaskFragment(parentTask).build();
+ final Task task = new TaskBuilder(mSupervisor).setParentTask(parentTask).build();
task.origActivity = alias;
task.realActivity = target;
new ActivityBuilder(mAtm).setComponent(target).setTask(task).setTargetActivity(
diff --git a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
index e0e1d73657cb..f84865bce0fa 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
@@ -172,7 +172,7 @@ public class RootWindowContainerTests extends WindowTestsBase {
@Test
public void testTaskLayerRank() {
final Task rootTask = new TaskBuilder(mSupervisor).build();
- final Task task1 = new TaskBuilder(mSupervisor).setParentTaskFragment(rootTask).build();
+ final Task task1 = new TaskBuilder(mSupervisor).setParentTask(rootTask).build();
final ActivityRecord activity1 = new ActivityBuilder(mAtm).setTask(task1).build();
activity1.mVisibleRequested = true;
mWm.mRoot.rankTaskLayers();
@@ -645,7 +645,7 @@ public class RootWindowContainerTests extends WindowTestsBase {
final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
final Task targetRootTask = taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_STANDARD, false /* onTop */);
- final Task targetTask = new TaskBuilder(mSupervisor).setParentTaskFragment(targetRootTask)
+ final Task targetTask = new TaskBuilder(mSupervisor).setParentTask(targetRootTask)
.build();
// Create Recents on secondary display.
diff --git a/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java
index eab2e156e9aa..9aa747a9297f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java
@@ -172,7 +172,7 @@ public class RunningTasksTest extends WindowTestsBase {
final Task task = new TaskBuilder(mAtm.mTaskSupervisor)
.setComponent(new ComponentName(mContext.getPackageName(), className))
.setTaskId(taskId)
- .setParentTaskFragment(stack)
+ .setParentTask(stack)
.build();
final ActivityRecord activity = new ActivityBuilder(mAtm)
.setTask(task)
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 7f09606d1c3a..d5fb1a856e31 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java
@@ -614,7 +614,7 @@ public class TaskDisplayAreaTests extends WindowTestsBase {
final Task pinnedRootTask = mRootWindowContainer.getDefaultTaskDisplayArea()
.createRootTask(WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, ON_TOP);
final Task pinnedTask = new TaskBuilder(mAtm.mTaskSupervisor)
- .setParentTaskFragment(pinnedRootTask).build();
+ .setParentTask(pinnedRootTask).build();
new ActivityBuilder(mAtm).setActivityFlags(FLAG_ALWAYS_FOCUSABLE)
.setTask(pinnedTask).build();
pinnedRootTask.moveToFront("movePinnedRootTaskToFront");
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java
index 3ff2c0e0d024..4e796c55dda2 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java
@@ -23,6 +23,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
import static android.os.Process.FIRST_APPLICATION_UID;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.any;
@@ -218,10 +219,8 @@ public class TaskFragmentTest extends WindowTestsBase {
final ActivityRecord bottomActivity = createActivityRecord(bottomTask);
final Task topTask = createTask(mDisplayContent);
// First create primary TF, and then secondary TF, so that the secondary will be on the top.
- final TaskFragment primaryTf = createTaskFragmentWithParentTask(
- topTask, false /* createEmbeddedTask */);
- final TaskFragment secondaryTf = createTaskFragmentWithParentTask(
- topTask, false /* createEmbeddedTask */);
+ final TaskFragment primaryTf = createTaskFragmentWithActivity(topTask);
+ final TaskFragment secondaryTf = createTaskFragmentWithActivity(topTask);
final ActivityRecord primaryActivity = primaryTf.getTopMostActivity();
final ActivityRecord secondaryActivity = secondaryTf.getTopMostActivity();
doReturn(true).when(primaryActivity).supportsPictureInPicture();
@@ -385,7 +384,7 @@ public class TaskFragmentTest extends WindowTestsBase {
final Task rootTask = createTask(mDisplayContent, WINDOWING_MODE_MULTI_WINDOW,
ACTIVITY_TYPE_STANDARD);
final Task leafTask0 = new TaskBuilder(mSupervisor)
- .setParentTaskFragment(rootTask)
+ .setParentTask(rootTask)
.build();
final TaskFragment organizedTf = new TaskFragmentBuilder(mAtm)
.createActivityCount(2)
@@ -421,7 +420,7 @@ public class TaskFragmentTest extends WindowTestsBase {
// There is an activity in a different leaf task on top of activity0 and activity1.
// None of the two has overlay over untrusted mode embedded because it is not the same Task.
final Task leafTask1 = new TaskBuilder(mSupervisor)
- .setParentTaskFragment(rootTask)
+ .setParentTask(rootTask)
.setOnTop(true)
.setCreateActivity(true)
.build();
@@ -547,4 +546,31 @@ public class TaskFragmentTest extends WindowTestsBase {
activity0.moveFocusableActivityToTop("test");
assertEquals(activity0, mDisplayContent.mFocusedApp);
}
+
+ @Test
+ public void testIsVisibleWithAdjacent_reportOrientationUnspecified() {
+ final Task task = createTask(mDisplayContent);
+ final TaskFragment tf0 = createTaskFragmentWithActivity(task);
+ final TaskFragment tf1 = createTaskFragmentWithActivity(task);
+ tf0.setAdjacentTaskFragment(tf1);
+ tf0.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
+ tf1.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
+ task.setBounds(0, 0, 1200, 1000);
+ tf0.setBounds(0, 0, 600, 1000);
+ tf1.setBounds(600, 0, 1200, 1000);
+ final ActivityRecord activity0 = tf0.getTopMostActivity();
+ final ActivityRecord activity1 = tf1.getTopMostActivity();
+ doReturn(true).when(activity0).isVisibleRequested();
+ doReturn(true).when(activity1).isVisibleRequested();
+
+ assertEquals(SCREEN_ORIENTATION_UNSPECIFIED, tf0.getOrientation(SCREEN_ORIENTATION_UNSET));
+ assertEquals(SCREEN_ORIENTATION_UNSPECIFIED, tf1.getOrientation(SCREEN_ORIENTATION_UNSET));
+ assertEquals(SCREEN_ORIENTATION_UNSPECIFIED, task.getOrientation(SCREEN_ORIENTATION_UNSET));
+
+ activity0.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE);
+
+ assertEquals(SCREEN_ORIENTATION_UNSPECIFIED, tf0.getOrientation(SCREEN_ORIENTATION_UNSET));
+ assertEquals(SCREEN_ORIENTATION_UNSPECIFIED, tf1.getOrientation(SCREEN_ORIENTATION_UNSET));
+ assertEquals(SCREEN_ORIENTATION_UNSPECIFIED, task.getOrientation(SCREEN_ORIENTATION_UNSET));
+ }
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java
index 2189ef8985e5..a4cc09a205f6 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java
@@ -85,6 +85,11 @@ public class TaskLaunchParamsModifierTests extends WindowTestsBase {
private static final Rect DISPLAY_STABLE_BOUNDS = new Rect(/* left */ 100,
/* top */ 200, /* right */ 1620, /* bottom */ 680);
+ private static final Rect SMALL_DISPLAY_BOUNDS = new Rect(/* left */ 0, /* top */ 0,
+ /* right */ 1000, /* bottom */ 500);
+ private static final Rect SMALL_DISPLAY_STABLE_BOUNDS = new Rect(/* left */ 100,
+ /* top */ 50, /* right */ 900, /* bottom */ 450);
+
private ActivityRecord mActivity;
private TaskLaunchParamsModifier mTarget;
@@ -888,10 +893,11 @@ public class TaskLaunchParamsModifierTests extends WindowTestsBase {
}
@Test
- public void testLaunchesPortraitUnresizableOnFreeformDisplayWithFreeformSizeCompat() {
+ public void testLaunchesPortraitUnresizableOnFreeformLandscapeDisplay() {
mAtm.mDevEnableNonResizableMultiWindow = true;
final TestDisplayContent freeformDisplay = createNewDisplayContent(
WINDOWING_MODE_FREEFORM);
+ assertTrue(freeformDisplay.getBounds().width() > freeformDisplay.getBounds().height());
final ActivityOptions options = ActivityOptions.makeBasic();
mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea();
mActivity.info.resizeMode = RESIZE_MODE_UNRESIZEABLE;
@@ -899,12 +905,42 @@ public class TaskLaunchParamsModifierTests extends WindowTestsBase {
assertEquals(RESULT_CONTINUE,
new CalculateRequestBuilder().setOptions(options).calculate());
- assertEquivalentWindowingMode(WINDOWING_MODE_FREEFORM, mResult.mWindowingMode,
+ assertEquals(WINDOWING_MODE_UNDEFINED, mResult.mWindowingMode);
+ }
+
+ @Test
+ public void testLaunchesLandscapeUnresizableOnFreeformLandscapeDisplay() {
+ mAtm.mDevEnableNonResizableMultiWindow = true;
+ final TestDisplayContent freeformDisplay = createNewDisplayContent(
WINDOWING_MODE_FREEFORM);
+ assertTrue(freeformDisplay.getBounds().width() > freeformDisplay.getBounds().height());
+ final ActivityOptions options = ActivityOptions.makeBasic();
+ mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea();
+ mActivity.info.resizeMode = RESIZE_MODE_UNRESIZEABLE;
+ mActivity.info.screenOrientation = SCREEN_ORIENTATION_LANDSCAPE;
+ assertEquals(RESULT_CONTINUE,
+ new CalculateRequestBuilder().setOptions(options).calculate());
+
+ assertEquals(WINDOWING_MODE_FULLSCREEN, mResult.mWindowingMode);
+ }
+
+ @Test
+ public void testLaunchesUndefinedUnresizableOnFreeformLandscapeDisplay() {
+ mAtm.mDevEnableNonResizableMultiWindow = true;
+ final TestDisplayContent freeformDisplay = createNewDisplayContent(
+ WINDOWING_MODE_FREEFORM);
+ assertTrue(freeformDisplay.getBounds().width() > freeformDisplay.getBounds().height());
+ final ActivityOptions options = ActivityOptions.makeBasic();
+ mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea();
+ mActivity.info.resizeMode = RESIZE_MODE_UNRESIZEABLE;
+ assertEquals(RESULT_CONTINUE,
+ new CalculateRequestBuilder().setOptions(options).calculate());
+
+ assertEquals(WINDOWING_MODE_FULLSCREEN, mResult.mWindowingMode);
}
@Test
- public void testSkipsForceMaximizingAppsOnNonFreeformDisplay() {
+ public void testForceMaximizingAppsOnNonFreeformDisplay() {
final ActivityOptions options = ActivityOptions.makeBasic();
options.setLaunchWindowingMode(WINDOWING_MODE_FREEFORM);
options.setLaunchBounds(new Rect(0, 0, 200, 100));
@@ -918,8 +954,9 @@ public class TaskLaunchParamsModifierTests extends WindowTestsBase {
assertEquals(RESULT_CONTINUE,
new CalculateRequestBuilder().setOptions(options).calculate());
- assertEquivalentWindowingMode(WINDOWING_MODE_FREEFORM, mResult.mWindowingMode,
- WINDOWING_MODE_FULLSCREEN);
+ // Non-resizable apps must be launched in fullscreen in a fullscreen display regardless of
+ // other properties.
+ assertEquals(WINDOWING_MODE_FULLSCREEN, mResult.mWindowingMode);
}
@Test
@@ -1414,6 +1451,20 @@ public class TaskLaunchParamsModifierTests extends WindowTestsBase {
}
@Test
+ public void testDefaultFreeformSizeShrinksOnSmallDisplay() {
+ final TestDisplayContent freeformDisplay = createNewDisplayContent(
+ WINDOWING_MODE_FREEFORM, SMALL_DISPLAY_BOUNDS, SMALL_DISPLAY_STABLE_BOUNDS);
+
+ final ActivityOptions options = ActivityOptions.makeBasic();
+ options.setLaunchDisplayId(freeformDisplay.mDisplayId);
+
+ assertEquals(RESULT_CONTINUE, new CalculateRequestBuilder().setOptions(options)
+ .calculate());
+
+ assertEquals(new Rect(414, 77, 587, 423), mResult.mBounds);
+ }
+
+ @Test
public void testDefaultFreeformSizeRespectsMinAspectRatio() {
final TestDisplayContent freeformDisplay = createNewDisplayContent(
WINDOWING_MODE_FREEFORM);
@@ -1603,16 +1654,15 @@ public class TaskLaunchParamsModifierTests extends WindowTestsBase {
options.setLaunchDisplayId(freeformDisplay.mDisplayId);
mCurrent.mWindowingMode = WINDOWING_MODE_FREEFORM;
- mCurrent.mBounds.set(100, 300, 1820, 1380);
+ mCurrent.mBounds.set(0, 0, 3000, 2000);
mActivity.info.applicationInfo.targetSdkVersion = Build.VERSION_CODES.LOLLIPOP;
assertEquals(RESULT_CONTINUE,
new CalculateRequestBuilder().setOptions(options).calculate());
- assertTrue("Result bounds should start from app bounds's origin, but it's "
- + mResult.mBounds,
- mResult.mBounds.left == 100 && mResult.mBounds.top == 200);
+ // Must shrink to fit the display while reserving aspect ratio.
+ assertEquals(new Rect(127, 227, 766, 653), mResult.mBounds);
}
@Test
@@ -1628,18 +1678,19 @@ public class TaskLaunchParamsModifierTests extends WindowTestsBase {
final ActivityOptions options = ActivityOptions.makeBasic();
options.setLaunchDisplayId(freeformDisplay.mDisplayId);
+ final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder()
+ .setMinWidth(500).setMinHeight(500).build();
mCurrent.mWindowingMode = WINDOWING_MODE_FREEFORM;
- mCurrent.mBounds.set(100, 300, 1820, 1380);
+ mCurrent.mBounds.set(0, 0, 2000, 3000);
mActivity.info.applicationInfo.targetSdkVersion = Build.VERSION_CODES.LOLLIPOP;
assertEquals(RESULT_CONTINUE,
- new CalculateRequestBuilder().setOptions(options).calculate());
+ new CalculateRequestBuilder().setOptions(options).setLayout(layout).calculate());
- assertTrue("Result bounds should start from top-right corner of app bounds, but "
- + "it's " + mResult.mBounds,
- mResult.mBounds.left == -100 && mResult.mBounds.top == 200);
+ // Must shrink to fit the display while reserving aspect ratio.
+ assertEquals(new Rect(1093, 227, 1593, 727), mResult.mBounds);
}
@Test
@@ -1814,7 +1865,7 @@ public class TaskLaunchParamsModifierTests extends WindowTestsBase {
assertEquals(RESULT_CONTINUE,
new CalculateRequestBuilder().setOptions(options).calculate());
- assertEquals(new Rect(100, 200, 400, 500), mResult.mBounds);
+ assertEquals(new Rect(127, 227, 427, 527), mResult.mBounds);
}
@Test
@@ -1867,13 +1918,18 @@ public class TaskLaunchParamsModifierTests extends WindowTestsBase {
}
private TestDisplayContent createNewDisplayContent(int windowingMode) {
+ return createNewDisplayContent(windowingMode, DISPLAY_BOUNDS, DISPLAY_STABLE_BOUNDS);
+ }
+
+ private TestDisplayContent createNewDisplayContent(int windowingMode, Rect displayBounds,
+ Rect displayStableBounds) {
final TestDisplayContent display = addNewDisplayContentAt(DisplayContent.POSITION_TOP);
display.getDefaultTaskDisplayArea().setWindowingMode(windowingMode);
- display.setBounds(DISPLAY_BOUNDS);
+ display.setBounds(displayBounds);
display.getConfiguration().densityDpi = DENSITY_DEFAULT;
display.getConfiguration().orientation = ORIENTATION_LANDSCAPE;
configInsetsState(display.getInsetsStateController().getRawInsetsState(), display,
- DISPLAY_STABLE_BOUNDS);
+ displayStableBounds);
return display;
}
@@ -1926,7 +1982,7 @@ public class TaskLaunchParamsModifierTests extends WindowTestsBase {
final Task rootTask = display.getDefaultTaskDisplayArea()
.createRootTask(display.getWindowingMode(), ACTIVITY_TYPE_STANDARD, true);
rootTask.setWindowingMode(WINDOWING_MODE_FREEFORM);
- final Task task = new TaskBuilder(mSupervisor).setParentTaskFragment(rootTask).build();
+ final Task task = new TaskBuilder(mSupervisor).setParentTask(rootTask).build();
// Just work around the unnecessary adjustments for bounds.
task.getWindowConfiguration().setBounds(bounds);
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
index d52c34bdc9e1..74d78842c7ac 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
@@ -149,8 +149,8 @@ public class TaskTests extends WindowTestsBase {
public void testRemoveContainer_multipleNestedTasks() {
final Task rootTask = createTask(mDisplayContent);
rootTask.mCreatedByOrganizer = true;
- final Task task1 = new TaskBuilder(mSupervisor).setParentTaskFragment(rootTask).build();
- final Task task2 = new TaskBuilder(mSupervisor).setParentTaskFragment(rootTask).build();
+ final Task task1 = new TaskBuilder(mSupervisor).setParentTask(rootTask).build();
+ final Task task2 = new TaskBuilder(mSupervisor).setParentTask(rootTask).build();
final ActivityRecord activity1 = createActivityRecord(task1);
final ActivityRecord activity2 = createActivityRecord(task2);
activity1.setVisible(false);
@@ -498,7 +498,7 @@ public class TaskTests extends WindowTestsBase {
TaskDisplayArea taskDisplayArea = mAtm.mRootWindowContainer.getDefaultTaskDisplayArea();
Task rootTask = taskDisplayArea.createRootTask(WINDOWING_MODE_FREEFORM,
ACTIVITY_TYPE_STANDARD, true /* onTop */);
- Task task = new TaskBuilder(mSupervisor).setParentTaskFragment(rootTask).build();
+ Task task = new TaskBuilder(mSupervisor).setParentTask(rootTask).build();
final Configuration parentConfig = rootTask.getConfiguration();
parentConfig.windowConfiguration.setBounds(parentBounds);
parentConfig.densityDpi = DisplayMetrics.DENSITY_DEFAULT;
@@ -800,7 +800,7 @@ public class TaskTests extends WindowTestsBase {
DisplayInfo displayInfo = new DisplayInfo();
mAtm.mContext.getDisplay().getDisplayInfo(displayInfo);
final int displayHeight = displayInfo.logicalHeight;
- final Task task = new TaskBuilder(mSupervisor).setParentTaskFragment(rootTask).build();
+ final Task task = new TaskBuilder(mSupervisor).setParentTask(rootTask).build();
final Configuration inOutConfig = new Configuration();
final Configuration parentConfig = new Configuration();
final int longSide = 1200;
@@ -1456,10 +1456,8 @@ public class TaskTests extends WindowTestsBase {
@Test
public void testResumeTask_doNotResumeTaskFragmentBehindTranslucent() {
final Task task = createTask(mDisplayContent);
- final TaskFragment tfBehind = createTaskFragmentWithParentTask(
- task, false /* createEmbeddedTask */);
- final TaskFragment tfFront = createTaskFragmentWithParentTask(
- task, false /* createEmbeddedTask */);
+ final TaskFragment tfBehind = createTaskFragmentWithActivity(task);
+ final TaskFragment tfFront = createTaskFragmentWithActivity(task);
spyOn(tfFront);
doReturn(true).when(tfFront).isTranslucent(any());
@@ -1479,8 +1477,8 @@ public class TaskTests extends WindowTestsBase {
@Test
public void testGetTaskFragment() {
final Task parentTask = createTask(mDisplayContent);
- final TaskFragment tf0 = createTaskFragmentWithParentTask(parentTask);
- final TaskFragment tf1 = createTaskFragmentWithParentTask(parentTask);
+ final TaskFragment tf0 = createTaskFragmentWithActivity(parentTask);
+ final TaskFragment tf1 = createTaskFragmentWithActivity(parentTask);
assertNull("Could not find it because there's no organized TaskFragment",
parentTask.getTaskFragment(TaskFragment::isOrganizedTaskFragment));
@@ -1522,7 +1520,7 @@ public class TaskTests extends WindowTestsBase {
TaskDisplayArea taskDisplayArea = mAtm.mRootWindowContainer.getDefaultTaskDisplayArea();
Task rootTask = taskDisplayArea.createRootTask(windowingMode, ACTIVITY_TYPE_STANDARD,
true /* onTop */);
- Task task = new TaskBuilder(mSupervisor).setParentTaskFragment(rootTask).build();
+ Task task = new TaskBuilder(mSupervisor).setParentTask(rootTask).build();
final Configuration parentConfig = rootTask.getConfiguration();
parentConfig.windowConfiguration.setAppBounds(parentBounds);
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
index c8ea70c5d650..50fcafca5273 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
@@ -1150,8 +1150,8 @@ public class WindowContainerTests extends WindowTestsBase {
@Test
public void testStartChangeTransitionWhenPreviousIsNotFinished() {
- final WindowContainer container = createTaskFragmentWithParentTask(
- createTask(mDisplayContent), false);
+ final WindowContainer container = createTaskFragmentWithActivity(
+ createTask(mDisplayContent));
container.mSurfaceControl = mock(SurfaceControl.class);
final SurfaceAnimator surfaceAnimator = container.mSurfaceAnimator;
final SurfaceFreezer surfaceFreezer = container.mSurfaceFreezer;
@@ -1214,8 +1214,8 @@ public class WindowContainerTests extends WindowTestsBase {
@Test
public void testUnfreezeWindow_removeWindowFromChanging() {
- final WindowContainer container = createTaskFragmentWithParentTask(
- createTask(mDisplayContent), false);
+ final WindowContainer container = createTaskFragmentWithActivity(
+ createTask(mDisplayContent));
mockSurfaceFreezerSnapshot(container.mSurfaceFreezer);
final SurfaceControl.Transaction t = mock(SurfaceControl.Transaction.class);
@@ -1230,8 +1230,8 @@ public class WindowContainerTests extends WindowTestsBase {
@Test
public void testFailToTaskSnapshot_unfreezeWindow() {
- final WindowContainer container = createTaskFragmentWithParentTask(
- createTask(mDisplayContent), false);
+ final WindowContainer container = createTaskFragmentWithActivity(
+ createTask(mDisplayContent));
final SurfaceControl.Transaction t = mock(SurfaceControl.Transaction.class);
spyOn(container.mSurfaceFreezer);
@@ -1244,8 +1244,8 @@ public class WindowContainerTests extends WindowTestsBase {
@Test
public void testRemoveUnstartedFreezeSurfaceWhenFreezeAgain() {
- final WindowContainer container = createTaskFragmentWithParentTask(
- createTask(mDisplayContent), false);
+ final WindowContainer container = createTaskFragmentWithActivity(
+ createTask(mDisplayContent));
container.mSurfaceControl = mock(SurfaceControl.class);
final SurfaceFreezer surfaceFreezer = container.mSurfaceFreezer;
mockSurfaceFreezerSnapshot(surfaceFreezer);
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
index ab042d15963b..1348770bd807 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
@@ -655,7 +655,7 @@ class WindowTestsBase extends SystemServiceTestsBase {
Task createTaskInRootTask(Task rootTask, int userId) {
final Task task = new TaskBuilder(rootTask.mTaskSupervisor)
.setUserId(userId)
- .setParentTaskFragment(rootTask)
+ .setParentTask(rootTask)
.build();
return task;
}
@@ -741,28 +741,18 @@ class WindowTestsBase extends SystemServiceTestsBase {
activity.mVisibleRequested = true;
}
- static TaskFragment createTaskFragmentWithParentTask(@NonNull Task parentTask) {
- return createTaskFragmentWithParentTask(parentTask, false /* createEmbeddedTask */);
- }
-
/**
- * Creates a {@link TaskFragment} and attach it to the {@code parentTask}.
+ * Creates a {@link TaskFragment} with {@link ActivityRecord} and attach it to the
+ * {@code parentTask}.
*
* @param parentTask the {@link Task} this TaskFragment is going to be attached
- * @param createEmbeddedTask Sets to {@code true} to create an embedded Task for this
- * TaskFragment. Otherwise, create a {@link ActivityRecord}.
* @return the created TaskFragment
*/
- static TaskFragment createTaskFragmentWithParentTask(@NonNull Task parentTask,
- boolean createEmbeddedTask) {
- final TaskFragmentBuilder builder = new TaskFragmentBuilder(parentTask.mAtmService)
- .setParentTask(parentTask);
- if (createEmbeddedTask) {
- builder.createEmbeddedTask();
- } else {
- builder.createActivityCount(1);
- }
- return builder.build();
+ static TaskFragment createTaskFragmentWithActivity(@NonNull Task parentTask) {
+ return new TaskFragmentBuilder(parentTask.mAtmService)
+ .setParentTask(parentTask)
+ .createActivityCount(1)
+ .build();
}
static TaskFragment createTaskFragmentWithEmbeddedActivity(@NonNull Task parentTask,
@@ -1218,7 +1208,7 @@ class WindowTestsBase extends SystemServiceTestsBase {
// Apply the root activity info and intent
.setActivityInfo(aInfo)
.setIntent(intent)
- .setParentTaskFragment(mParentTask).build();
+ .setParentTask(mParentTask).build();
} else if (mTask == null && mParentTask != null && DisplayContent.alwaysCreateRootTask(
mParentTask.getWindowingMode(), mParentTask.getActivityType())) {
// The parent task can be the task root.
@@ -1275,7 +1265,6 @@ class WindowTestsBase extends SystemServiceTestsBase {
private final ActivityTaskManagerService mAtm;
private Task mParentTask;
private boolean mCreateParentTask;
- private boolean mCreateEmbeddedTask;
private int mCreateActivityCount = 0;
@Nullable
private TaskFragmentOrganizer mOrganizer;
@@ -1296,12 +1285,6 @@ class WindowTestsBase extends SystemServiceTestsBase {
return this;
}
- /** Creates a child embedded Task and its Activity */
- TaskFragmentBuilder createEmbeddedTask() {
- mCreateEmbeddedTask = true;
- return this;
- }
-
TaskFragmentBuilder createActivityCount(int count) {
mCreateActivityCount = count;
return this;
@@ -1333,12 +1316,6 @@ class WindowTestsBase extends SystemServiceTestsBase {
if (mParentTask != null) {
mParentTask.addChild(taskFragment, POSITION_TOP);
}
- if (mCreateEmbeddedTask) {
- new TaskBuilder(mAtm.mTaskSupervisor)
- .setParentTaskFragment(taskFragment)
- .setCreateActivity(true)
- .build();
- }
while (mCreateActivityCount > 0) {
final ActivityRecord activity = new ActivityBuilder(mAtm).build();
taskFragment.addChild(activity);
@@ -1377,7 +1354,7 @@ class WindowTestsBase extends SystemServiceTestsBase {
private IVoiceInteractionSession mVoiceSession;
private boolean mCreateParentTask = false;
- private TaskFragment mParentTaskFragment;
+ private Task mParentTask;
private boolean mCreateActivity = false;
private boolean mCreatedByOrganizer = false;
@@ -1462,8 +1439,8 @@ class WindowTestsBase extends SystemServiceTestsBase {
return this;
}
- TaskBuilder setParentTaskFragment(TaskFragment parentTaskFragment) {
- mParentTaskFragment = parentTaskFragment;
+ TaskBuilder setParentTask(Task parentTask) {
+ mParentTask = parentTask;
return this;
}
@@ -1481,13 +1458,12 @@ class WindowTestsBase extends SystemServiceTestsBase {
SystemServicesTestRule.checkHoldsLock(mSupervisor.mService.mGlobalLock);
// Create parent task.
- if (mParentTaskFragment == null && mCreateParentTask) {
- mParentTaskFragment = mTaskDisplayArea.createRootTask(
+ if (mParentTask == null && mCreateParentTask) {
+ mParentTask = mTaskDisplayArea.createRootTask(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
}
- if (mParentTaskFragment != null
- && !Mockito.mockingDetails(mParentTaskFragment).isSpy()) {
- spyOn(mParentTaskFragment);
+ if (mParentTask != null && !Mockito.mockingDetails(mParentTask).isSpy()) {
+ spyOn(mParentTask);
}
// Create task.
@@ -1515,15 +1491,13 @@ class WindowTestsBase extends SystemServiceTestsBase {
.setVoiceSession(mVoiceSession)
.setCreatedByOrganizer(mCreatedByOrganizer);
final Task task;
- if (mParentTaskFragment == null) {
+ if (mParentTask == null) {
task = builder.setActivityType(mActivityType)
.setParent(mTaskDisplayArea)
.build();
} else {
- task = builder.setParent(mParentTaskFragment).build();
- if (mParentTaskFragment.asTask() != null) {
- mParentTaskFragment.asTask().moveToFront("build-task");
- }
+ task = builder.setParent(mParentTask).build();
+ mParentTask.moveToFront("build-task");
}
spyOn(task);
task.mUserId = mUserId;
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
index 3e49aedbb41e..415166328519 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
@@ -595,7 +595,7 @@ final class HotwordDetectionConnection {
detectFromDspSource(event, callback);
}
- private void detectFromDspSource(SoundTrigger.KeyphraseRecognitionEvent recognitionEvent,
+ void detectFromDspSource(SoundTrigger.KeyphraseRecognitionEvent recognitionEvent,
IHotwordRecognitionStatusCallback externalCallback) {
if (DEBUG) {
Slog.d(TAG, "detectFromDspSource");
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/TrustedHotwordDetectorSession.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/TrustedHotwordDetectorSession.java
new file mode 100644
index 000000000000..b87b8f790338
--- /dev/null
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/TrustedHotwordDetectorSession.java
@@ -0,0 +1,1324 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.voiceinteraction;
+
+import static android.Manifest.permission.CAPTURE_AUDIO_HOTWORD;
+import static android.Manifest.permission.RECORD_AUDIO;
+import static android.service.attention.AttentionService.PROXIMITY_UNKNOWN;
+import static android.service.voice.HotwordDetectionService.AUDIO_SOURCE_EXTERNAL;
+import static android.service.voice.HotwordDetectionService.AUDIO_SOURCE_MICROPHONE;
+import static android.service.voice.HotwordDetectionService.ENABLE_PROXIMITY_RESULT;
+import static android.service.voice.HotwordDetectionService.INITIALIZATION_STATUS_SUCCESS;
+import static android.service.voice.HotwordDetectionService.INITIALIZATION_STATUS_UNKNOWN;
+import static android.service.voice.HotwordDetectionService.KEY_INITIALIZATION_STATUS;
+
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED__RESULT__CALLBACK_INIT_STATE_ERROR;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED__RESULT__CALLBACK_INIT_STATE_SUCCESS;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED__RESULT__CALLBACK_INIT_STATE_UNKNOWN_NO_VALUE;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED__RESULT__CALLBACK_INIT_STATE_UNKNOWN_OVER_MAX_CUSTOM_VALUE;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED__RESULT__CALLBACK_INIT_STATE_UNKNOWN_TIMEOUT;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTION_SERVICE_RESTARTED__REASON__AUDIO_SERVICE_DIED;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTION_SERVICE_RESTARTED__REASON__SCHEDULE;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__APP_REQUEST_UPDATE_STATE;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__CALLBACK_ON_ERROR_EXCEPTION;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__CALLBACK_ON_PROCESS_RESTARTED_EXCEPTION;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__CALLBACK_ON_REJECTED_EXCEPTION;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__CALLBACK_ON_STATUS_REPORTED_EXCEPTION;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__CALLBACK_UPDATE_STATE_AFTER_TIMEOUT;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__CALL_UPDATE_STATE_EXCEPTION;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__EXTERNAL_SOURCE_DETECTED;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__EXTERNAL_SOURCE_DETECT_SECURITY_EXCEPTION;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__EXTERNAL_SOURCE_REJECTED;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__ON_CONNECTED;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__ON_DISCONNECTED;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__REQUEST_BIND_SERVICE;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__REQUEST_BIND_SERVICE_FAIL;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__REQUEST_UPDATE_STATE;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__START_EXTERNAL_SOURCE_DETECTION;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__START_SOFTWARE_DETECTION;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__DETECTOR_TYPE__NORMAL_DETECTOR;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__DETECTOR_TYPE__TRUSTED_DETECTOR_DSP;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__DETECTED;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__DETECT_SECURITY_EXCEPTION;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__DETECT_TIMEOUT;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__DETECT_UNEXPECTED_CALLBACK;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__KEYPHRASE_TRIGGER;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__REJECTED;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__REJECTED_FROM_RESTART;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__REJECT_UNEXPECTED_CALLBACK;
+import static com.android.server.voiceinteraction.SoundTriggerSessionPermissionsDecorator.enforcePermissionForPreflight;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.AppOpsManager;
+import android.attention.AttentionManagerInternal;
+import android.content.ComponentName;
+import android.content.ContentCaptureOptions;
+import android.content.Context;
+import android.content.Intent;
+import android.content.PermissionChecker;
+import android.hardware.soundtrigger.IRecognitionStatusCallback;
+import android.hardware.soundtrigger.SoundTrigger;
+import android.media.AudioFormat;
+import android.media.AudioManagerInternal;
+import android.media.permission.Identity;
+import android.media.permission.PermissionUtil;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.IRemoteCallback;
+import android.os.ParcelFileDescriptor;
+import android.os.PersistableBundle;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.SharedMemory;
+import android.provider.DeviceConfig;
+import android.service.voice.HotwordDetectedResult;
+import android.service.voice.HotwordDetectionService;
+import android.service.voice.HotwordDetector;
+import android.service.voice.HotwordRejectedResult;
+import android.service.voice.IDspHotwordDetectionCallback;
+import android.service.voice.IHotwordDetectionService;
+import android.service.voice.IMicrophoneHotwordDetectionVoiceInteractionCallback;
+import android.service.voice.VoiceInteractionManagerInternal.HotwordDetectionServiceIdentity;
+import android.speech.IRecognitionServiceManager;
+import android.text.TextUtils;
+import android.util.Pair;
+import android.util.Slog;
+import android.view.contentcapture.IContentCaptureManager;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.app.IHotwordRecognitionStatusCallback;
+import com.android.internal.infra.AndroidFuture;
+import com.android.internal.infra.ServiceConnector;
+import com.android.server.LocalServices;
+import com.android.server.pm.permission.PermissionManagerServiceInternal;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.time.Duration;
+import java.time.Instant;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.Function;
+
+/**
+ * A class that provides the communication with the HotwordDetectionService.
+ */
+final class TrustedHotwordDetectorSession {
+ private static final String TAG = "TrustedHotwordDetectorSession";
+ static final boolean DEBUG = false;
+
+ private static final String KEY_RESTART_PERIOD_IN_SECONDS = "restart_period_in_seconds";
+ // TODO: These constants need to be refined.
+ // The validation timeout value is 3 seconds for onDetect of DSP trigger event.
+ private static final long VALIDATION_TIMEOUT_MILLIS = 3000;
+ // Write the onDetect timeout metric when it takes more time than MAX_VALIDATION_TIMEOUT_MILLIS.
+ private static final long MAX_VALIDATION_TIMEOUT_MILLIS = 4000;
+ private static final long MAX_UPDATE_TIMEOUT_MILLIS = 30000;
+ private static final long EXTERNAL_HOTWORD_CLEANUP_MILLIS = 2000;
+ private static final Duration MAX_UPDATE_TIMEOUT_DURATION =
+ Duration.ofMillis(MAX_UPDATE_TIMEOUT_MILLIS);
+ private static final long RESET_DEBUG_HOTWORD_LOGGING_TIMEOUT_MILLIS = 60 * 60 * 1000; // 1 hour
+ private static final int MAX_ISOLATED_PROCESS_NUMBER = 10;
+
+ // The error codes are used for onError callback
+ private static final int HOTWORD_DETECTION_SERVICE_DIED = -1;
+ private static final int CALLBACK_ONDETECTED_GOT_SECURITY_EXCEPTION = -2;
+ private static final int CALLBACK_DETECT_TIMEOUT = -3;
+ private static final int CALLBACK_ONDETECTED_STREAM_COPY_ERROR = -4;
+
+ // Hotword metrics
+ private static final int METRICS_INIT_UNKNOWN_TIMEOUT =
+ HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED__RESULT__CALLBACK_INIT_STATE_UNKNOWN_TIMEOUT;
+ private static final int METRICS_INIT_UNKNOWN_NO_VALUE =
+ HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED__RESULT__CALLBACK_INIT_STATE_UNKNOWN_NO_VALUE;
+ private static final int METRICS_INIT_UNKNOWN_OVER_MAX_CUSTOM_VALUE =
+ HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED__RESULT__CALLBACK_INIT_STATE_UNKNOWN_OVER_MAX_CUSTOM_VALUE;
+ private static final int METRICS_INIT_CALLBACK_STATE_ERROR =
+ HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED__RESULT__CALLBACK_INIT_STATE_ERROR;
+ private static final int METRICS_INIT_CALLBACK_STATE_SUCCESS =
+ HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED__RESULT__CALLBACK_INIT_STATE_SUCCESS;
+
+ private static final int METRICS_KEYPHRASE_TRIGGERED_DETECT_SECURITY_EXCEPTION =
+ HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__DETECT_SECURITY_EXCEPTION;
+ private static final int METRICS_KEYPHRASE_TRIGGERED_DETECT_UNEXPECTED_CALLBACK =
+ HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__DETECT_UNEXPECTED_CALLBACK;
+ private static final int METRICS_KEYPHRASE_TRIGGERED_REJECT_UNEXPECTED_CALLBACK =
+ HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__REJECT_UNEXPECTED_CALLBACK;
+
+ private static final int METRICS_EXTERNAL_SOURCE_DETECTED =
+ HOTWORD_DETECTOR_EVENTS__EVENT__EXTERNAL_SOURCE_DETECTED;
+ private static final int METRICS_EXTERNAL_SOURCE_REJECTED =
+ HOTWORD_DETECTOR_EVENTS__EVENT__EXTERNAL_SOURCE_REJECTED;
+ private static final int METRICS_EXTERNAL_SOURCE_DETECT_SECURITY_EXCEPTION =
+ HOTWORD_DETECTOR_EVENTS__EVENT__EXTERNAL_SOURCE_DETECT_SECURITY_EXCEPTION;
+ private static final int METRICS_CALLBACK_ON_STATUS_REPORTED_EXCEPTION =
+ HOTWORD_DETECTOR_EVENTS__EVENT__CALLBACK_ON_STATUS_REPORTED_EXCEPTION;
+
+ private final Executor mAudioCopyExecutor = Executors.newCachedThreadPool();
+ // TODO: This may need to be a Handler(looper)
+ private final ScheduledExecutorService mScheduledExecutorService =
+ Executors.newSingleThreadScheduledExecutor();
+ private final AppOpsManager mAppOpsManager;
+ private final HotwordAudioStreamManager mHotwordAudioStreamManager;
+ @Nullable private final ScheduledFuture<?> mCancellationTaskFuture;
+ private final AtomicBoolean mUpdateStateAfterStartFinished = new AtomicBoolean(false);
+ private final IBinder.DeathRecipient mAudioServerDeathRecipient = this::audioServerDied;
+ private final @NonNull ServiceConnectionFactory mServiceConnectionFactory;
+ private final IHotwordRecognitionStatusCallback mCallback;
+ private final int mDetectorType;
+ /**
+ * Time after which each HotwordDetectionService process is stopped and replaced by a new one.
+ * 0 indicates no restarts.
+ */
+ private final int mReStartPeriodSeconds;
+
+ final Object mLock;
+ final int mVoiceInteractionServiceUid;
+ final ComponentName mDetectionComponentName;
+ final int mUser;
+ final Context mContext;
+
+ @Nullable AttentionManagerInternal mAttentionManagerInternal = null;
+
+ final AttentionManagerInternal.ProximityUpdateCallbackInternal mProximityCallbackInternal =
+ this::setProximityValue;
+
+
+ volatile HotwordDetectionServiceIdentity mIdentity;
+ private IMicrophoneHotwordDetectionVoiceInteractionCallback mSoftwareCallback;
+ private Instant mLastRestartInstant;
+
+ private ScheduledFuture<?> mCancellationKeyPhraseDetectionFuture;
+ private ScheduledFuture<?> mDebugHotwordLoggingTimeoutFuture = null;
+
+ /** Identity used for attributing app ops when delivering data to the Interactor. */
+ @GuardedBy("mLock")
+ @Nullable
+ private final Identity mVoiceInteractorIdentity;
+ @GuardedBy("mLock")
+ private ParcelFileDescriptor mCurrentAudioSink;
+ @GuardedBy("mLock")
+ private boolean mValidatingDspTrigger = false;
+ @GuardedBy("mLock")
+ private boolean mPerformingSoftwareHotwordDetection;
+ private @NonNull ServiceConnection mRemoteHotwordDetectionService;
+ private IBinder mAudioFlinger;
+ private boolean mDebugHotwordLogging = false;
+ @GuardedBy("mLock")
+ private double mProximityMeters = PROXIMITY_UNKNOWN;
+
+ TrustedHotwordDetectorSession(Object lock, Context context, int voiceInteractionServiceUid,
+ Identity voiceInteractorIdentity, ComponentName serviceName, int userId,
+ boolean bindInstantServiceAllowed, @Nullable PersistableBundle options,
+ @Nullable SharedMemory sharedMemory,
+ @NonNull IHotwordRecognitionStatusCallback callback, int detectorType) {
+ if (callback == null) {
+ Slog.w(TAG, "Callback is null while creating connection");
+ throw new IllegalArgumentException("Callback is null while creating connection");
+ }
+ mLock = lock;
+ mContext = context;
+ mVoiceInteractionServiceUid = voiceInteractionServiceUid;
+ mVoiceInteractorIdentity = voiceInteractorIdentity;
+ mAppOpsManager = mContext.getSystemService(AppOpsManager.class);
+ mHotwordAudioStreamManager = new HotwordAudioStreamManager(mAppOpsManager,
+ mVoiceInteractorIdentity);
+ mDetectionComponentName = serviceName;
+ mUser = userId;
+ mCallback = callback;
+ mDetectorType = detectorType;
+ mReStartPeriodSeconds = DeviceConfig.getInt(DeviceConfig.NAMESPACE_VOICE_INTERACTION,
+ KEY_RESTART_PERIOD_IN_SECONDS, 0);
+ final Intent intent = new Intent(HotwordDetectionService.SERVICE_INTERFACE);
+ intent.setComponent(mDetectionComponentName);
+ initAudioFlingerLocked();
+
+ mServiceConnectionFactory = new ServiceConnectionFactory(intent, bindInstantServiceAllowed);
+
+ mRemoteHotwordDetectionService = mServiceConnectionFactory.createLocked();
+ if (ENABLE_PROXIMITY_RESULT) {
+ mAttentionManagerInternal = LocalServices.getService(AttentionManagerInternal.class);
+ if (mAttentionManagerInternal != null) {
+ mAttentionManagerInternal.onStartProximityUpdates(mProximityCallbackInternal);
+ }
+ }
+
+ mLastRestartInstant = Instant.now();
+ updateStateAfterProcessStart(options, sharedMemory);
+
+ if (mReStartPeriodSeconds <= 0) {
+ mCancellationTaskFuture = null;
+ } else {
+ // TODO: we need to be smarter here, e.g. schedule it a bit more often,
+ // but wait until the current session is closed.
+ mCancellationTaskFuture = mScheduledExecutorService.scheduleAtFixedRate(() -> {
+ Slog.v(TAG, "Time to restart the process, TTL has passed");
+ synchronized (mLock) {
+ restartProcessLocked();
+ HotwordMetricsLogger.writeServiceRestartEvent(mDetectorType,
+ HOTWORD_DETECTION_SERVICE_RESTARTED__REASON__SCHEDULE);
+ }
+ }, mReStartPeriodSeconds, mReStartPeriodSeconds, TimeUnit.SECONDS);
+ }
+ }
+
+ private void initAudioFlingerLocked() {
+ if (DEBUG) {
+ Slog.d(TAG, "initAudioFlingerLocked");
+ }
+ mAudioFlinger = ServiceManager.waitForService("media.audio_flinger");
+ if (mAudioFlinger == null) {
+ throw new IllegalStateException("Service media.audio_flinger wasn't found.");
+ }
+ if (DEBUG) {
+ Slog.d(TAG, "Obtained audio_flinger binder.");
+ }
+ try {
+ mAudioFlinger.linkToDeath(mAudioServerDeathRecipient, /* flags= */ 0);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Audio server died before we registered a DeathRecipient; retrying init.",
+ e);
+ initAudioFlingerLocked();
+ }
+ }
+
+ private void audioServerDied() {
+ Slog.w(TAG, "Audio server died; restarting the HotwordDetectionService.");
+ synchronized (mLock) {
+ // TODO: Check if this needs to be scheduled on a different thread.
+ initAudioFlingerLocked();
+ // We restart the process instead of simply sending over the new binder, to avoid race
+ // conditions with audio reading in the service.
+ restartProcessLocked();
+ HotwordMetricsLogger.writeServiceRestartEvent(mDetectorType,
+ HOTWORD_DETECTION_SERVICE_RESTARTED__REASON__AUDIO_SERVICE_DIED);
+ }
+ }
+
+ private void updateStateAfterProcessStart(
+ PersistableBundle options, SharedMemory sharedMemory) {
+ if (DEBUG) {
+ Slog.d(TAG, "updateStateAfterProcessStart");
+ }
+ mRemoteHotwordDetectionService.postAsync(service -> {
+ AndroidFuture<Void> future = new AndroidFuture<>();
+ IRemoteCallback statusCallback = new IRemoteCallback.Stub() {
+ @Override
+ public void sendResult(Bundle bundle) throws RemoteException {
+ if (DEBUG) {
+ Slog.d(TAG, "updateState finish");
+ }
+ future.complete(null);
+ if (mUpdateStateAfterStartFinished.getAndSet(true)) {
+ Slog.w(TAG, "call callback after timeout");
+ HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
+ HOTWORD_DETECTOR_EVENTS__EVENT__CALLBACK_UPDATE_STATE_AFTER_TIMEOUT,
+ mVoiceInteractionServiceUid);
+ return;
+ }
+ Pair<Integer, Integer> statusResultPair = getInitStatusAndMetricsResult(bundle);
+ int status = statusResultPair.first;
+ int initResultMetricsResult = statusResultPair.second;
+ try {
+ mCallback.onStatusReported(status);
+ HotwordMetricsLogger.writeServiceInitResultEvent(mDetectorType,
+ initResultMetricsResult);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Failed to report initialization status: " + e);
+ HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
+ METRICS_CALLBACK_ON_STATUS_REPORTED_EXCEPTION,
+ mVoiceInteractionServiceUid);
+ }
+ }
+ };
+ try {
+ service.updateState(options, sharedMemory, statusCallback);
+ HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
+ HOTWORD_DETECTOR_EVENTS__EVENT__REQUEST_UPDATE_STATE,
+ mVoiceInteractionServiceUid);
+ } catch (RemoteException e) {
+ // TODO: (b/181842909) Report an error to voice interactor
+ Slog.w(TAG, "Failed to updateState for HotwordDetectionService", e);
+ HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
+ HOTWORD_DETECTOR_EVENTS__EVENT__CALL_UPDATE_STATE_EXCEPTION,
+ mVoiceInteractionServiceUid);
+ }
+ return future.orTimeout(MAX_UPDATE_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
+ }).whenComplete((res, err) -> {
+ if (err instanceof TimeoutException) {
+ Slog.w(TAG, "updateState timed out");
+ if (mUpdateStateAfterStartFinished.getAndSet(true)) {
+ return;
+ }
+ try {
+ mCallback.onStatusReported(INITIALIZATION_STATUS_UNKNOWN);
+ HotwordMetricsLogger.writeServiceInitResultEvent(mDetectorType,
+ METRICS_INIT_UNKNOWN_TIMEOUT);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Failed to report initialization status UNKNOWN", e);
+ HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
+ METRICS_CALLBACK_ON_STATUS_REPORTED_EXCEPTION,
+ mVoiceInteractionServiceUid);
+ }
+ } else if (err != null) {
+ Slog.w(TAG, "Failed to update state: " + err);
+ } else {
+ // NOTE: so far we don't need to take any action.
+ }
+ });
+ }
+
+ private static Pair<Integer, Integer> getInitStatusAndMetricsResult(Bundle bundle) {
+ if (bundle == null) {
+ return new Pair<>(INITIALIZATION_STATUS_UNKNOWN, METRICS_INIT_UNKNOWN_NO_VALUE);
+ }
+ int status = bundle.getInt(KEY_INITIALIZATION_STATUS, INITIALIZATION_STATUS_UNKNOWN);
+ if (status > HotwordDetectionService.getMaxCustomInitializationStatus()) {
+ return new Pair<>(INITIALIZATION_STATUS_UNKNOWN,
+ status == INITIALIZATION_STATUS_UNKNOWN
+ ? METRICS_INIT_UNKNOWN_NO_VALUE
+ : METRICS_INIT_UNKNOWN_OVER_MAX_CUSTOM_VALUE);
+ }
+ // TODO: should guard against negative here
+ int metricsResult = status == INITIALIZATION_STATUS_SUCCESS
+ ? METRICS_INIT_CALLBACK_STATE_SUCCESS
+ : METRICS_INIT_CALLBACK_STATE_ERROR;
+ return new Pair<>(status, metricsResult);
+ }
+
+ private boolean isBound() {
+ synchronized (mLock) {
+ return mRemoteHotwordDetectionService.isBound();
+ }
+ }
+
+ void cancelLocked() {
+ Slog.v(TAG, "cancelLocked");
+ clearDebugHotwordLoggingTimeoutLocked();
+ mDebugHotwordLogging = false;
+ mRemoteHotwordDetectionService.unbind();
+ LocalServices.getService(PermissionManagerServiceInternal.class)
+ .setHotwordDetectionServiceProvider(null);
+ if (mIdentity != null) {
+ removeServiceUidForAudioPolicy(mIdentity.getIsolatedUid());
+ }
+ mIdentity = null;
+ if (mCancellationTaskFuture != null) {
+ mCancellationTaskFuture.cancel(/* may interrupt */ true);
+ }
+ if (mAudioFlinger != null) {
+ mAudioFlinger.unlinkToDeath(mAudioServerDeathRecipient, /* flags= */ 0);
+ }
+ if (mAttentionManagerInternal != null) {
+ mAttentionManagerInternal.onStopProximityUpdates(mProximityCallbackInternal);
+ }
+ }
+
+ void updateStateLocked(PersistableBundle options, SharedMemory sharedMemory) {
+ HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
+ HOTWORD_DETECTOR_EVENTS__EVENT__APP_REQUEST_UPDATE_STATE,
+ mVoiceInteractionServiceUid);
+
+ // Prevent doing the init late, so restart is handled equally to a clean process start.
+ // TODO(b/191742511): this logic needs a test
+ if (!mUpdateStateAfterStartFinished.get()
+ && Instant.now().minus(MAX_UPDATE_TIMEOUT_DURATION).isBefore(mLastRestartInstant)) {
+ Slog.v(TAG, "call updateStateAfterProcessStart");
+ updateStateAfterProcessStart(options, sharedMemory);
+ } else {
+ mRemoteHotwordDetectionService.run(
+ service -> service.updateState(options, sharedMemory, null /* callback */));
+ }
+ }
+
+ void startListeningFromMic(
+ AudioFormat audioFormat,
+ IMicrophoneHotwordDetectionVoiceInteractionCallback callback) {
+ if (DEBUG) {
+ Slog.d(TAG, "startListeningFromMic");
+ }
+ mSoftwareCallback = callback;
+
+ synchronized (mLock) {
+ if (mPerformingSoftwareHotwordDetection) {
+ Slog.i(TAG, "Hotword validation is already in progress, ignoring.");
+ return;
+ }
+ mPerformingSoftwareHotwordDetection = true;
+
+ startListeningFromMicLocked();
+ }
+ }
+
+ private void startListeningFromMicLocked() {
+ // TODO: consider making this a non-anonymous class.
+ IDspHotwordDetectionCallback internalCallback = new IDspHotwordDetectionCallback.Stub() {
+ @Override
+ public void onDetected(HotwordDetectedResult result) throws RemoteException {
+ if (DEBUG) {
+ Slog.d(TAG, "onDetected");
+ }
+ synchronized (mLock) {
+ HotwordMetricsLogger.writeKeyphraseTriggerEvent(
+ mDetectorType,
+ HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__DETECTED);
+ if (!mPerformingSoftwareHotwordDetection) {
+ Slog.i(TAG, "Hotword detection has already completed");
+ HotwordMetricsLogger.writeKeyphraseTriggerEvent(
+ mDetectorType,
+ METRICS_KEYPHRASE_TRIGGERED_DETECT_UNEXPECTED_CALLBACK);
+ return;
+ }
+ mPerformingSoftwareHotwordDetection = false;
+ try {
+ enforcePermissionsForDataDelivery();
+ } catch (SecurityException e) {
+ HotwordMetricsLogger.writeKeyphraseTriggerEvent(
+ mDetectorType,
+ METRICS_KEYPHRASE_TRIGGERED_DETECT_SECURITY_EXCEPTION);
+ mSoftwareCallback.onError();
+ return;
+ }
+ saveProximityValueToBundle(result);
+ HotwordDetectedResult newResult;
+ try {
+ newResult = mHotwordAudioStreamManager.startCopyingAudioStreams(result);
+ } catch (IOException e) {
+ // TODO: Write event
+ mSoftwareCallback.onError();
+ return;
+ }
+ mSoftwareCallback.onDetected(newResult, null, null);
+ Slog.i(TAG, "Egressed " + HotwordDetectedResult.getUsageSize(newResult)
+ + " bits from hotword trusted process");
+ if (mDebugHotwordLogging) {
+ Slog.i(TAG, "Egressed detected result: " + newResult);
+ }
+ }
+ }
+
+ @Override
+ public void onRejected(HotwordRejectedResult result) throws RemoteException {
+ if (DEBUG) {
+ Slog.wtf(TAG, "onRejected");
+ }
+ HotwordMetricsLogger.writeKeyphraseTriggerEvent(
+ mDetectorType,
+ HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__REJECTED);
+ // onRejected isn't allowed here, and we are not expecting it.
+ }
+ };
+
+ mRemoteHotwordDetectionService.run(
+ service -> service.detectFromMicrophoneSource(
+ null,
+ AUDIO_SOURCE_MICROPHONE,
+ null,
+ null,
+ internalCallback));
+ HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
+ HOTWORD_DETECTOR_EVENTS__EVENT__START_SOFTWARE_DETECTION,
+ mVoiceInteractionServiceUid);
+ }
+
+ public void startListeningFromExternalSource(
+ ParcelFileDescriptor audioStream,
+ AudioFormat audioFormat,
+ @Nullable PersistableBundle options,
+ IMicrophoneHotwordDetectionVoiceInteractionCallback callback) {
+ if (DEBUG) {
+ Slog.d(TAG, "startListeningFromExternalSource");
+ }
+
+ handleExternalSourceHotwordDetection(
+ audioStream,
+ audioFormat,
+ options,
+ callback);
+ }
+
+ void stopListening() {
+ if (DEBUG) {
+ Slog.d(TAG, "stopListening");
+ }
+ synchronized (mLock) {
+ stopListeningLocked();
+ }
+ }
+
+ private void stopListeningLocked() {
+ if (!mPerformingSoftwareHotwordDetection) {
+ Slog.i(TAG, "Hotword detection is not running");
+ return;
+ }
+ mPerformingSoftwareHotwordDetection = false;
+
+ mRemoteHotwordDetectionService.run(IHotwordDetectionService::stopDetection);
+
+ if (mCurrentAudioSink != null) {
+ Slog.i(TAG, "Closing audio stream to hotword detector: stopping requested");
+ bestEffortClose(mCurrentAudioSink);
+ }
+ mCurrentAudioSink = null;
+ }
+
+ void triggerHardwareRecognitionEventForTestLocked(
+ SoundTrigger.KeyphraseRecognitionEvent event,
+ IHotwordRecognitionStatusCallback callback) {
+ if (DEBUG) {
+ Slog.d(TAG, "triggerHardwareRecognitionEventForTestLocked");
+ }
+ detectFromDspSource(event, callback);
+ }
+
+ private void detectFromDspSource(SoundTrigger.KeyphraseRecognitionEvent recognitionEvent,
+ IHotwordRecognitionStatusCallback externalCallback) {
+ if (DEBUG) {
+ Slog.d(TAG, "detectFromDspSource");
+ }
+
+ AtomicBoolean timeoutDetected = new AtomicBoolean(false);
+ // TODO: consider making this a non-anonymous class.
+ IDspHotwordDetectionCallback internalCallback = new IDspHotwordDetectionCallback.Stub() {
+ @Override
+ public void onDetected(HotwordDetectedResult result) throws RemoteException {
+ if (DEBUG) {
+ Slog.d(TAG, "onDetected");
+ }
+ synchronized (mLock) {
+ if (mCancellationKeyPhraseDetectionFuture != null) {
+ mCancellationKeyPhraseDetectionFuture.cancel(true);
+ }
+ if (timeoutDetected.get()) {
+ return;
+ }
+ HotwordMetricsLogger.writeKeyphraseTriggerEvent(
+ mDetectorType,
+ HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__DETECTED);
+ if (!mValidatingDspTrigger) {
+ Slog.i(TAG, "Ignoring #onDetected due to a process restart");
+ HotwordMetricsLogger.writeKeyphraseTriggerEvent(
+ mDetectorType,
+ METRICS_KEYPHRASE_TRIGGERED_DETECT_UNEXPECTED_CALLBACK);
+ return;
+ }
+ mValidatingDspTrigger = false;
+ try {
+ enforcePermissionsForDataDelivery();
+ enforceExtraKeyphraseIdNotLeaked(result, recognitionEvent);
+ } catch (SecurityException e) {
+ Slog.i(TAG, "Ignoring #onDetected due to a SecurityException", e);
+ HotwordMetricsLogger.writeKeyphraseTriggerEvent(
+ mDetectorType,
+ METRICS_KEYPHRASE_TRIGGERED_DETECT_SECURITY_EXCEPTION);
+ externalCallback.onError(CALLBACK_ONDETECTED_GOT_SECURITY_EXCEPTION);
+ return;
+ }
+ saveProximityValueToBundle(result);
+ HotwordDetectedResult newResult;
+ try {
+ newResult = mHotwordAudioStreamManager.startCopyingAudioStreams(result);
+ } catch (IOException e) {
+ // TODO: Write event
+ externalCallback.onError(CALLBACK_ONDETECTED_STREAM_COPY_ERROR);
+ return;
+ }
+ externalCallback.onKeyphraseDetected(recognitionEvent, newResult);
+ Slog.i(TAG, "Egressed " + HotwordDetectedResult.getUsageSize(newResult)
+ + " bits from hotword trusted process");
+ if (mDebugHotwordLogging) {
+ Slog.i(TAG, "Egressed detected result: " + newResult);
+ }
+ }
+ }
+
+ @Override
+ public void onRejected(HotwordRejectedResult result) throws RemoteException {
+ if (DEBUG) {
+ Slog.d(TAG, "onRejected");
+ }
+ synchronized (mLock) {
+ if (mCancellationKeyPhraseDetectionFuture != null) {
+ mCancellationKeyPhraseDetectionFuture.cancel(true);
+ }
+ if (timeoutDetected.get()) {
+ return;
+ }
+ HotwordMetricsLogger.writeKeyphraseTriggerEvent(
+ mDetectorType,
+ HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__REJECTED);
+ if (!mValidatingDspTrigger) {
+ Slog.i(TAG, "Ignoring #onRejected due to a process restart");
+ HotwordMetricsLogger.writeKeyphraseTriggerEvent(
+ mDetectorType,
+ METRICS_KEYPHRASE_TRIGGERED_REJECT_UNEXPECTED_CALLBACK);
+ return;
+ }
+ mValidatingDspTrigger = false;
+ externalCallback.onRejected(result);
+ if (mDebugHotwordLogging && result != null) {
+ Slog.i(TAG, "Egressed rejected result: " + result);
+ }
+ }
+ }
+ };
+
+ synchronized (mLock) {
+ mValidatingDspTrigger = true;
+ mRemoteHotwordDetectionService.run(service -> {
+ // We use the VALIDATION_TIMEOUT_MILLIS to inform that the client needs to invoke
+ // the callback before timeout value. In order to reduce the latency impact between
+ // server side and client side, we need to use another timeout value
+ // MAX_VALIDATION_TIMEOUT_MILLIS to monitor it.
+ mCancellationKeyPhraseDetectionFuture = mScheduledExecutorService.schedule(
+ () -> {
+ // TODO: avoid allocate every time
+ timeoutDetected.set(true);
+ Slog.w(TAG, "Timed out on #detectFromDspSource");
+ HotwordMetricsLogger.writeKeyphraseTriggerEvent(
+ mDetectorType,
+ HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__DETECT_TIMEOUT);
+ try {
+ externalCallback.onError(CALLBACK_DETECT_TIMEOUT);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Failed to report onError status: ", e);
+ HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
+ HOTWORD_DETECTOR_EVENTS__EVENT__CALLBACK_ON_ERROR_EXCEPTION,
+ mVoiceInteractionServiceUid);
+ }
+ },
+ MAX_VALIDATION_TIMEOUT_MILLIS,
+ TimeUnit.MILLISECONDS);
+ service.detectFromDspSource(
+ recognitionEvent,
+ recognitionEvent.getCaptureFormat(),
+ VALIDATION_TIMEOUT_MILLIS,
+ internalCallback);
+ });
+ }
+ }
+
+ void forceRestart() {
+ Slog.v(TAG, "Requested to restart the service internally. Performing the restart");
+ synchronized (mLock) {
+ restartProcessLocked();
+ }
+ }
+
+ void setDebugHotwordLoggingLocked(boolean logging) {
+ Slog.v(TAG, "setDebugHotwordLoggingLocked: " + logging);
+ clearDebugHotwordLoggingTimeoutLocked();
+ mDebugHotwordLogging = logging;
+
+ if (logging) {
+ // Reset mDebugHotwordLogging to false after one hour
+ mDebugHotwordLoggingTimeoutFuture = mScheduledExecutorService.schedule(() -> {
+ Slog.v(TAG, "Timeout to reset mDebugHotwordLogging to false");
+ synchronized (mLock) {
+ mDebugHotwordLogging = false;
+ }
+ }, RESET_DEBUG_HOTWORD_LOGGING_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
+ }
+ }
+
+ private void clearDebugHotwordLoggingTimeoutLocked() {
+ if (mDebugHotwordLoggingTimeoutFuture != null) {
+ mDebugHotwordLoggingTimeoutFuture.cancel(/* mayInterruptIfRunning= */true);
+ mDebugHotwordLoggingTimeoutFuture = null;
+ }
+ }
+
+ private void restartProcessLocked() {
+ // TODO(b/244598068): Check HotwordAudioStreamManager first
+ Slog.v(TAG, "Restarting hotword detection process");
+ ServiceConnection oldConnection = mRemoteHotwordDetectionService;
+ HotwordDetectionServiceIdentity previousIdentity = mIdentity;
+
+ // TODO(volnov): this can be done after connect() has been successful.
+ if (mValidatingDspTrigger) {
+ // We're restarting the process while it's processing a DSP trigger, so report a
+ // rejection. This also allows the Interactor to startReco again
+ try {
+ mCallback.onRejected(new HotwordRejectedResult.Builder().build());
+ HotwordMetricsLogger.writeKeyphraseTriggerEvent(
+ mDetectorType,
+ HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__REJECTED_FROM_RESTART);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Failed to call #rejected");
+ HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
+ HOTWORD_DETECTOR_EVENTS__EVENT__CALLBACK_ON_REJECTED_EXCEPTION,
+ mVoiceInteractionServiceUid);
+ }
+ mValidatingDspTrigger = false;
+ }
+
+ mUpdateStateAfterStartFinished.set(false);
+ mLastRestartInstant = Instant.now();
+
+ // Recreate connection to reset the cache.
+ mRemoteHotwordDetectionService = mServiceConnectionFactory.createLocked();
+
+ Slog.v(TAG, "Started the new process, issuing #onProcessRestarted");
+ try {
+ mCallback.onProcessRestarted();
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Failed to communicate #onProcessRestarted", e);
+ HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
+ HOTWORD_DETECTOR_EVENTS__EVENT__CALLBACK_ON_PROCESS_RESTARTED_EXCEPTION,
+ mVoiceInteractionServiceUid);
+ }
+
+ // Restart listening from microphone if the hotword process has been restarted.
+ if (mPerformingSoftwareHotwordDetection) {
+ Slog.i(TAG, "Process restarted: calling startRecognition() again");
+ startListeningFromMicLocked();
+ }
+
+ if (mCurrentAudioSink != null) {
+ Slog.i(TAG, "Closing external audio stream to hotword detector: process restarted");
+ bestEffortClose(mCurrentAudioSink);
+ mCurrentAudioSink = null;
+ }
+
+ if (DEBUG) {
+ Slog.i(TAG, "#onProcessRestarted called, unbinding from the old process");
+ }
+ oldConnection.ignoreConnectionStatusEvents();
+ oldConnection.unbind();
+ if (previousIdentity != null) {
+ removeServiceUidForAudioPolicy(previousIdentity.getIsolatedUid());
+ }
+ }
+
+ static final class SoundTriggerCallback extends IRecognitionStatusCallback.Stub {
+ private SoundTrigger.KeyphraseRecognitionEvent mRecognitionEvent;
+ private final HotwordDetectionConnection mHotwordDetectionConnection;
+ private final IHotwordRecognitionStatusCallback mExternalCallback;
+
+ SoundTriggerCallback(IHotwordRecognitionStatusCallback callback,
+ HotwordDetectionConnection connection) {
+ mHotwordDetectionConnection = connection;
+ mExternalCallback = callback;
+ }
+
+ @Override
+ public void onKeyphraseDetected(SoundTrigger.KeyphraseRecognitionEvent recognitionEvent)
+ throws RemoteException {
+ if (DEBUG) {
+ Slog.d(TAG, "onKeyphraseDetected recognitionEvent : " + recognitionEvent);
+ }
+ final boolean useHotwordDetectionService = mHotwordDetectionConnection != null;
+ if (useHotwordDetectionService) {
+ HotwordMetricsLogger.writeKeyphraseTriggerEvent(
+ HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__DETECTOR_TYPE__TRUSTED_DETECTOR_DSP,
+ HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__KEYPHRASE_TRIGGER);
+ mRecognitionEvent = recognitionEvent;
+ mHotwordDetectionConnection.detectFromDspSource(
+ recognitionEvent, mExternalCallback);
+ } else {
+ HotwordMetricsLogger.writeKeyphraseTriggerEvent(
+ HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__DETECTOR_TYPE__NORMAL_DETECTOR,
+ HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__KEYPHRASE_TRIGGER);
+ mExternalCallback.onKeyphraseDetected(recognitionEvent, null);
+ }
+ }
+
+ @Override
+ public void onGenericSoundTriggerDetected(
+ SoundTrigger.GenericRecognitionEvent recognitionEvent)
+ throws RemoteException {
+ mExternalCallback.onGenericSoundTriggerDetected(recognitionEvent);
+ }
+
+ @Override
+ public void onError(int status) throws RemoteException {
+ mExternalCallback.onError(status);
+ }
+
+ @Override
+ public void onRecognitionPaused() throws RemoteException {
+ mExternalCallback.onRecognitionPaused();
+ }
+
+ @Override
+ public void onRecognitionResumed() throws RemoteException {
+ mExternalCallback.onRecognitionResumed();
+ }
+ }
+
+ public void dump(String prefix, PrintWriter pw) {
+ pw.print(prefix); pw.print("mReStartPeriodSeconds="); pw.println(mReStartPeriodSeconds);
+ pw.print(prefix);
+ pw.print("mBound=" + mRemoteHotwordDetectionService.isBound());
+ pw.print(", mValidatingDspTrigger=" + mValidatingDspTrigger);
+ pw.print(", mPerformingSoftwareHotwordDetection=" + mPerformingSoftwareHotwordDetection);
+ pw.print(", mRestartCount=" + mServiceConnectionFactory.mRestartCount);
+ pw.print(", mLastRestartInstant=" + mLastRestartInstant);
+ pw.println(", mDetectorType=" + HotwordDetector.detectorTypeToString(mDetectorType));
+ }
+
+ private void handleExternalSourceHotwordDetection(
+ ParcelFileDescriptor audioStream,
+ AudioFormat audioFormat,
+ @Nullable PersistableBundle options,
+ IMicrophoneHotwordDetectionVoiceInteractionCallback callback) {
+ if (DEBUG) {
+ Slog.d(TAG, "#handleExternalSourceHotwordDetection");
+ }
+ InputStream audioSource = new ParcelFileDescriptor.AutoCloseInputStream(audioStream);
+
+ Pair<ParcelFileDescriptor, ParcelFileDescriptor> clientPipe = createPipe();
+ if (clientPipe == null) {
+ // TODO: Need to propagate as unknown error or something?
+ return;
+ }
+ ParcelFileDescriptor serviceAudioSink = clientPipe.second;
+ ParcelFileDescriptor serviceAudioSource = clientPipe.first;
+
+ synchronized (mLock) {
+ mCurrentAudioSink = serviceAudioSink;
+ }
+
+ mAudioCopyExecutor.execute(() -> {
+ try (InputStream source = audioSource;
+ OutputStream fos =
+ new ParcelFileDescriptor.AutoCloseOutputStream(serviceAudioSink)) {
+
+ byte[] buffer = new byte[1024];
+ while (true) {
+ int bytesRead = source.read(buffer, 0, 1024);
+
+ if (bytesRead < 0) {
+ Slog.i(TAG, "Reached end of stream for external hotword");
+ break;
+ }
+
+ // TODO: First write to ring buffer to make sure we don't lose data if the next
+ // statement fails.
+ // ringBuffer.append(buffer, bytesRead);
+ fos.write(buffer, 0, bytesRead);
+ }
+ } catch (IOException e) {
+ Slog.w(TAG, "Failed supplying audio data to validator", e);
+
+ try {
+ callback.onError();
+ } catch (RemoteException ex) {
+ Slog.w(TAG, "Failed to report onError status: " + ex);
+ HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
+ HOTWORD_DETECTOR_EVENTS__EVENT__CALLBACK_ON_ERROR_EXCEPTION,
+ mVoiceInteractionServiceUid);
+ }
+ } finally {
+ synchronized (mLock) {
+ mCurrentAudioSink = null;
+ }
+ }
+ });
+
+ // TODO: handle cancellations well
+ // TODO: what if we cancelled and started a new one?
+ mRemoteHotwordDetectionService.run(
+ service -> {
+ service.detectFromMicrophoneSource(
+ serviceAudioSource,
+ // TODO: consider making a proxy callback + copy of audio format
+ AUDIO_SOURCE_EXTERNAL,
+ audioFormat,
+ options,
+ new IDspHotwordDetectionCallback.Stub() {
+ @Override
+ public void onRejected(HotwordRejectedResult result)
+ throws RemoteException {
+ HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
+ METRICS_EXTERNAL_SOURCE_REJECTED,
+ mVoiceInteractionServiceUid);
+ mScheduledExecutorService.schedule(
+ () -> {
+ bestEffortClose(serviceAudioSink, audioSource);
+ },
+ EXTERNAL_HOTWORD_CLEANUP_MILLIS,
+ TimeUnit.MILLISECONDS);
+
+ callback.onRejected(result);
+
+ if (result != null) {
+ Slog.i(TAG, "Egressed 'hotword rejected result' "
+ + "from hotword trusted process");
+ if (mDebugHotwordLogging) {
+ Slog.i(TAG, "Egressed detected result: " + result);
+ }
+ }
+ }
+
+ @Override
+ public void onDetected(HotwordDetectedResult triggerResult)
+ throws RemoteException {
+ HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
+ METRICS_EXTERNAL_SOURCE_DETECTED,
+ mVoiceInteractionServiceUid);
+ mScheduledExecutorService.schedule(
+ () -> {
+ bestEffortClose(serviceAudioSink, audioSource);
+ },
+ EXTERNAL_HOTWORD_CLEANUP_MILLIS,
+ TimeUnit.MILLISECONDS);
+
+ try {
+ enforcePermissionsForDataDelivery();
+ } catch (SecurityException e) {
+ HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
+ METRICS_EXTERNAL_SOURCE_DETECT_SECURITY_EXCEPTION,
+ mVoiceInteractionServiceUid);
+ callback.onError();
+ return;
+ }
+ HotwordDetectedResult newResult;
+ try {
+ newResult =
+ mHotwordAudioStreamManager.startCopyingAudioStreams(
+ triggerResult);
+ } catch (IOException e) {
+ // TODO: Write event
+ callback.onError();
+ return;
+ }
+ callback.onDetected(newResult, null /* audioFormat */,
+ null /* audioStream */);
+ Slog.i(TAG, "Egressed "
+ + HotwordDetectedResult.getUsageSize(newResult)
+ + " bits from hotword trusted process");
+ if (mDebugHotwordLogging) {
+ Slog.i(TAG,
+ "Egressed detected result: " + newResult);
+ }
+ }
+ });
+
+ // A copy of this has been created and passed to the hotword validator
+ bestEffortClose(serviceAudioSource);
+ });
+ HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
+ HOTWORD_DETECTOR_EVENTS__EVENT__START_EXTERNAL_SOURCE_DETECTION,
+ mVoiceInteractionServiceUid);
+ }
+
+ private class ServiceConnectionFactory {
+ private final Intent mIntent;
+ private final int mBindingFlags;
+
+ private int mRestartCount = 0;
+
+ ServiceConnectionFactory(@NonNull Intent intent, boolean bindInstantServiceAllowed) {
+ mIntent = intent;
+ mBindingFlags = bindInstantServiceAllowed ? Context.BIND_ALLOW_INSTANT : 0;
+ }
+
+ ServiceConnection createLocked() {
+ ServiceConnection connection =
+ new ServiceConnection(mContext, mIntent, mBindingFlags, mUser,
+ IHotwordDetectionService.Stub::asInterface,
+ mRestartCount++ % MAX_ISOLATED_PROCESS_NUMBER);
+ connection.connect();
+
+ updateAudioFlinger(connection, mAudioFlinger);
+ updateContentCaptureManager(connection);
+ updateSpeechService(connection);
+ updateServiceIdentity(connection);
+ return connection;
+ }
+ }
+
+ private class ServiceConnection extends ServiceConnector.Impl<IHotwordDetectionService> {
+ private final Object mLock = new Object();
+
+ private final Intent mIntent;
+ private final int mBindingFlags;
+ private final int mInstanceNumber;
+
+ private boolean mRespectServiceConnectionStatusChanged = true;
+ private boolean mIsBound = false;
+ private boolean mIsLoggedFirstConnect = false;
+
+ ServiceConnection(@NonNull Context context,
+ @NonNull Intent intent, int bindingFlags, int userId,
+ @Nullable Function<IBinder, IHotwordDetectionService> binderAsInterface,
+ int instanceNumber) {
+ super(context, intent, bindingFlags, userId, binderAsInterface);
+ this.mIntent = intent;
+ this.mBindingFlags = bindingFlags;
+ this.mInstanceNumber = instanceNumber;
+ }
+
+ @Override // from ServiceConnector.Impl
+ protected void onServiceConnectionStatusChanged(IHotwordDetectionService service,
+ boolean connected) {
+ if (DEBUG) {
+ Slog.d(TAG, "onServiceConnectionStatusChanged connected = " + connected);
+ }
+ synchronized (mLock) {
+ if (!mRespectServiceConnectionStatusChanged) {
+ Slog.v(TAG, "Ignored onServiceConnectionStatusChanged event");
+ return;
+ }
+ mIsBound = connected;
+
+ if (!connected) {
+ HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
+ HOTWORD_DETECTOR_EVENTS__EVENT__ON_DISCONNECTED,
+ mVoiceInteractionServiceUid);
+ } else if (!mIsLoggedFirstConnect) {
+ mIsLoggedFirstConnect = true;
+ HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
+ HOTWORD_DETECTOR_EVENTS__EVENT__ON_CONNECTED,
+ mVoiceInteractionServiceUid);
+ }
+ }
+ }
+
+ @Override
+ protected long getAutoDisconnectTimeoutMs() {
+ return -1;
+ }
+
+ @Override
+ public void binderDied() {
+ super.binderDied();
+ synchronized (mLock) {
+ if (!mRespectServiceConnectionStatusChanged) {
+ Slog.v(TAG, "Ignored #binderDied event");
+ return;
+ }
+
+ Slog.w(TAG, "binderDied");
+ try {
+ mCallback.onError(HOTWORD_DETECTION_SERVICE_DIED);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Failed to report onError status: " + e);
+ HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
+ HOTWORD_DETECTOR_EVENTS__EVENT__CALLBACK_ON_ERROR_EXCEPTION,
+ mVoiceInteractionServiceUid);
+ }
+ }
+ }
+
+ @Override
+ protected boolean bindService(
+ @NonNull android.content.ServiceConnection serviceConnection) {
+ try {
+ HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
+ HOTWORD_DETECTOR_EVENTS__EVENT__REQUEST_BIND_SERVICE,
+ mVoiceInteractionServiceUid);
+ boolean bindResult = mContext.bindIsolatedService(
+ mIntent,
+ Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE | mBindingFlags,
+ "hotword_detector_" + mInstanceNumber,
+ mExecutor,
+ serviceConnection);
+ if (!bindResult) {
+ HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
+ HOTWORD_DETECTOR_EVENTS__EVENT__REQUEST_BIND_SERVICE_FAIL,
+ mVoiceInteractionServiceUid);
+ }
+ return bindResult;
+ } catch (IllegalArgumentException e) {
+ HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
+ HOTWORD_DETECTOR_EVENTS__EVENT__REQUEST_BIND_SERVICE_FAIL,
+ mVoiceInteractionServiceUid);
+ Slog.wtf(TAG, "Can't bind to the hotword detection service!", e);
+ return false;
+ }
+ }
+
+ boolean isBound() {
+ synchronized (mLock) {
+ return mIsBound;
+ }
+ }
+
+ void ignoreConnectionStatusEvents() {
+ synchronized (mLock) {
+ mRespectServiceConnectionStatusChanged = false;
+ }
+ }
+ }
+
+ private static Pair<ParcelFileDescriptor, ParcelFileDescriptor> createPipe() {
+ ParcelFileDescriptor[] fileDescriptors;
+ try {
+ fileDescriptors = ParcelFileDescriptor.createPipe();
+ } catch (IOException e) {
+ Slog.e(TAG, "Failed to create audio stream pipe", e);
+ return null;
+ }
+
+ return Pair.create(fileDescriptors[0], fileDescriptors[1]);
+ }
+
+ private static void updateAudioFlinger(ServiceConnection connection, IBinder audioFlinger) {
+ // TODO: Consider using a proxy that limits the exposed API surface.
+ connection.run(service -> service.updateAudioFlinger(audioFlinger));
+ }
+
+ private static void updateContentCaptureManager(ServiceConnection connection) {
+ IBinder b = ServiceManager
+ .getService(Context.CONTENT_CAPTURE_MANAGER_SERVICE);
+ IContentCaptureManager binderService = IContentCaptureManager.Stub.asInterface(b);
+ connection.run(
+ service -> service.updateContentCaptureManager(binderService,
+ new ContentCaptureOptions(null)));
+ }
+
+ private static void updateSpeechService(ServiceConnection connection) {
+ IBinder b = ServiceManager.getService(Context.SPEECH_RECOGNITION_SERVICE);
+ IRecognitionServiceManager binderService = IRecognitionServiceManager.Stub.asInterface(b);
+ connection.run(service -> {
+ service.updateRecognitionServiceManager(binderService);
+ });
+ }
+
+ private void updateServiceIdentity(ServiceConnection connection) {
+ connection.run(service -> service.ping(new IRemoteCallback.Stub() {
+ @Override
+ public void sendResult(Bundle bundle) throws RemoteException {
+ // TODO: Exit if the service has been unbound already (though there's a very low
+ // chance this happens).
+ if (DEBUG) {
+ Slog.d(TAG, "updating hotword UID " + Binder.getCallingUid());
+ }
+ // TODO: Have the provider point to the current state stored in
+ // VoiceInteractionManagerServiceImpl.
+ final int uid = Binder.getCallingUid();
+ LocalServices.getService(PermissionManagerServiceInternal.class)
+ .setHotwordDetectionServiceProvider(() -> uid);
+ mIdentity = new HotwordDetectionServiceIdentity(uid, mVoiceInteractionServiceUid);
+ addServiceUidForAudioPolicy(uid);
+ }
+ }));
+ }
+
+ private void addServiceUidForAudioPolicy(int uid) {
+ mScheduledExecutorService.execute(() -> {
+ AudioManagerInternal audioManager =
+ LocalServices.getService(AudioManagerInternal.class);
+ if (audioManager != null) {
+ audioManager.addAssistantServiceUid(uid);
+ }
+ });
+ }
+
+ private void removeServiceUidForAudioPolicy(int uid) {
+ mScheduledExecutorService.execute(() -> {
+ AudioManagerInternal audioManager =
+ LocalServices.getService(AudioManagerInternal.class);
+ if (audioManager != null) {
+ audioManager.removeAssistantServiceUid(uid);
+ }
+ });
+ }
+
+ private void saveProximityValueToBundle(HotwordDetectedResult result) {
+ synchronized (mLock) {
+ if (result != null && mProximityMeters != PROXIMITY_UNKNOWN) {
+ result.setProximity(mProximityMeters);
+ }
+ }
+ }
+
+ private void setProximityValue(double proximityMeters) {
+ synchronized (mLock) {
+ mProximityMeters = proximityMeters;
+ }
+ }
+
+ private static void bestEffortClose(Closeable... closeables) {
+ for (Closeable closeable : closeables) {
+ bestEffortClose(closeable);
+ }
+ }
+
+ private static void bestEffortClose(Closeable closeable) {
+ try {
+ closeable.close();
+ } catch (IOException e) {
+ if (DEBUG) {
+ Slog.w(TAG, "Failed closing", e);
+ }
+ }
+ }
+
+ // TODO: Share this code with SoundTriggerMiddlewarePermission.
+ private void enforcePermissionsForDataDelivery() {
+ Binder.withCleanCallingIdentity(() -> {
+ enforcePermissionForPreflight(mContext, mVoiceInteractorIdentity, RECORD_AUDIO);
+ int hotwordOp = AppOpsManager.strOpToOp(AppOpsManager.OPSTR_RECORD_AUDIO_HOTWORD);
+ mAppOpsManager.noteOpNoThrow(hotwordOp,
+ mVoiceInteractorIdentity.uid, mVoiceInteractorIdentity.packageName,
+ mVoiceInteractorIdentity.attributionTag, OP_MESSAGE);
+ enforcePermissionForDataDelivery(mContext, mVoiceInteractorIdentity,
+ CAPTURE_AUDIO_HOTWORD, OP_MESSAGE);
+ });
+ }
+
+ /**
+ * Throws a {@link SecurityException} iff the given identity has given permission to receive
+ * data.
+ *
+ * @param context A {@link Context}, used for permission checks.
+ * @param identity The identity to check.
+ * @param permission The identifier of the permission we want to check.
+ * @param reason The reason why we're requesting the permission, for auditing purposes.
+ */
+ private static void enforcePermissionForDataDelivery(@NonNull Context context,
+ @NonNull Identity identity,
+ @NonNull String permission, @NonNull String reason) {
+ final int status = PermissionUtil.checkPermissionForDataDelivery(context, identity,
+ permission, reason);
+ if (status != PermissionChecker.PERMISSION_GRANTED) {
+ throw new SecurityException(
+ TextUtils.formatSimple("Failed to obtain permission %s for identity %s",
+ permission,
+ SoundTriggerSessionPermissionsDecorator.toString(identity)));
+ }
+ }
+
+ private static void enforceExtraKeyphraseIdNotLeaked(HotwordDetectedResult result,
+ SoundTrigger.KeyphraseRecognitionEvent recognitionEvent) {
+ // verify the phrase ID in HotwordDetectedResult is not exposing extra phrases
+ // the DSP did not detect
+ for (SoundTrigger.KeyphraseRecognitionExtra keyphrase : recognitionEvent.keyphraseExtras) {
+ if (keyphrase.getKeyphraseId() == result.getHotwordPhraseId()) {
+ return;
+ }
+ }
+ throw new SecurityException("Ignoring #onDetected due to trusted service "
+ + "sharing a keyphrase ID which the DSP did not detect");
+ }
+
+ private static final String OP_MESSAGE =
+ "Providing hotword detection result to VoiceInteractionService";
+}
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index 5cef2cb0a161..bbdc8907275e 100644
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -738,6 +738,7 @@ public final class Call {
private final String mContactDisplayName;
private final @CallDirection int mCallDirection;
private final @Connection.VerificationStatus int mCallerNumberVerificationStatus;
+ private final Uri mContactPhotoUri;
/**
* Whether the supplied capabilities supports the specified capability.
@@ -945,6 +946,17 @@ public final class Call {
}
/**
+ * @return The contact photo URI which corresponds to
+ * {@link android.provider.ContactsContract.PhoneLookup#PHOTO_URI}, or {@code null} if the
+ * lookup is not yet complete, if there's no contacts entry for the caller,
+ * or if the {@link InCallService} does not hold the
+ * {@link android.Manifest.permission#READ_CONTACTS} permission.
+ */
+ public @Nullable Uri getContactPhotoUri() {
+ return mContactPhotoUri;
+ }
+
+ /**
* The display name for the caller.
* <p>
* This is the name as reported by the {@link ConnectionService} associated with this call.
@@ -1143,7 +1155,8 @@ public final class Call {
Objects.equals(mContactDisplayName, d.mContactDisplayName) &&
Objects.equals(mCallDirection, d.mCallDirection) &&
Objects.equals(mCallerNumberVerificationStatus,
- d.mCallerNumberVerificationStatus);
+ d.mCallerNumberVerificationStatus) &&
+ Objects.equals(mContactPhotoUri, d.mContactPhotoUri);
}
return false;
}
@@ -1168,7 +1181,8 @@ public final class Call {
mCreationTimeMillis,
mContactDisplayName,
mCallDirection,
- mCallerNumberVerificationStatus);
+ mCallerNumberVerificationStatus,
+ mContactPhotoUri);
}
/** {@hide} */
@@ -1192,7 +1206,8 @@ public final class Call {
long creationTimeMillis,
String contactDisplayName,
int callDirection,
- int callerNumberVerificationStatus) {
+ int callerNumberVerificationStatus,
+ Uri contactPhotoUri) {
mState = state;
mTelecomCallId = telecomCallId;
mHandle = handle;
@@ -1213,6 +1228,7 @@ public final class Call {
mContactDisplayName = contactDisplayName;
mCallDirection = callDirection;
mCallerNumberVerificationStatus = callerNumberVerificationStatus;
+ mContactPhotoUri = contactPhotoUri;
}
/** {@hide} */
@@ -1237,7 +1253,9 @@ public final class Call {
parcelableCall.getCreationTimeMillis(),
parcelableCall.getContactDisplayName(),
parcelableCall.getCallDirection(),
- parcelableCall.getCallerNumberVerificationStatus());
+ parcelableCall.getCallerNumberVerificationStatus(),
+ parcelableCall.getContactPhotoUri()
+ );
}
@Override
@@ -2644,7 +2662,8 @@ public final class Call {
mDetails.getCreationTimeMillis(),
mDetails.getContactDisplayName(),
mDetails.getCallDirection(),
- mDetails.getCallerNumberVerificationStatus()
+ mDetails.getCallerNumberVerificationStatus(),
+ mDetails.getContactPhotoUri()
);
fireDetailsChanged(mDetails);
}
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index 7c736e38897d..568c8abc40a2 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -66,6 +66,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
+import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
@@ -2531,11 +2532,21 @@ public abstract class Connection extends Conferenceable {
*/
public final void setCallerDisplayName(String callerDisplayName, int presentation) {
checkImmutable();
- Log.d(this, "setCallerDisplayName %s", callerDisplayName);
- mCallerDisplayName = callerDisplayName;
- mCallerDisplayNamePresentation = presentation;
- for (Listener l : mListeners) {
- l.onCallerDisplayNameChanged(this, callerDisplayName, presentation);
+ boolean nameChanged = !Objects.equals(mCallerDisplayName, callerDisplayName);
+ boolean presentationChanged = mCallerDisplayNamePresentation != presentation;
+ if (nameChanged) {
+ // Ensure the new name is not clobbering the old one with a null value due to the caller
+ // wanting to only set the presentation and not knowing the display name.
+ mCallerDisplayName = callerDisplayName;
+ }
+ if (presentationChanged) {
+ mCallerDisplayNamePresentation = presentation;
+ }
+ if (nameChanged || presentationChanged) {
+ for (Listener l : mListeners) {
+ l.onCallerDisplayNameChanged(this, mCallerDisplayName,
+ mCallerDisplayNamePresentation);
+ }
}
}
diff --git a/telecomm/java/android/telecom/ParcelableCall.java b/telecomm/java/android/telecom/ParcelableCall.java
index f412a1825e2a..6a1318982e77 100644
--- a/telecomm/java/android/telecom/ParcelableCall.java
+++ b/telecomm/java/android/telecom/ParcelableCall.java
@@ -69,6 +69,7 @@ public final class ParcelableCall implements Parcelable {
private int mCallerNumberVerificationStatus;
private String mContactDisplayName;
private String mActiveChildCallId;
+ private Uri mContactPhotoUri;
public ParcelableCallBuilder setId(String id) {
mId = id;
@@ -224,6 +225,11 @@ public final class ParcelableCall implements Parcelable {
return this;
}
+ public ParcelableCallBuilder setContactPhotoUri(Uri contactPhotoUri) {
+ mContactPhotoUri = contactPhotoUri;
+ return this;
+ }
+
public ParcelableCall createParcelableCall() {
return new ParcelableCall(
mId,
@@ -255,7 +261,8 @@ public final class ParcelableCall implements Parcelable {
mCallDirection,
mCallerNumberVerificationStatus,
mContactDisplayName,
- mActiveChildCallId);
+ mActiveChildCallId,
+ mContactPhotoUri);
}
public static ParcelableCallBuilder fromParcelableCall(ParcelableCall parcelableCall) {
@@ -292,6 +299,7 @@ public final class ParcelableCall implements Parcelable {
parcelableCall.mCallerNumberVerificationStatus;
newBuilder.mContactDisplayName = parcelableCall.mContactDisplayName;
newBuilder.mActiveChildCallId = parcelableCall.mActiveChildCallId;
+ newBuilder.mContactPhotoUri = parcelableCall.mContactPhotoUri;
return newBuilder;
}
}
@@ -327,6 +335,7 @@ public final class ParcelableCall implements Parcelable {
private final int mCallerNumberVerificationStatus;
private final String mContactDisplayName;
private final String mActiveChildCallId; // Only valid for CDMA conferences
+ private final Uri mContactPhotoUri;
public ParcelableCall(
String id,
@@ -358,7 +367,8 @@ public final class ParcelableCall implements Parcelable {
int callDirection,
int callerNumberVerificationStatus,
String contactDisplayName,
- String activeChildCallId
+ String activeChildCallId,
+ Uri contactPhotoUri
) {
mId = id;
mState = state;
@@ -390,6 +400,7 @@ public final class ParcelableCall implements Parcelable {
mCallerNumberVerificationStatus = callerNumberVerificationStatus;
mContactDisplayName = contactDisplayName;
mActiveChildCallId = activeChildCallId;
+ mContactPhotoUri = contactPhotoUri;
}
/** The unique ID of the call. */
@@ -607,6 +618,14 @@ public final class ParcelableCall implements Parcelable {
}
/**
+ * @return the caller photo URI.
+ */
+ public @Nullable Uri getContactPhotoUri() {
+ return mContactPhotoUri;
+ }
+
+
+ /**
* @return On a CDMA conference with two participants, returns the ID of the child call that's
* currently active.
*/
@@ -655,6 +674,7 @@ public final class ParcelableCall implements Parcelable {
int callerNumberVerificationStatus = source.readInt();
String contactDisplayName = source.readString();
String activeChildCallId = source.readString();
+ Uri contactPhotoUri = source.readParcelable(classLoader, Uri.class);
return new ParcelableCallBuilder()
.setId(id)
.setState(state)
@@ -686,6 +706,7 @@ public final class ParcelableCall implements Parcelable {
.setCallerNumberVerificationStatus(callerNumberVerificationStatus)
.setContactDisplayName(contactDisplayName)
.setActiveChildCallId(activeChildCallId)
+ .setContactPhotoUri(contactPhotoUri)
.createParcelableCall();
}
@@ -735,6 +756,7 @@ public final class ParcelableCall implements Parcelable {
destination.writeInt(mCallerNumberVerificationStatus);
destination.writeString(mContactDisplayName);
destination.writeString(mActiveChildCallId);
+ destination.writeParcelable(mContactPhotoUri, 0);
}
@Override
diff --git a/tests/ApkVerityTest/src/com/android/apkverity/ApkVerityTest.java b/tests/ApkVerityTest/src/com/android/apkverity/ApkVerityTest.java
index d96005b8a71a..16f005f28856 100644
--- a/tests/ApkVerityTest/src/com/android/apkverity/ApkVerityTest.java
+++ b/tests/ApkVerityTest/src/com/android/apkverity/ApkVerityTest.java
@@ -25,7 +25,6 @@ import static org.junit.Assert.fail;
import android.platform.test.annotations.RootPermissionTest;
import com.android.blockdevicewriter.BlockDeviceWriter;
-import com.android.fsverity.AddFsVerityCertRule;
import com.android.tradefed.device.DeviceNotAvailableException;
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.log.LogUtil.CLog;
@@ -36,7 +35,6 @@ import com.android.tradefed.util.CommandStatus;
import org.junit.After;
import org.junit.Before;
-import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -90,10 +88,6 @@ public class ApkVerityTest extends BaseHostJUnit4Test {
/** Only 4K page is supported by fs-verity currently. */
private static final int FSVERITY_PAGE_SIZE = 4096;
- @Rule
- public final AddFsVerityCertRule mAddFsVerityCertRule =
- new AddFsVerityCertRule(this, CERT_PATH);
-
private ITestDevice mDevice;
private boolean mDmRequireFsVerity;
@@ -103,11 +97,13 @@ public class ApkVerityTest extends BaseHostJUnit4Test {
mDmRequireFsVerity = "true".equals(
mDevice.getProperty("pm.dexopt.dm.require_fsverity"));
+ expectRemoteCommandToSucceed("cmd file_integrity append-cert " + CERT_PATH);
uninstallPackage(TARGET_PACKAGE);
}
@After
public void tearDown() throws DeviceNotAvailableException {
+ expectRemoteCommandToSucceed("cmd file_integrity remove-last-cert");
uninstallPackage(TARGET_PACKAGE);
}
diff --git a/tests/InputMethodStressTest/AndroidManifest.xml b/tests/InputMethodStressTest/AndroidManifest.xml
index f5fe8f2e8e76..2d183bcb81fd 100644
--- a/tests/InputMethodStressTest/AndroidManifest.xml
+++ b/tests/InputMethodStressTest/AndroidManifest.xml
@@ -16,11 +16,11 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.inputmethod.stresstest">
+ package="com.android.inputmethod.stresstest">
<application>
- <activity android:name=".AutoShowTest$TestActivity"/>
- <activity android:name=".ImeOpenCloseStressTest$TestActivity"/>
+ <activity android:name=".ImeStressTestUtil$TestActivity"
+ android:configChanges="orientation|screenSize"/>
</application>
<instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
diff --git a/tests/InputMethodStressTest/TEST_MAPPING b/tests/InputMethodStressTest/TEST_MAPPING
index ad07205ab02d..06e2ce84eb0f 100644
--- a/tests/InputMethodStressTest/TEST_MAPPING
+++ b/tests/InputMethodStressTest/TEST_MAPPING
@@ -1,5 +1,5 @@
{
- "presubmit": [
+ "presubmit-large": [
{
"name": "InputMethodStressTest"
}
diff --git a/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/AutoShowTest.java b/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/AutoShowTest.java
index 92ea029bf469..8e4ecf1b2a26 100644
--- a/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/AutoShowTest.java
+++ b/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/AutoShowTest.java
@@ -16,24 +16,32 @@
package com.android.inputmethod.stresstest;
-import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
-import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
-
+import static com.android.inputmethod.stresstest.ImeStressTestUtil.REQUEST_FOCUS_ON_CREATE;
+import static com.android.inputmethod.stresstest.ImeStressTestUtil.TestActivity;
+import static com.android.inputmethod.stresstest.ImeStressTestUtil.TestActivity.createIntent;
+import static com.android.inputmethod.stresstest.ImeStressTestUtil.UNFOCUSABLE_VIEW;
+import static com.android.inputmethod.stresstest.ImeStressTestUtil.callOnMainSync;
+import static com.android.inputmethod.stresstest.ImeStressTestUtil.getWindowAndSoftInputFlagParameters;
+import static com.android.inputmethod.stresstest.ImeStressTestUtil.hasUnfocusableWindowFlags;
+import static com.android.inputmethod.stresstest.ImeStressTestUtil.verifyImeAlwaysHiddenWithWindowFlagSet;
import static com.android.inputmethod.stresstest.ImeStressTestUtil.verifyImeIsAlwaysHidden;
-import static com.android.inputmethod.stresstest.ImeStressTestUtil.waitOnMainUntil;
+import static com.android.inputmethod.stresstest.ImeStressTestUtil.verifyWindowAndViewFocus;
import static com.android.inputmethod.stresstest.ImeStressTestUtil.waitOnMainUntilImeIsShown;
-import android.app.Activity;
+import static com.google.common.truth.Truth.assertThat;
+
import android.app.Instrumentation;
import android.content.Intent;
-import android.os.Bundle;
+import android.os.SystemClock;
import android.platform.test.annotations.RootPermissionTest;
import android.platform.test.rule.UnlockScreenRule;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.UiDevice;
+import android.support.test.uiautomator.UiObject2;
+import android.support.test.uiautomator.Until;
import android.view.WindowManager;
import android.widget.EditText;
-import android.widget.LinearLayout;
-import androidx.annotation.Nullable;
import androidx.test.platform.app.InstrumentationRegistry;
import org.junit.Rule;
@@ -41,135 +49,428 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
-import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
/**
- * Tests to verify the "auto show" behavior in {@code InputMethodManagerService} when the window
+ * Tests to verify the "auto-show" behavior in {@code InputMethodManagerService} when the window
* gaining the focus to start the input.
*/
@RootPermissionTest
@RunWith(Parameterized.class)
public final class AutoShowTest {
- @Rule
- public UnlockScreenRule mUnlockScreenRule = new UnlockScreenRule();
+ @Rule public UnlockScreenRule mUnlockScreenRule = new UnlockScreenRule();
@Rule
public ScreenCaptureRule mScreenCaptureRule =
new ScreenCaptureRule("/sdcard/InputMethodStressTest");
- private static final int[] SOFT_INPUT_VISIBILITY_FLAGS =
- new int[] {
- WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED,
- WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN,
- WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN,
- WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE,
- WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE,
- };
-
- private static final int[] SOFT_INPUT_ADJUST_FLAGS =
- new int[] {
- WindowManager.LayoutParams.SOFT_INPUT_ADJUST_UNSPECIFIED,
- WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE,
- WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN,
- WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING
- };
-
// TODO(b/240359838): add test case {@code Configuration.SCREENLAYOUT_SIZE_LARGE}.
@Parameterized.Parameters(
- name =
- "softInputVisibility={0}, softInputAdjustment={1},"
- + " softInputModeIsForwardNavigation={2}")
- public static List<Object[]> softInputModeConfigs() {
- ArrayList<Object[]> params = new ArrayList<>();
- for (int softInputVisibility : SOFT_INPUT_VISIBILITY_FLAGS) {
- for (int softInputAdjust : SOFT_INPUT_ADJUST_FLAGS) {
- params.add(new Object[] {softInputVisibility, softInputAdjust, true});
- params.add(new Object[] {softInputVisibility, softInputAdjust, false});
- }
- }
- return params;
+ name = "windowFocusFlags={0}, softInputVisibility={1}, softInputAdjustment={2}")
+ public static List<Object[]> windowAndSoftInputFlagParameters() {
+ return getWindowAndSoftInputFlagParameters();
}
- private static final String SOFT_INPUT_FLAGS = "soft_input_flags";
+ private final int mSoftInputFlags;
+ private final int mWindowFocusFlags;
+ private final Instrumentation mInstrumentation;
- private final int mSoftInputVisibility;
- private final int mSoftInputAdjustment;
- private final boolean mSoftInputIsForwardNavigation;
+ public AutoShowTest(int windowFocusFlags, int softInputVisibility, int softInputAdjustment) {
+ mSoftInputFlags = softInputVisibility | softInputAdjustment;
+ mWindowFocusFlags = windowFocusFlags;
+ mInstrumentation = InstrumentationRegistry.getInstrumentation();
+ }
- public AutoShowTest(
- int softInputVisibility,
- int softInputAdjustment,
- boolean softInputIsForwardNavigation) {
- mSoftInputVisibility = softInputVisibility;
- mSoftInputAdjustment = softInputAdjustment;
- mSoftInputIsForwardNavigation = softInputIsForwardNavigation;
+ /**
+ * Test auto-show IME behavior when the {@link EditText} is focusable ({@link
+ * EditText#isFocusableInTouchMode} is {@code true}) and has called {@link
+ * EditText#requestFocus}.
+ */
+ @Test
+ public void autoShow_hasFocusedView_requestFocus() {
+ // request focus at onCreate()
+ Intent intent =
+ createIntent(
+ mWindowFocusFlags,
+ mSoftInputFlags,
+ Collections.singletonList(REQUEST_FOCUS_ON_CREATE));
+ TestActivity activity = TestActivity.start(intent);
+
+ verifyAutoShowBehavior_forwardWithKeyboardOff(activity);
}
+ /**
+ * Test auto-show IME behavior when the {@link EditText} is focusable ({@link
+ * EditText#isFocusableInTouchMode} is {@code true}) and {@link EditText#requestFocus} is not
+ * called. The IME should never be shown because there is no focused editor in the window.
+ */
@Test
- public void autoShow() {
- Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
- int flags = mSoftInputVisibility | mSoftInputAdjustment;
- if (mSoftInputIsForwardNavigation) {
- flags |= WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION;
+ public void autoShow_hasFocusedView_notRequestFocus() {
+ // request focus not set
+ Intent intent = createIntent(mWindowFocusFlags, mSoftInputFlags, Collections.emptyList());
+ TestActivity activity = TestActivity.start(intent);
+ EditText editText = activity.getEditText();
+
+ int windowFlags = activity.getWindow().getAttributes().flags;
+ if ((windowFlags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) != 0) {
+ // When FLAG_NOT_FOCUSABLE is set true, the view will never gain window focus.
+ verifyWindowAndViewFocus(
+ editText, /*expectWindowFocus*/ false, /*expectViewFocus*/ false);
+ } else {
+ verifyWindowAndViewFocus(
+ editText, /*expectWindowFocus*/ true, /*expectViewFocus*/ false);
}
+ // IME is always hidden because there is no view focus.
+ verifyImeIsAlwaysHidden(editText);
+ }
+ /**
+ * Test auto-show IME behavior when the {@link EditText} is not focusable ({@link
+ * EditText#isFocusableInTouchMode} is {@code false}) and {@link EditText#requestFocus} is not
+ * called. The IME should never be shown because there is no focusable editor in the window.
+ */
+ @Test
+ public void autoShow_notFocusedView_notRequestFocus() {
+ // Unfocusable view, request focus not set
Intent intent =
- new Intent()
- .setAction(Intent.ACTION_MAIN)
- .setClass(instrumentation.getContext(), TestActivity.class)
- .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
- .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
- .putExtra(SOFT_INPUT_FLAGS, flags);
- TestActivity activity = (TestActivity) instrumentation.startActivitySync(intent);
+ createIntent(
+ mWindowFocusFlags,
+ mSoftInputFlags,
+ Collections.singletonList(UNFOCUSABLE_VIEW));
+ TestActivity activity = TestActivity.start(intent);
EditText editText = activity.getEditText();
- waitOnMainUntil("activity should gain focus", editText::hasWindowFocus);
- if (mSoftInputVisibility == WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE
- || mSoftInputVisibility
- == WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE) {
- // IME will be auto-shown if softInputMode is set with flag:
- // SOFT_INPUT_STATE_VISIBLE or SOFT_INPUT_STATE_ALWAYS_VISIBLE
- waitOnMainUntilImeIsShown(editText);
- } else if (mSoftInputVisibility == WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN
- || mSoftInputVisibility
- == WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN) {
- // IME will be not be shown if softInputMode is set with flag:
- // SOFT_INPUT_STATE_HIDDEN or SOFT_INPUT_STATE_ALWAYS_HIDDEN
- verifyImeIsAlwaysHidden(editText);
+ int windowFlags = activity.getWindow().getAttributes().flags;
+ if ((windowFlags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) != 0) {
+ // When FLAG_NOT_FOCUSABLE is set true, the view will never gain window focus.
+ verifyWindowAndViewFocus(
+ editText, /*expectWindowFocus*/ false, /*expectViewFocus*/ false);
} else {
- // The current system behavior will choose to show IME automatically when navigating
- // forward to an app that has no visibility state specified (i.e.
- // SOFT_INPUT_STATE_UNSPECIFIED) with set SOFT_INPUT_ADJUST_RESIZE flag.
- if (mSoftInputVisibility == WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED
- && mSoftInputAdjustment == WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE
- && mSoftInputIsForwardNavigation) {
+ verifyWindowAndViewFocus(
+ editText, /*expectWindowFocus*/ true, /*expectViewFocus*/ false);
+ }
+ // IME is always hidden because there is no focused view.
+ verifyImeIsAlwaysHidden(editText);
+ }
+
+ /**
+ * Test auto-show IME behavior when the activity is navigated forward from another activity with
+ * keyboard off.
+ */
+ @Test
+ public void autoShow_forwardWithKeyboardOff() {
+ // Create first activity with keyboard off
+ Intent intent1 =
+ createIntent(
+ 0x0 /* No window focus flags */,
+ WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED
+ | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE,
+ Collections.emptyList());
+ TestActivity firstActivity = TestActivity.start(intent1);
+
+ // Create second activity with parameterized flags:
+ Intent intent2 =
+ createIntent(
+ mWindowFocusFlags,
+ mSoftInputFlags,
+ Collections.singletonList(REQUEST_FOCUS_ON_CREATE));
+ TestActivity secondActivity = firstActivity.startSecondTestActivity(intent2);
+
+ // The auto-show behavior should be the same as opening the app
+ verifyAutoShowBehavior_forwardWithKeyboardOff(secondActivity);
+ }
+
+ /**
+ * Test auto-show IME behavior when the activity is navigated forward from another activity with
+ * keyboard on.
+ */
+ @Test
+ public void autoShow_forwardWithKeyboardOn() {
+ // Create first activity with keyboard on
+ Intent intent1 =
+ createIntent(
+ 0x0 /* No window focus flags */,
+ WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED
+ | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE,
+ Collections.singletonList(REQUEST_FOCUS_ON_CREATE));
+ TestActivity firstActivity = TestActivity.start(intent1);
+ // Show Ime with InputMethodManager to ensure the keyboard is on.
+ boolean succ = callOnMainSync(firstActivity::showImeWithInputMethodManager);
+ assertThat(succ).isTrue();
+ SystemClock.sleep(1000);
+ mInstrumentation.waitForIdleSync();
+
+ // Create second activity with parameterized flags:
+ Intent intent2 =
+ createIntent(
+ mWindowFocusFlags,
+ mSoftInputFlags,
+ Collections.singletonList(REQUEST_FOCUS_ON_CREATE));
+ TestActivity secondActivity = firstActivity.startSecondTestActivity(intent2);
+
+ // The auto-show behavior should be the same as open app
+ verifyAutoShowBehavior_forwardWithKeyboardOn(secondActivity);
+ }
+
+ /**
+ * Test auto-show IME behavior when the activity is navigated back from another activity with
+ * keyboard off.
+ */
+ @Test
+ public void autoShow_backwardWithKeyboardOff() {
+ // Not request focus at onCreate() to avoid triggering auto-show behavior
+ Intent intent1 = createIntent(mWindowFocusFlags, mSoftInputFlags, Collections.emptyList());
+ TestActivity firstActivity = TestActivity.start(intent1);
+ // Request view focus after app starts
+ mInstrumentation.runOnMainSync(firstActivity::requestFocus);
+
+ Intent intent2 =
+ createIntent(
+ 0x0 /* No window focus flags */,
+ WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED
+ | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE,
+ Collections.emptyList());
+ TestActivity secondActivity = firstActivity.startSecondTestActivity(intent2);
+ secondActivity.finish();
+ mInstrumentation.waitForIdleSync();
+
+ // When activity is navigated back from another activity with keyboard off, the keyboard
+ // will not show except when soft input visibility flag is SOFT_INPUT_STATE_ALWAYS_VISIBLE.
+ verifyAutoShowBehavior_backwardWithKeyboardOff(firstActivity);
+ }
+
+ /**
+ * Test auto-show IME behavior when the activity is navigated back from another activity with
+ * keyboard on.
+ */
+ @Test
+ public void autoShow_backwardWithKeyboardOn() {
+ // Not request focus at onCreate() to avoid triggering auto-show behavior
+ Intent intent1 = createIntent(mWindowFocusFlags, mSoftInputFlags, Collections.emptyList());
+ TestActivity activity = TestActivity.start(intent1);
+ // Request view focus after app starts
+ mInstrumentation.runOnMainSync(activity::requestFocus);
+
+ // Create second TestActivity
+ Intent intent2 =
+ createIntent(
+ 0x0 /* No window focus flags */,
+ WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED
+ | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE,
+ Collections.singletonList(REQUEST_FOCUS_ON_CREATE));
+ ImeStressTestUtil.TestActivity secondActivity = activity.startSecondTestActivity(intent2);
+ // Show Ime with InputMethodManager to ensure the keyboard is shown on the second activity
+ boolean succ = callOnMainSync(secondActivity::showImeWithInputMethodManager);
+ assertThat(succ).isTrue();
+ SystemClock.sleep(1000);
+ mInstrumentation.waitForIdleSync();
+ // Close the second activity
+ secondActivity.finish();
+ SystemClock.sleep(1000);
+ mInstrumentation.waitForIdleSync();
+ // When activity is navigated back from another activity with keyboard on, the keyboard
+ // will not hide except when soft input visibility flag is SOFT_INPUT_STATE_ALWAYS_HIDDEN.
+ verifyAutoShowBehavior_backwardWithKeyboardOn(activity);
+ }
+
+ @Test
+ public void clickFocusableView_requestFocus() {
+ if ((mWindowFocusFlags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) != 0) {
+ // UiAutomator cannot get UiObject if FLAG_NOT_FOCUSABLE is set
+ return;
+ }
+ Intent intent = createIntent(mWindowFocusFlags, mSoftInputFlags, Collections.emptyList());
+ TestActivity activity = TestActivity.start(intent);
+ // Request view focus after app starts
+ mInstrumentation.runOnMainSync(activity::requestFocus);
+
+ // Find the editText and click it
+ UiObject2 editTextUiObject =
+ UiDevice.getInstance(mInstrumentation)
+ .wait(Until.findObject(By.clazz(EditText.class)), 5000);
+ assertThat(editTextUiObject).isNotNull();
+ editTextUiObject.click();
+
+ // Ime will show unless window flag is set
+ verifyClickBehavior(activity);
+ }
+
+ @Test
+ public void clickFocusableView_notRequestFocus() {
+ if ((mWindowFocusFlags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) != 0) {
+ // UiAutomator cannot get UiObject if FLAG_NOT_FOCUSABLE is set
+ return;
+ }
+ // Not request focus
+ Intent intent1 = createIntent(mWindowFocusFlags, mSoftInputFlags, Collections.emptyList());
+ TestActivity activity = TestActivity.start(intent1);
+
+ // Find the editText and click it
+ UiObject2 editTextUiObject =
+ UiDevice.getInstance(mInstrumentation)
+ .wait(Until.findObject(By.clazz(EditText.class)), 5000);
+ assertThat(editTextUiObject).isNotNull();
+ editTextUiObject.click();
+
+ // Ime will show unless window flag is set
+ verifyClickBehavior(activity);
+ }
+
+ public static void verifyAutoShowBehavior_forwardWithKeyboardOff(TestActivity activity) {
+ // public: also used by ImeOpenCloseStressTest
+ if (hasUnfocusableWindowFlags(activity)) {
+ verifyImeAlwaysHiddenWithWindowFlagSet(activity);
+ return;
+ }
+
+ int softInputMode = activity.getWindow().getAttributes().softInputMode;
+ int softInputVisibility = softInputMode & WindowManager.LayoutParams.SOFT_INPUT_MASK_STATE;
+ int softInputAdjustment = softInputMode & WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST;
+ EditText editText = activity.getEditText();
+
+ verifyWindowAndViewFocus(editText, /*expectWindowFocus*/ true, /*expectViewFocus*/ true);
+ switch (softInputVisibility) {
+ case WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE:
+ case WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE: {
+ // IME will be auto-shown if softInputMode is set with flag:
+ // SOFT_INPUT_STATE_VISIBLE or SOFT_INPUT_STATE_ALWAYS_VISIBLE
waitOnMainUntilImeIsShown(editText);
+ break;
+ }
+ case WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED:
+ case WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN:
+ case WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN: {
+ // IME will be not be auto-shown if softInputMode is set with flag:
+ // SOFT_INPUT_STATE_HIDDEN or SOFT_INPUT_STATE_ALWAYS_HIDDEN,
+ // or stay unchanged if set SOFT_INPUT_STATE_UNCHANGED
+ verifyImeIsAlwaysHidden(editText);
+ break;
+ }
+ case WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED: {
+ if (softInputAdjustment
+ == WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE) {
+ // The current system behavior will choose to show IME automatically when
+ // navigating forward to an app that has no visibility state specified
+ // (i.e. SOFT_INPUT_STATE_UNSPECIFIED) with set SOFT_INPUT_ADJUST_RESIZE
+ // flag.
+ waitOnMainUntilImeIsShown(editText);
+ } else {
+ verifyImeIsAlwaysHidden(editText);
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ private static void verifyAutoShowBehavior_forwardWithKeyboardOn(TestActivity activity) {
+ int windowFlags = activity.getWindow().getAttributes().flags;
+ int softInputMode = activity.getWindow().getAttributes().softInputMode;
+ int softInputVisibility = softInputMode & WindowManager.LayoutParams.SOFT_INPUT_MASK_STATE;
+ int softInputAdjustment = softInputMode & WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST;
+ EditText editText = activity.getEditText();
+
+ if ((windowFlags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) != 0) {
+ // When FLAG_NOT_FOCUSABLE is set true, the view will never gain window focus. The IME
+ // will always be hidden even though the view can get focus itself.
+ verifyWindowAndViewFocus(
+ editText, /*expectWindowFocus*/ false, /*expectViewFocus*/ true);
+ // TODO(b/252192121): Ime should be hidden but is shown.
+ // waitOnMainUntilImeIsHidden(editText);
+ return;
+ } else if ((windowFlags & WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM) != 0
+ || (windowFlags & WindowManager.LayoutParams.FLAG_LOCAL_FOCUS_MODE) != 0) {
+ // When FLAG_ALT_FOCUSABLE_IM or FLAG_LOCAL_FOCUS_MODE is set, the view can gain both
+ // window focus and view focus but not IME focus. The IME will always be hidden.
+ verifyWindowAndViewFocus(
+ editText, /*expectWindowFocus*/ true, /*expectViewFocus*/ true);
+ // TODO(b/252192121): Ime should be hidden but is shown.
+ // waitOnMainUntilImeIsHidden(editText);
+ return;
+ }
+ verifyWindowAndViewFocus(editText, /*expectWindowFocus*/ true, /*expectViewFocus*/ true);
+ switch (softInputVisibility) {
+ case WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED:
+ case WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE:
+ case WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE: {
+ // IME will be auto-shown if softInputMode is set with flag:
+ // SOFT_INPUT_STATE_VISIBLE or SOFT_INPUT_STATE_ALWAYS_VISIBLE
+ waitOnMainUntilImeIsShown(editText);
+ break;
+ }
+ case WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN:
+ case WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN: {
+ // IME will be not be auto-shown if softInputMode is set with flag:
+ // SOFT_INPUT_STATE_HIDDEN or SOFT_INPUT_STATE_ALWAYS_HIDDEN
+ // or stay unchanged if set SOFT_INPUT_STATE_UNCHANGED
+ verifyImeIsAlwaysHidden(editText);
+ break;
}
+ case WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED: {
+ if (softInputAdjustment
+ == WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE) {
+ // The current system behavior will choose to show IME automatically when
+ // navigating
+ // forward to an app that has no visibility state specified (i.e.
+ // SOFT_INPUT_STATE_UNSPECIFIED) with set SOFT_INPUT_ADJUST_RESIZE flag.
+ waitOnMainUntilImeIsShown(editText);
+ } else {
+ verifyImeIsAlwaysHidden(editText);
+ }
+ break;
+ }
+ default:
+ break;
}
}
- public static class TestActivity extends Activity {
- private EditText mEditText;
-
- @Override
- protected void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- int flags = getIntent().getIntExtra(SOFT_INPUT_FLAGS, 0);
- getWindow().setSoftInputMode(flags);
- LinearLayout rootView = new LinearLayout(this);
- rootView.setOrientation(LinearLayout.VERTICAL);
- mEditText = new EditText(this);
- rootView.addView(mEditText, new LinearLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT));
- setContentView(rootView);
- // Ensure the focused view is a text editor (View#onCheckIsTextEditor() returns true) to
- // automatically display a soft input window.
- mEditText.requestFocus();
+ private static void verifyAutoShowBehavior_backwardWithKeyboardOff(TestActivity activity) {
+ if (hasUnfocusableWindowFlags(activity)) {
+ verifyImeAlwaysHiddenWithWindowFlagSet(activity);
+ return;
+ }
+ int softInputMode = activity.getWindow().getAttributes().softInputMode;
+ int softInputVisibility = softInputMode & WindowManager.LayoutParams.SOFT_INPUT_MASK_STATE;
+ EditText editText = activity.getEditText();
+
+ verifyWindowAndViewFocus(editText, /*expectWindowFocus*/ true, /*expectViewFocus*/ true);
+ if (softInputVisibility == WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE) {
+ waitOnMainUntilImeIsShown(editText);
+ } else {
+ verifyImeIsAlwaysHidden(editText);
+ }
+ }
+
+ private static void verifyAutoShowBehavior_backwardWithKeyboardOn(TestActivity activity) {
+ if (hasUnfocusableWindowFlags(activity)) {
+ verifyImeAlwaysHiddenWithWindowFlagSet(activity);
+ return;
+ }
+ int softInputMode = activity.getWindow().getAttributes().softInputMode;
+ int softInputVisibility = softInputMode & WindowManager.LayoutParams.SOFT_INPUT_MASK_STATE;
+ EditText editText = activity.getEditText();
+
+ verifyWindowAndViewFocus(editText, /*expectWindowFocus*/ true, /*expectViewFocus*/ true);
+ if (softInputVisibility == WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN) {
+ verifyImeIsAlwaysHidden(editText);
+ } else {
+ waitOnMainUntilImeIsShown(editText);
}
+ }
- public EditText getEditText() {
- return mEditText;
+ private static void verifyClickBehavior(TestActivity activity) {
+ int windowFlags = activity.getWindow().getAttributes().flags;
+ EditText editText = activity.getEditText();
+
+ verifyWindowAndViewFocus(editText, /*expectWindowFocus*/ true, /*expectViewFocus*/ true);
+ if ((windowFlags & WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM) != 0
+ || (windowFlags & WindowManager.LayoutParams.FLAG_LOCAL_FOCUS_MODE) != 0) {
+ verifyImeIsAlwaysHidden(editText);
+ } else {
+ waitOnMainUntilImeIsShown(editText);
}
}
}
diff --git a/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeOpenCloseStressTest.java b/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeOpenCloseStressTest.java
index 8419276f4406..82acfb646d19 100644
--- a/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeOpenCloseStressTest.java
+++ b/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeOpenCloseStressTest.java
@@ -16,224 +16,535 @@
package com.android.inputmethod.stresstest;
-import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
-import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
-import static android.view.WindowInsetsAnimation.Callback.DISPATCH_MODE_STOP;
-
+import static com.android.inputmethod.stresstest.ImeStressTestUtil.INPUT_METHOD_MANAGER_HIDE_ON_CREATE;
+import static com.android.inputmethod.stresstest.ImeStressTestUtil.INPUT_METHOD_MANAGER_SHOW_ON_CREATE;
+import static com.android.inputmethod.stresstest.ImeStressTestUtil.REQUEST_FOCUS_ON_CREATE;
+import static com.android.inputmethod.stresstest.ImeStressTestUtil.TestActivity;
+import static com.android.inputmethod.stresstest.ImeStressTestUtil.TestActivity.createIntent;
+import static com.android.inputmethod.stresstest.ImeStressTestUtil.WINDOW_INSETS_CONTROLLER_HIDE_ON_CREATE;
+import static com.android.inputmethod.stresstest.ImeStressTestUtil.WINDOW_INSETS_CONTROLLER_SHOW_ON_CREATE;
+import static com.android.inputmethod.stresstest.ImeStressTestUtil.callOnMainSync;
+import static com.android.inputmethod.stresstest.ImeStressTestUtil.getWindowAndSoftInputFlagParameters;
+import static com.android.inputmethod.stresstest.ImeStressTestUtil.hasUnfocusableWindowFlags;
import static com.android.inputmethod.stresstest.ImeStressTestUtil.isImeShown;
+import static com.android.inputmethod.stresstest.ImeStressTestUtil.verifyImeAlwaysHiddenWithWindowFlagSet;
+import static com.android.inputmethod.stresstest.ImeStressTestUtil.verifyImeIsAlwaysHidden;
+import static com.android.inputmethod.stresstest.ImeStressTestUtil.verifyWindowAndViewFocus;
import static com.android.inputmethod.stresstest.ImeStressTestUtil.waitOnMainUntil;
+import static com.android.inputmethod.stresstest.ImeStressTestUtil.waitOnMainUntilImeIsHidden;
+import static com.android.inputmethod.stresstest.ImeStressTestUtil.waitOnMainUntilImeIsShown;
+
+import static com.google.common.truth.Truth.assertThat;
-import android.app.Activity;
import android.app.Instrumentation;
import android.content.Intent;
-import android.os.Bundle;
+import android.os.Build;
import android.os.SystemClock;
import android.platform.test.annotations.RootPermissionTest;
import android.platform.test.rule.UnlockScreenRule;
+import android.support.test.uiautomator.UiDevice;
import android.util.Log;
-import android.view.WindowInsets;
-import android.view.WindowInsetsAnimation;
-import android.view.inputmethod.InputMethodManager;
+import android.view.WindowManager;
import android.widget.EditText;
-import android.widget.LinearLayout;
-import androidx.annotation.Nullable;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.platform.app.InstrumentationRegistry;
-import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
@RootPermissionTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(Parameterized.class)
public final class ImeOpenCloseStressTest {
private static final String TAG = "ImeOpenCloseStressTest";
private static final int NUM_TEST_ITERATIONS = 10;
- @Rule
- public UnlockScreenRule mUnlockScreenRule = new UnlockScreenRule();
+ @Rule public UnlockScreenRule mUnlockScreenRule = new UnlockScreenRule();
@Rule
public ScreenCaptureRule mScreenCaptureRule =
new ScreenCaptureRule("/sdcard/InputMethodStressTest");
- private Instrumentation mInstrumentation;
- @Before
- public void setUp() {
+ private final Instrumentation mInstrumentation;
+ private final int mSoftInputFlags;
+ private final int mWindowFocusFlags;
+
+ @Parameterized.Parameters(
+ name = "windowFocusFlags={0}, softInputVisibility={1}, softInputAdjustment={2}")
+ public static List<Object[]> windowAndSoftInputFlagParameters() {
+ return getWindowAndSoftInputFlagParameters();
+ }
+
+ public ImeOpenCloseStressTest(
+ int windowFocusFlags, int softInputVisibility, int softInputAdjustment) {
+ mSoftInputFlags = softInputVisibility | softInputAdjustment;
+ mWindowFocusFlags = windowFocusFlags;
mInstrumentation = InstrumentationRegistry.getInstrumentation();
}
@Test
- public void testShowHide_waitingVisibilityChange() {
- TestActivity activity = TestActivity.start();
- EditText editText = activity.getEditText();
- waitOnMainUntil("activity should gain focus", editText::hasWindowFocus);
- for (int i = 0; i < NUM_TEST_ITERATIONS; i++) {
+ public void testShowHideWithInputMethodManager_waitingVisibilityChange() {
+ Intent intent = createIntent(mWindowFocusFlags, mSoftInputFlags, Collections.emptyList());
+ TestActivity activity = TestActivity.start(intent);
+ // Request focus after app starts to avoid triggering auto-show behavior.
+ mInstrumentation.runOnMainSync(activity::requestFocus);
+ // Test only once if window flags set to save time.
+ int iterNum = hasUnfocusableWindowFlags(activity) ? 1 : NUM_TEST_ITERATIONS;
+ for (int i = 0; i < iterNum; i++) {
String msgPrefix = "Iteration #" + i + " ";
Log.i(TAG, msgPrefix + "start");
- mInstrumentation.runOnMainSync(activity::showIme);
- waitOnMainUntil(msgPrefix + "IME should be visible", () -> isImeShown(editText));
- mInstrumentation.runOnMainSync(activity::hideIme);
- waitOnMainUntil(msgPrefix + "IME should be hidden", () -> !isImeShown(editText));
+ boolean showResult = callOnMainSync(activity::showImeWithInputMethodManager);
+ assertThat(showResult).isEqualTo(!(hasUnfocusableWindowFlags(activity)));
+ verifyShowBehavior(activity);
+
+ boolean hideResult = callOnMainSync(activity::hideImeWithInputMethodManager);
+ assertThat(hideResult).isEqualTo(!(hasUnfocusableWindowFlags(activity)));
+
+ verifyHideBehavior(activity);
}
}
@Test
- public void testShowHide_waitingAnimationEnd() {
- TestActivity activity = TestActivity.start();
+ public void testShowHideWithInputMethodManager_waitingAnimationEnd() {
+ Intent intent = createIntent(mWindowFocusFlags, mSoftInputFlags, Collections.emptyList());
+ TestActivity activity = TestActivity.start(intent);
+ // Request focus after app starts to avoid triggering auto-show behavior.
+ mInstrumentation.runOnMainSync(activity::requestFocus);
+
+ if (hasUnfocusableWindowFlags(activity)) {
+ return; // Skip to save time.
+ }
activity.enableAnimationMonitoring();
EditText editText = activity.getEditText();
- waitOnMainUntil("activity should gain focus", editText::hasWindowFocus);
for (int i = 0; i < NUM_TEST_ITERATIONS; i++) {
String msgPrefix = "Iteration #" + i + " ";
Log.i(TAG, msgPrefix + "start");
- mInstrumentation.runOnMainSync(activity::showIme);
- waitOnMainUntil(msgPrefix + "IME should be visible",
+ boolean showResult = callOnMainSync(activity::showImeWithInputMethodManager);
+ assertThat(showResult).isTrue();
+ waitOnMainUntil(
+ msgPrefix + "IME should be visible",
() -> !activity.isAnimating() && isImeShown(editText));
- mInstrumentation.runOnMainSync(activity::hideIme);
- waitOnMainUntil(msgPrefix + "IME should be hidden",
+
+ boolean hideResult = callOnMainSync(activity::hideImeWithInputMethodManager);
+ assertThat(hideResult).isTrue();
+ waitOnMainUntil(
+ msgPrefix + "IME should be hidden",
() -> !activity.isAnimating() && !isImeShown(editText));
}
}
@Test
- public void testShowHide_intervalAfterHide() {
+ public void testShowHideWithInputMethodManager_intervalAfterHide() {
// Regression test for b/221483132
- TestActivity activity = TestActivity.start();
- EditText editText = activity.getEditText();
+ Intent intent = createIntent(mWindowFocusFlags, mSoftInputFlags, Collections.emptyList());
+ TestActivity activity = TestActivity.start(intent);
+ // Request focus after app starts to avoid triggering auto-show behavior.
+ mInstrumentation.runOnMainSync(activity::requestFocus);
+ if (hasUnfocusableWindowFlags(activity)) {
+ return; // Skip to save time.
+ }
// Intervals = 10, 20, 30, ..., 100, 150, 200, ...
List<Integer> intervals = new ArrayList<>();
for (int i = 10; i < 100; i += 10) intervals.add(i);
for (int i = 100; i < 1000; i += 50) intervals.add(i);
- waitOnMainUntil("activity should gain focus", editText::hasWindowFocus);
+ boolean firstHide = false;
for (int intervalMillis : intervals) {
String msgPrefix = "Interval = " + intervalMillis + " ";
Log.i(TAG, msgPrefix + " start");
- mInstrumentation.runOnMainSync(activity::hideIme);
+ boolean hideResult = callOnMainSync(activity::hideImeWithInputMethodManager);
+ assertThat(hideResult).isEqualTo(firstHide);
+ firstHide = true;
SystemClock.sleep(intervalMillis);
- mInstrumentation.runOnMainSync(activity::showIme);
- waitOnMainUntil(msgPrefix + "IME should be visible",
- () -> isImeShown(editText));
+
+ boolean showResult = callOnMainSync(activity::showImeWithInputMethodManager);
+ assertThat(showResult).isTrue();
+ verifyShowBehavior(activity);
}
}
@Test
- public void testShowHideInSameFrame() {
- TestActivity activity = TestActivity.start();
- activity.enableAnimationMonitoring();
- EditText editText = activity.getEditText();
- waitOnMainUntil("activity should gain focus", editText::hasWindowFocus);
+ public void testShowHideWithInputMethodManager_inSameFrame() {
+ Intent intent = createIntent(mWindowFocusFlags, mSoftInputFlags, Collections.emptyList());
+ TestActivity activity = TestActivity.start(intent);
+ // Request focus after app starts to avoid triggering auto-show behavior.
+ mInstrumentation.runOnMainSync(activity::requestFocus);
+ if (hasUnfocusableWindowFlags(activity)) {
+ return; // Skip to save time.
+ }
// hidden -> show -> hide
- mInstrumentation.runOnMainSync(() -> {
- Log.i(TAG, "Calling showIme() and hideIme()");
- activity.showIme();
- activity.hideIme();
- });
+ mInstrumentation.runOnMainSync(
+ () -> {
+ Log.i(TAG, "Calling showIme() and hideIme()");
+ activity.showImeWithInputMethodManager();
+ activity.hideImeWithInputMethodManager();
+ });
// Wait until IMMS / IMS handles messages.
SystemClock.sleep(1000);
mInstrumentation.waitForIdleSync();
- waitOnMainUntil("IME should be invisible after show/hide", () -> !isImeShown(editText));
+ verifyHideBehavior(activity);
- mInstrumentation.runOnMainSync(activity::showIme);
- waitOnMainUntil("IME should be visible",
- () -> !activity.isAnimating() && isImeShown(editText));
+ mInstrumentation.runOnMainSync(activity::showImeWithInputMethodManager);
+ verifyShowBehavior(activity);
mInstrumentation.waitForIdleSync();
// shown -> hide -> show
- mInstrumentation.runOnMainSync(() -> {
- Log.i(TAG, "Calling hideIme() and showIme()");
- activity.hideIme();
- activity.showIme();
- });
+ mInstrumentation.runOnMainSync(
+ () -> {
+ Log.i(TAG, "Calling hideIme() and showIme()");
+ activity.hideImeWithInputMethodManager();
+ activity.showImeWithInputMethodManager();
+ });
// Wait until IMMS / IMS handles messages.
SystemClock.sleep(1000);
mInstrumentation.waitForIdleSync();
- waitOnMainUntil("IME should be visible after hide/show",
- () -> !activity.isAnimating() && isImeShown(editText));
+ verifyShowBehavior(activity);
+ }
+
+ @Test
+ public void testShowHideWithInputMethodManager_onCreate() {
+ // Show and hide with InputMethodManager at onCreate()
+ Intent intent =
+ createIntent(
+ mWindowFocusFlags,
+ mSoftInputFlags,
+ Arrays.asList(
+ REQUEST_FOCUS_ON_CREATE,
+ INPUT_METHOD_MANAGER_SHOW_ON_CREATE,
+ INPUT_METHOD_MANAGER_HIDE_ON_CREATE));
+ TestActivity activity = TestActivity.start(intent);
+
+ // TODO: The Ime is expected to show first and then hide. But show or hide
+ // with InputMethodManager at onCreate() would always fail because the window
+ // has not gained focus, so the actual behavior will be the same as auto-show.
+ // verifyHideBehavior(activity);
+ }
+
+ @Test
+ public void testShowWithInputMethodManager_notRequestFocus() {
+ Intent intent = createIntent(mWindowFocusFlags, mSoftInputFlags, Collections.emptyList());
+ TestActivity activity = TestActivity.start(intent);
+
+ // Show InputMethodManager without requesting focus
+ boolean showResult = callOnMainSync(activity::showImeWithInputMethodManager);
+ assertThat(showResult).isFalse();
+
+ int windowFlags = activity.getWindow().getAttributes().flags;
+ EditText editText = activity.getEditText();
+ if ((windowFlags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) != 0) {
+ verifyWindowAndViewFocus(
+ editText, /*expectWindowFocus*/ false, /*expectViewFocus*/ false);
+ } else {
+ verifyWindowAndViewFocus(
+ editText, /*expectWindowFocus*/ true, /*expectViewFocus*/ false);
+ }
+ // The Ime should always be hidden because view never gains focus.
+ verifyImeIsAlwaysHidden(editText);
+ }
+
+ @Test
+ public void testShowHideWithWindowInsetsController_waitingVisibilityChange() {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
+ return;
+ }
+ Intent intent = createIntent(mWindowFocusFlags, mSoftInputFlags, Collections.emptyList());
+ TestActivity activity = TestActivity.start(intent);
+ // Request focus after app starts to avoid triggering auto-show behavior.
+ mInstrumentation.runOnMainSync(activity::requestFocus);
+ // Test only once if window flags set to save time.
+ int iterNum = hasUnfocusableWindowFlags(activity) ? 1 : NUM_TEST_ITERATIONS;
+ for (int i = 0; i < iterNum; i++) {
+ String msgPrefix = "Iteration #" + i + " ";
+ Log.i(TAG, msgPrefix + "start");
+ mInstrumentation.runOnMainSync(activity::showImeWithWindowInsetsController);
+ verifyShowBehavior(activity);
+ mInstrumentation.runOnMainSync(activity::hideImeWithWindowInsetsController);
+ verifyHideBehavior(activity);
+ }
+ }
+
+ @Test
+ public void testShowHideWithWindowInsetsController_waitingAnimationEnd() {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
+ return;
+ }
+ Intent intent = createIntent(mWindowFocusFlags, mSoftInputFlags, Collections.emptyList());
+ TestActivity activity = TestActivity.start(intent);
+ // Request focus after app starts to avoid triggering auto-show behavior.
+ mInstrumentation.runOnMainSync(activity::requestFocus);
+
+ if (hasUnfocusableWindowFlags(activity)) {
+ return; // Skip to save time.
+ }
+ activity.enableAnimationMonitoring();
+ EditText editText = activity.getEditText();
+ for (int i = 0; i < NUM_TEST_ITERATIONS; i++) {
+ String msgPrefix = "Iteration #" + i + " ";
+ Log.i(TAG, msgPrefix + "start");
+ mInstrumentation.runOnMainSync(activity::showImeWithWindowInsetsController);
+ waitOnMainUntil(
+ msgPrefix + "IME should be visible",
+ () -> !activity.isAnimating() && isImeShown(editText));
+
+ mInstrumentation.runOnMainSync(activity::hideImeWithWindowInsetsController);
+ waitOnMainUntil(
+ msgPrefix + "IME should be hidden",
+ () -> !activity.isAnimating() && !isImeShown(editText));
+ }
+ }
+
+ @Test
+ public void testShowHideWithWindowInsetsController_intervalAfterHide() {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
+ return;
+ }
+ Intent intent = createIntent(mWindowFocusFlags, mSoftInputFlags, Collections.emptyList());
+ TestActivity activity = TestActivity.start(intent);
+ // Request focus after app starts to avoid triggering auto-show behavior.
+ mInstrumentation.runOnMainSync(activity::requestFocus);
+
+ if (hasUnfocusableWindowFlags(activity)) {
+ return; // Skip to save time.
+ }
+ // Intervals = 10, 20, 30, ..., 100, 150, 200, ...
+ List<Integer> intervals = new ArrayList<>();
+ for (int i = 10; i < 100; i += 10) intervals.add(i);
+ for (int i = 100; i < 1000; i += 50) intervals.add(i);
+ for (int intervalMillis : intervals) {
+ String msgPrefix = "Interval = " + intervalMillis + " ";
+ Log.i(TAG, msgPrefix + " start");
+ mInstrumentation.runOnMainSync(activity::hideImeWithWindowInsetsController);
+ SystemClock.sleep(intervalMillis);
+
+ mInstrumentation.runOnMainSync(activity::showImeWithWindowInsetsController);
+ verifyShowBehavior(activity);
+ }
}
- public static class TestActivity extends Activity {
+ @Test
+ public void testShowHideWithWindowInsetsController_inSameFrame() {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
+ return;
+ }
+ Intent intent = createIntent(mWindowFocusFlags, mSoftInputFlags, Collections.emptyList());
+ TestActivity activity = TestActivity.start(intent);
+ // Request focus after app starts to avoid triggering auto-show behavior.
+ mInstrumentation.runOnMainSync(activity::requestFocus);
- private EditText mEditText;
- private boolean mIsAnimating;
+ if (hasUnfocusableWindowFlags(activity)) {
+ return; // Skip to save time.
+ }
+ // hidden -> show -> hide
+ mInstrumentation.runOnMainSync(
+ () -> {
+ Log.i(TAG, "Calling showIme() and hideIme()");
+ activity.showImeWithWindowInsetsController();
+ activity.hideImeWithWindowInsetsController();
+ });
+ // Wait until IMMS / IMS handles messages.
+ SystemClock.sleep(1000);
+ mInstrumentation.waitForIdleSync();
+ // TODO(b/248456059): Ime should be hidden but is shown.
+ // verifyHideBehavior(activity);
+
+ mInstrumentation.runOnMainSync(activity::showImeWithWindowInsetsController);
+ verifyShowBehavior(activity);
+ mInstrumentation.waitForIdleSync();
- private final WindowInsetsAnimation.Callback mWindowInsetsAnimationCallback =
- new WindowInsetsAnimation.Callback(DISPATCH_MODE_STOP) {
- @Override
- public WindowInsetsAnimation.Bounds onStart(WindowInsetsAnimation animation,
- WindowInsetsAnimation.Bounds bounds) {
- mIsAnimating = true;
- return super.onStart(animation, bounds);
- }
+ // shown -> hide -> show
+ mInstrumentation.runOnMainSync(
+ () -> {
+ Log.i(TAG, "Calling hideIme() and showIme()");
+ activity.hideImeWithWindowInsetsController();
+ activity.showImeWithWindowInsetsController();
+ });
+ // Wait until IMMS / IMS handles messages.
+ SystemClock.sleep(1000);
+ mInstrumentation.waitForIdleSync();
+ verifyShowBehavior(activity);
+ }
- @Override
- public void onEnd(WindowInsetsAnimation animation) {
- super.onEnd(animation);
- mIsAnimating = false;
- }
+ @Test
+ public void testShowWithWindowInsetsController_onCreate_requestFocus() {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
+ return;
+ }
+ // Show with InputMethodManager at onCreate()
+ Intent intent =
+ createIntent(
+ mWindowFocusFlags,
+ mSoftInputFlags,
+ Arrays.asList(
+ REQUEST_FOCUS_ON_CREATE, WINDOW_INSETS_CONTROLLER_SHOW_ON_CREATE));
+ TestActivity activity = TestActivity.start(intent);
- @Override
- public WindowInsets onProgress(WindowInsets insets,
- List<WindowInsetsAnimation> runningAnimations) {
- return insets;
- }
- };
+ verifyShowBehavior(activity);
+ }
- public static TestActivity start() {
- Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
- Intent intent = new Intent()
- .setAction(Intent.ACTION_MAIN)
- .setClass(instrumentation.getContext(), TestActivity.class)
- .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
- .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
- return (TestActivity) instrumentation.startActivitySync(intent);
+ @Test
+ public void testShowWithWindowInsetsController_onCreate_notRequestFocus() {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
+ return;
}
+ // Show and hide with InputMethodManager at onCreate()
+ Intent intent =
+ createIntent(
+ mWindowFocusFlags,
+ mSoftInputFlags,
+ Collections.singletonList(WINDOW_INSETS_CONTROLLER_SHOW_ON_CREATE));
+ TestActivity activity = TestActivity.start(intent);
+
+ // Ime is shown but with a fallback InputConnection
+ verifyShowBehaviorNotRequestFocus(activity);
+ }
- @Override
- protected void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- LinearLayout rootView = new LinearLayout(this);
- rootView.setOrientation(LinearLayout.VERTICAL);
- mEditText = new EditText(this);
- rootView.addView(mEditText, new LinearLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT));
- setContentView(rootView);
+ @Test
+ public void testShowWithWindowInsetsController_afterStart_notRequestFocus() {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
+ return;
}
+ // Show and hide with InputMethodManager at onCreate()
+ Intent intent = createIntent(mWindowFocusFlags, mSoftInputFlags, Collections.emptyList());
+ TestActivity activity = TestActivity.start(intent);
+ mInstrumentation.runOnMainSync(activity::showImeWithWindowInsetsController);
+
+ // Ime is shown but with a fallback InputConnection
+ verifyShowBehaviorNotRequestFocus(activity);
+ }
- public EditText getEditText() {
- return mEditText;
+ @Test
+ public void testHideWithWindowInsetsController_onCreate_requestFocus() {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
+ return;
}
+ // Show and hide with InputMethodManager at onCreate()
+ Intent intent =
+ createIntent(
+ mWindowFocusFlags,
+ mSoftInputFlags,
+ Arrays.asList(
+ REQUEST_FOCUS_ON_CREATE,
+ WINDOW_INSETS_CONTROLLER_SHOW_ON_CREATE,
+ WINDOW_INSETS_CONTROLLER_HIDE_ON_CREATE));
+ TestActivity activity = TestActivity.start(intent);
+
+ // TODO(b/248456059): Ime should be hidden but is shown.
+ //verifyHideBehavior(activity);
+ }
- public void showIme() {
- Log.i(TAG, "TestActivity.showIme");
- mEditText.requestFocus();
- InputMethodManager imm = getSystemService(InputMethodManager.class);
- imm.showSoftInput(mEditText, 0);
+ @Test
+ public void testScreenOffOn() throws Exception {
+ Intent intent1 =
+ createIntent(
+ mWindowFocusFlags,
+ mSoftInputFlags,
+ Collections.singletonList(REQUEST_FOCUS_ON_CREATE));
+ TestActivity activity = TestActivity.start(intent1);
+ // Show Ime with InputMethodManager to ensure the keyboard is shown on the second activity
+ boolean showResult = callOnMainSync(activity::showImeWithInputMethodManager);
+ assertThat(showResult).isEqualTo(!(hasUnfocusableWindowFlags(activity)));
+
+ Thread.sleep(1000);
+ verifyShowBehavior(activity);
+
+ UiDevice uiDevice = UiDevice.getInstance(mInstrumentation);
+
+ if (uiDevice.isScreenOn()) {
+ uiDevice.sleep();
+ }
+ Thread.sleep(1000);
+ if (!uiDevice.isScreenOn()) {
+ uiDevice.wakeUp();
}
- public void hideIme() {
- Log.i(TAG, "TestActivity.hideIme");
- InputMethodManager imm = getSystemService(InputMethodManager.class);
- imm.hideSoftInputFromWindow(mEditText.getWindowToken(), 0);
+ verifyShowBehavior(activity);
+ }
+
+ @Test
+ public void testRotateScreenWithKeyboardOn() throws Exception {
+ // TODO(b/256739702): Keyboard disappears after rotating screen to landscape mode if
+ // android:configChanges="orientation|screenSize" is not set
+ Intent intent =
+ createIntent(
+ mWindowFocusFlags,
+ mSoftInputFlags,
+ Collections.singletonList(REQUEST_FOCUS_ON_CREATE));
+ TestActivity activity = TestActivity.start(intent);
+ // Show Ime with InputMethodManager to ensure the keyboard is shown on the second activity
+ boolean showResult = callOnMainSync(activity::showImeWithInputMethodManager);
+ assertThat(showResult).isEqualTo(!(hasUnfocusableWindowFlags(activity)));
+ Thread.sleep(2000);
+ verifyShowBehavior(activity);
+
+ UiDevice uiDevice = UiDevice.getInstance(mInstrumentation);
+
+ uiDevice.freezeRotation();
+ uiDevice.setOrientationRight();
+ uiDevice.waitForIdle();
+ Thread.sleep(1000);
+ Log.i(TAG, "Rotate screen right");
+ assertThat(uiDevice.isNaturalOrientation()).isFalse();
+ verifyShowBehavior(activity);
+
+ uiDevice.setOrientationLeft();
+ uiDevice.waitForIdle();
+ Thread.sleep(1000);
+ Log.i(TAG, "Rotate screen left");
+ assertThat(uiDevice.isNaturalOrientation()).isFalse();
+ verifyShowBehavior(activity);
+
+ uiDevice.setOrientationNatural();
+ uiDevice.waitForIdle();
+ uiDevice.unfreezeRotation();
+ }
+
+ private static void verifyShowBehavior(TestActivity activity) {
+ if (hasUnfocusableWindowFlags(activity)) {
+ verifyImeAlwaysHiddenWithWindowFlagSet(activity);
+ return;
}
+ EditText editText = activity.getEditText();
- public void enableAnimationMonitoring() {
- // Enable WindowInsetsAnimation.
- // Note that this has a side effect of disabling InsetsAnimationThreadControlRunner.
- InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
- getWindow().setDecorFitsSystemWindows(false);
- mEditText.setWindowInsetsAnimationCallback(mWindowInsetsAnimationCallback);
- });
+ verifyWindowAndViewFocus(editText, /*expectWindowFocus*/ true, /*expectViewFocus*/ true);
+ waitOnMainUntilImeIsShown(editText);
+ }
+
+ private static void verifyHideBehavior(TestActivity activity) {
+ if (hasUnfocusableWindowFlags(activity)) {
+ verifyImeAlwaysHiddenWithWindowFlagSet(activity);
+ return;
}
+ EditText editText = activity.getEditText();
+
+ verifyWindowAndViewFocus(editText, /*expectWindowFocus*/ true, /*expectViewFocus*/ true);
+ waitOnMainUntilImeIsHidden(editText);
+ }
+
+ private static void verifyShowBehaviorNotRequestFocus(TestActivity activity) {
+ int windowFlags = activity.getWindow().getAttributes().flags;
+ EditText editText = activity.getEditText();
- public boolean isAnimating() {
- return mIsAnimating;
+ if ((windowFlags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) != 0) {
+ verifyWindowAndViewFocus(
+ editText, /*expectWindowFocus*/ false, /*expectViewFocus*/ false);
+ verifyImeIsAlwaysHidden(editText);
+ } else if ((windowFlags & WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM) != 0
+ || (windowFlags & WindowManager.LayoutParams.FLAG_LOCAL_FOCUS_MODE) != 0) {
+ verifyWindowAndViewFocus(
+ editText, /*expectWindowFocus*/ true, /*expectViewFocus*/ false);
+ verifyImeIsAlwaysHidden(editText);
+ } else {
+ verifyWindowAndViewFocus(
+ editText, /*expectWindowFocus*/ true, /*expectViewFocus*/ false);
+ // Ime is shown but with a fallback InputConnection
+ waitOnMainUntilImeIsShown(editText);
}
}
}
diff --git a/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeStressTestUtil.java b/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeStressTestUtil.java
index b6d462c6203d..e16c9152df3e 100644
--- a/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeStressTestUtil.java
+++ b/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeStressTestUtil.java
@@ -16,17 +16,37 @@
package com.android.inputmethod.stresstest;
+import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
+import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
+import static android.view.WindowInsetsAnimation.Callback.DISPATCH_MODE_STOP;
+
import static com.android.compatibility.common.util.SystemUtil.eventually;
import static com.google.common.truth.Truth.assertWithMessage;
+import android.app.Activity;
+import android.app.Instrumentation;
+import android.content.Intent;
+import android.os.Build;
+import android.os.Bundle;
+import android.util.Log;
import android.view.View;
import android.view.WindowInsets;
+import android.view.WindowInsetsAnimation;
+import android.view.WindowInsetsController;
+import android.view.WindowManager;
+import android.view.WindowManager.LayoutParams;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+import androidx.annotation.Nullable;
import androidx.test.platform.app.InstrumentationRegistry;
import com.android.compatibility.common.util.ThrowingRunnable;
+import java.util.ArrayList;
+import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
@@ -34,28 +54,96 @@ import java.util.concurrent.atomic.AtomicReference;
/** Utility methods for IME stress test. */
public final class ImeStressTestUtil {
- private static final long TIMEOUT = TimeUnit.SECONDS.toMillis(5);
- private static final long VERIFY_DURATION = TimeUnit.SECONDS.toMillis(2);
+ private static final long TIMEOUT = TimeUnit.SECONDS.toMillis(3);
+
+ private ImeStressTestUtil() {}
+
+ private static final int[] WINDOW_FOCUS_FLAGS =
+ new int[] {
+ LayoutParams.FLAG_NOT_FOCUSABLE,
+ LayoutParams.FLAG_ALT_FOCUSABLE_IM,
+ LayoutParams.FLAG_NOT_FOCUSABLE | LayoutParams.FLAG_ALT_FOCUSABLE_IM,
+ LayoutParams.FLAG_LOCAL_FOCUS_MODE
+ };
+
+ private static final int[] SOFT_INPUT_VISIBILITY_FLAGS =
+ new int[] {
+ LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED,
+ LayoutParams.SOFT_INPUT_STATE_UNCHANGED,
+ LayoutParams.SOFT_INPUT_STATE_HIDDEN,
+ LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN,
+ LayoutParams.SOFT_INPUT_STATE_VISIBLE,
+ LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE,
+ };
+
+ private static final int[] SOFT_INPUT_ADJUST_FLAGS =
+ new int[] {
+ LayoutParams.SOFT_INPUT_ADJUST_UNSPECIFIED,
+ LayoutParams.SOFT_INPUT_ADJUST_RESIZE,
+ LayoutParams.SOFT_INPUT_ADJUST_PAN,
+ LayoutParams.SOFT_INPUT_ADJUST_NOTHING
+ };
+
+ public static final String SOFT_INPUT_FLAGS = "soft_input_flags";
+ public static final String WINDOW_FLAGS = "window_flags";
+ public static final String UNFOCUSABLE_VIEW = "unfocusable_view";
+ public static final String REQUEST_FOCUS_ON_CREATE = "request_focus_on_create";
+ public static final String INPUT_METHOD_MANAGER_SHOW_ON_CREATE =
+ "input_method_manager_show_on_create";
+ public static final String INPUT_METHOD_MANAGER_HIDE_ON_CREATE =
+ "input_method_manager_hide_on_create";
+ public static final String WINDOW_INSETS_CONTROLLER_SHOW_ON_CREATE =
+ "window_insets_controller_show_on_create";
+ public static final String WINDOW_INSETS_CONTROLLER_HIDE_ON_CREATE =
+ "window_insets_controller_hide_on_create";
- private ImeStressTestUtil() {
+ /** Parameters for show/hide ime parameterized tests. */
+ public static ArrayList<Object[]> getWindowAndSoftInputFlagParameters() {
+ ArrayList<Object[]> params = new ArrayList<>();
+
+ // Set different window focus flags and keep soft input flags as default values (4 cases)
+ for (int windowFocusFlags : WINDOW_FOCUS_FLAGS) {
+ params.add(
+ new Object[] {
+ windowFocusFlags,
+ LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED,
+ LayoutParams.SOFT_INPUT_ADJUST_RESIZE
+ });
+ }
+ // Set the combinations of different softInputVisibility, softInputAdjustment flags,
+ // keep the window focus flag as default value ( 6 * 4 = 24 cases)
+ for (int softInputVisibility : SOFT_INPUT_VISIBILITY_FLAGS) {
+ for (int softInputAdjust : SOFT_INPUT_ADJUST_FLAGS) {
+ params.add(
+ new Object[] {
+ 0x0 /* No window focus flags */, softInputVisibility, softInputAdjust
+ });
+ }
+ }
+ return params;
}
/** Checks if the IME is shown on the window that the given view belongs to. */
public static boolean isImeShown(View view) {
WindowInsets insets = view.getRootWindowInsets();
+ if (insets == null) {
+ return false;
+ }
return insets.isVisible(WindowInsets.Type.ime());
}
/** Calls the callable on the main thread and returns the result. */
public static <V> V callOnMainSync(Callable<V> callable) {
AtomicReference<V> result = new AtomicReference<>();
- InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
- try {
- result.set(callable.call());
- } catch (Exception e) {
- throw new RuntimeException("Exception was thrown", e);
- }
- });
+ InstrumentationRegistry.getInstrumentation()
+ .runOnMainSync(
+ () -> {
+ try {
+ result.set(callable.call());
+ } catch (Exception e) {
+ throw new RuntimeException("Exception was thrown", e);
+ }
+ });
return result.get();
}
@@ -70,15 +158,42 @@ public final class ImeStressTestUtil {
/** Waits until IME is shown, or throws on timeout. */
public static void waitOnMainUntilImeIsShown(View view) {
- eventually(() -> assertWithMessage("IME should be shown").that(
- callOnMainSync(() -> isImeShown(view))).isTrue(), TIMEOUT);
+ eventually(
+ () ->
+ assertWithMessage("IME should be shown")
+ .that(callOnMainSync(() -> isImeShown(view)))
+ .isTrue(),
+ TIMEOUT);
}
/** Waits until IME is hidden, or throws on timeout. */
public static void waitOnMainUntilImeIsHidden(View view) {
- //eventually(() -> assertThat(callOnMainSync(() -> isImeShown(view))).isFalse(), TIMEOUT);
- eventually(() -> assertWithMessage("IME should be hidden").that(
- callOnMainSync(() -> isImeShown(view))).isFalse(), TIMEOUT);
+ eventually(
+ () ->
+ assertWithMessage("IME should be hidden")
+ .that(callOnMainSync(() -> isImeShown(view)))
+ .isFalse(),
+ TIMEOUT);
+ }
+
+ /** Waits until window get focus, or throws on timeout. */
+ public static void waitOnMainUntilWindowGainsFocus(View view) {
+ eventually(
+ () ->
+ assertWithMessage("Window should gain focus")
+ .that(callOnMainSync(view::hasWindowFocus))
+ .isTrue(),
+ TIMEOUT);
+ }
+
+ /** Waits until view get focus, or throws on timeout. */
+ public static void waitOnMainUntilViewGainsFocus(View view) {
+ eventually(
+ () ->
+ assertWithMessage("View should gain focus")
+ .that(callOnMainSync(view::hasFocus))
+ .isTrue(),
+ TIMEOUT);
}
/** Verify IME is always hidden within the given time duration. */
@@ -88,7 +203,27 @@ public final class ImeStressTestUtil {
assertWithMessage("IME should be hidden")
.that(callOnMainSync(() -> isImeShown(view)))
.isFalse(),
- VERIFY_DURATION);
+ TIMEOUT);
+ }
+
+ /** Verify the window never gains focus within the given time duration. */
+ public static void verifyWindowNeverGainsFocus(View view) {
+ always(
+ () ->
+ assertWithMessage("window should never gain focus")
+ .that(callOnMainSync(view::hasWindowFocus))
+ .isFalse(),
+ TIMEOUT);
+ }
+
+ /** Verify the view never gains focus within the given time duration. */
+ public static void verifyViewNeverGainsFocus(View view) {
+ always(
+ () ->
+ assertWithMessage("view should never gain ime focus")
+ .that(callOnMainSync(view::hasFocus))
+ .isFalse(),
+ TIMEOUT);
}
/**
@@ -117,4 +252,232 @@ public final class ImeStressTestUtil {
}
}
}
+
+ public static boolean hasUnfocusableWindowFlags(Activity activity) {
+ int windowFlags = activity.getWindow().getAttributes().flags;
+ return (windowFlags & LayoutParams.FLAG_NOT_FOCUSABLE) != 0
+ || (windowFlags & LayoutParams.FLAG_ALT_FOCUSABLE_IM) != 0
+ || (windowFlags & LayoutParams.FLAG_LOCAL_FOCUS_MODE) != 0;
+ }
+
+ public static void verifyWindowAndViewFocus(
+ View view, boolean expectWindowFocus, boolean expectViewFocus) {
+ if (expectWindowFocus) {
+ waitOnMainUntilWindowGainsFocus(view);
+ } else {
+ verifyWindowNeverGainsFocus(view);
+ }
+ if (expectViewFocus) {
+ waitOnMainUntilViewGainsFocus(view);
+ } else {
+ verifyViewNeverGainsFocus(view);
+ }
+ }
+
+ public static void verifyImeAlwaysHiddenWithWindowFlagSet(TestActivity activity) {
+ int windowFlags = activity.getWindow().getAttributes().flags;
+ View view = activity.getEditText();
+ if ((windowFlags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) != 0) {
+ // When FLAG_NOT_FOCUSABLE is set true, the view will never gain window focus. The IME
+ // will always be hidden even though the view can get focus itself.
+ verifyWindowAndViewFocus(view, /*expectWindowFocus*/ false, /*expectViewFocus*/ true);
+ verifyImeIsAlwaysHidden(view);
+ } else if ((windowFlags & WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM) != 0
+ || (windowFlags & WindowManager.LayoutParams.FLAG_LOCAL_FOCUS_MODE) != 0) {
+ // When FLAG_ALT_FOCUSABLE_IM or FLAG_LOCAL_FOCUS_MODE is set, the view can gain both
+ // window focus and view focus but not IME focus. The IME will always be hidden.
+ verifyWindowAndViewFocus(view, /*expectWindowFocus*/ true, /*expectViewFocus*/ true);
+ verifyImeIsAlwaysHidden(view);
+ }
+ }
+
+ /** Activity to help test show/hide behavior of IME. */
+ public static class TestActivity extends Activity {
+ private static final String TAG = "ImeStressTestUtil.TestActivity";
+ private EditText mEditText;
+ private boolean mIsAnimating;
+
+ private final WindowInsetsAnimation.Callback mWindowInsetsAnimationCallback =
+ new WindowInsetsAnimation.Callback(DISPATCH_MODE_STOP) {
+ @Override
+ public WindowInsetsAnimation.Bounds onStart(
+ WindowInsetsAnimation animation, WindowInsetsAnimation.Bounds bounds) {
+ mIsAnimating = true;
+ return super.onStart(animation, bounds);
+ }
+
+ @Override
+ public void onEnd(WindowInsetsAnimation animation) {
+ super.onEnd(animation);
+ mIsAnimating = false;
+ }
+
+ @Override
+ public WindowInsets onProgress(
+ WindowInsets insets, List<WindowInsetsAnimation> runningAnimations) {
+ return insets;
+ }
+ };
+
+ /** Create intent with extras. */
+ public static Intent createIntent(
+ int windowFlags, int softInputFlags, List<String> extras) {
+ Intent intent =
+ new Intent()
+ .putExtra(WINDOW_FLAGS, windowFlags)
+ .putExtra(SOFT_INPUT_FLAGS, softInputFlags);
+ for (String extra : extras) {
+ intent.putExtra(extra, true);
+ }
+ return intent;
+ }
+
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ Log.i(TAG, "onCreate()");
+ boolean isUnfocusableView = getIntent().getBooleanExtra(UNFOCUSABLE_VIEW, false);
+ boolean requestFocus = getIntent().getBooleanExtra(REQUEST_FOCUS_ON_CREATE, false);
+ int softInputFlags = getIntent().getIntExtra(SOFT_INPUT_FLAGS, 0);
+ int windowFlags = getIntent().getIntExtra(WINDOW_FLAGS, 0);
+ boolean showWithInputMethodManagerOnCreate =
+ getIntent().getBooleanExtra(INPUT_METHOD_MANAGER_SHOW_ON_CREATE, false);
+ boolean hideWithInputMethodManagerOnCreate =
+ getIntent().getBooleanExtra(INPUT_METHOD_MANAGER_HIDE_ON_CREATE, false);
+ boolean showWithWindowInsetsControllerOnCreate =
+ getIntent().getBooleanExtra(WINDOW_INSETS_CONTROLLER_SHOW_ON_CREATE, false);
+ boolean hideWithWindowInsetsControllerOnCreate =
+ getIntent().getBooleanExtra(WINDOW_INSETS_CONTROLLER_HIDE_ON_CREATE, false);
+
+ getWindow().addFlags(windowFlags);
+ getWindow().setSoftInputMode(softInputFlags);
+
+ LinearLayout rootView = new LinearLayout(this);
+ rootView.setOrientation(LinearLayout.VERTICAL);
+ mEditText = new EditText(this);
+ if (isUnfocusableView) {
+ mEditText.setFocusableInTouchMode(false);
+ }
+ rootView.addView(mEditText, new LinearLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT));
+ setContentView(rootView);
+
+ if (requestFocus) {
+ requestFocus();
+ }
+ if (showWithInputMethodManagerOnCreate) {
+ showImeWithInputMethodManager();
+ }
+ if (hideWithInputMethodManagerOnCreate) {
+ hideImeWithInputMethodManager();
+ }
+ if (showWithWindowInsetsControllerOnCreate) {
+ showImeWithWindowInsetsController();
+ }
+ if (hideWithWindowInsetsControllerOnCreate) {
+ hideImeWithWindowInsetsController();
+ }
+ }
+
+ /** Show IME with InputMethodManager. */
+ public boolean showImeWithInputMethodManager() {
+ boolean showResult =
+ getInputMethodManager()
+ .showSoftInput(mEditText, InputMethodManager.SHOW_IMPLICIT);
+ if (showResult) {
+ Log.i(TAG, "IMM#showSoftInput successfully");
+ } else {
+ Log.i(TAG, "IMM#showSoftInput failed");
+ }
+ return showResult;
+ }
+
+ /** Hide IME with InputMethodManager. */
+ public boolean hideImeWithInputMethodManager() {
+ boolean hideResult =
+ getInputMethodManager().hideSoftInputFromWindow(mEditText.getWindowToken(), 0);
+ if (hideResult) {
+ Log.i(TAG, "IMM#hideSoftInput successfully");
+ } else {
+ Log.i(TAG, "IMM#hideSoftInput failed");
+ }
+ return hideResult;
+ }
+
+ /** Show IME with WindowInsetsController */
+ public void showImeWithWindowInsetsController() {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
+ return;
+ }
+ Log.i(TAG, "showImeWithWIC()");
+ WindowInsetsController windowInsetsController = mEditText.getWindowInsetsController();
+ assertWithMessage("WindowInsetsController shouldn't be null.")
+ .that(windowInsetsController)
+ .isNotNull();
+ windowInsetsController.show(WindowInsets.Type.ime());
+ }
+
+ /** Hide IME with WindowInsetsController. */
+ public void hideImeWithWindowInsetsController() {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
+ return;
+ }
+ Log.i(TAG, "hideImeWithWIC()");
+ WindowInsetsController windowInsetsController = mEditText.getWindowInsetsController();
+ assertWithMessage("WindowInsetsController shouldn't be null.")
+ .that(windowInsetsController)
+ .isNotNull();
+ windowInsetsController.hide(WindowInsets.Type.ime());
+ }
+
+ private InputMethodManager getInputMethodManager() {
+ return getSystemService(InputMethodManager.class);
+ }
+
+ public EditText getEditText() {
+ return mEditText;
+ }
+
+ /** Start TestActivity with intent. */
+ public static TestActivity start(Intent intent) {
+ Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+ intent.setAction(Intent.ACTION_MAIN)
+ .setClass(instrumentation.getContext(), TestActivity.class)
+ .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+ .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ return (TestActivity) instrumentation.startActivitySync(intent);
+ }
+
+ /** Start the second TestActivity with intent. */
+ public TestActivity startSecondTestActivity(Intent intent) {
+ Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+ intent.setClass(TestActivity.this, TestActivity.class);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ return (TestActivity) instrumentation.startActivitySync(intent);
+ }
+
+ public void enableAnimationMonitoring() {
+ // Enable WindowInsetsAnimation.
+ // Note that this has a side effect of disabling InsetsAnimationThreadControlRunner.
+ InstrumentationRegistry.getInstrumentation()
+ .runOnMainSync(
+ () -> {
+ getWindow().setDecorFitsSystemWindows(false);
+ mEditText.setWindowInsetsAnimationCallback(
+ mWindowInsetsAnimationCallback);
+ });
+ }
+
+ public boolean isAnimating() {
+ return mIsAnimating;
+ }
+
+ public void requestFocus() {
+ boolean requestFocusResult = getEditText().requestFocus();
+ if (requestFocusResult) {
+ Log.i(TAG, "Request focus successfully");
+ } else {
+ Log.i(TAG, "Request focus failed");
+ }
+ }
+ }
}
diff --git a/tests/Internal/src/com/android/internal/protolog/ProtoLogImplTest.java b/tests/Internal/src/com/android/internal/protolog/ProtoLogImplTest.java
index 3db011683a86..2cdb94526839 100644
--- a/tests/Internal/src/com/android/internal/protolog/ProtoLogImplTest.java
+++ b/tests/Internal/src/com/android/internal/protolog/ProtoLogImplTest.java
@@ -201,24 +201,24 @@ public class ProtoLogImplTest {
@Test
public void log_logcatEnabledExternalMessage() {
- when(mReader.getViewerString(anyInt())).thenReturn("test %b %d %% %o %x %e %g %s %f");
+ when(mReader.getViewerString(anyInt())).thenReturn("test %b %d %% 0x%x %s %f");
ProtoLogImpl implSpy = Mockito.spy(mProtoLog);
TestProtoLogGroup.TEST_GROUP.setLogToLogcat(true);
TestProtoLogGroup.TEST_GROUP.setLogToProto(false);
implSpy.log(
ProtoLogImpl.LogLevel.INFO, TestProtoLogGroup.TEST_GROUP, 1234, 4321, null,
- new Object[]{true, 10000, 20000, 30000, 0.0001, 0.00002, "test", 0.000003});
+ new Object[]{true, 10000, 30000, "test", 0.000003});
verify(implSpy).passToLogcat(eq(TestProtoLogGroup.TEST_GROUP.getTag()), eq(
ProtoLogImpl.LogLevel.INFO),
- eq("test true 10000 % 47040 7530 1.000000e-04 2.00000e-05 test 0.000003"));
+ eq("test true 10000 % 0x7530 test 3.0E-6"));
verify(mReader).getViewerString(eq(1234));
}
@Test
public void log_logcatEnabledInvalidMessage() {
- when(mReader.getViewerString(anyInt())).thenReturn("test %b %d %% %o %x %e %g %s %f");
+ when(mReader.getViewerString(anyInt())).thenReturn("test %b %d %% %x %s %f");
ProtoLogImpl implSpy = Mockito.spy(mProtoLog);
TestProtoLogGroup.TEST_GROUP.setLogToLogcat(true);
TestProtoLogGroup.TEST_GROUP.setLogToProto(false);
diff --git a/tests/Internal/src/com/android/internal/protolog/common/LogDataTypeTest.java b/tests/Internal/src/com/android/internal/protolog/common/LogDataTypeTest.java
index e20ca3df57c7..9c2f74eabe02 100644
--- a/tests/Internal/src/com/android/internal/protolog/common/LogDataTypeTest.java
+++ b/tests/Internal/src/com/android/internal/protolog/common/LogDataTypeTest.java
@@ -36,15 +36,12 @@ import java.util.List;
public class LogDataTypeTest {
@Test
public void parseFormatString() {
- String str = "%b %d %o %x %f %e %g %s %%";
+ String str = "%b %d %x %f %s %%";
List<Integer> out = LogDataType.parseFormatString(str);
assertEquals(Arrays.asList(
LogDataType.BOOLEAN,
LogDataType.LONG,
LogDataType.LONG,
- LogDataType.LONG,
- LogDataType.DOUBLE,
- LogDataType.DOUBLE,
LogDataType.DOUBLE,
LogDataType.STRING
), out);
diff --git a/tests/utils/hostutils/src/com/android/fsverity/AddFsVerityCertRule.java b/tests/utils/hostutils/src/com/android/fsverity/AddFsVerityCertRule.java
deleted file mode 100644
index 5ab4dc60e2ac..000000000000
--- a/tests/utils/hostutils/src/com/android/fsverity/AddFsVerityCertRule.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.fsverity;
-
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import static org.junit.Assume.assumeTrue;
-
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil;
-import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
-import com.android.tradefed.util.CommandResult;
-import com.android.tradefed.util.CommandStatus;
-
-import org.junit.rules.ExternalResource;
-
-public final class AddFsVerityCertRule extends ExternalResource {
-
- private static final String APK_VERITY_STANDARD_MODE = "2";
-
- private final BaseHostJUnit4Test mHost;
- private final String mCertPath;
- private String mKeyId;
-
- public AddFsVerityCertRule(BaseHostJUnit4Test host, String certPath) {
- mHost = host;
- mCertPath = certPath;
- }
-
- @Override
- protected void before() throws Throwable {
- ITestDevice device = mHost.getDevice();
- String apkVerityMode = device.getProperty("ro.apk_verity.mode");
- assumeTrue(device.getLaunchApiLevel() >= 30
- || APK_VERITY_STANDARD_MODE.equals(apkVerityMode));
-
- String keyId = executeCommand(
- "mini-keyctl padd asymmetric fsv_test .fs-verity < " + mCertPath).trim();
- assertThat(keyId).matches("^\\d+$");
- mKeyId = keyId;
- }
-
- @Override
- protected void after() {
- if (mKeyId == null) return;
- try {
- executeCommand("mini-keyctl unlink " + mKeyId + " .fs-verity");
- } catch (DeviceNotAvailableException e) {
- LogUtil.CLog.e(e);
- }
- mKeyId = null;
- }
-
- private String executeCommand(String cmd) throws DeviceNotAvailableException {
- CommandResult result = mHost.getDevice().executeShellV2Command(cmd);
- assertWithMessage("`" + cmd + "` failed: " + result.getStderr())
- .that(result.getStatus())
- .isEqualTo(CommandStatus.SUCCESS);
- return result.getStdout();
- }
-}
diff --git a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
index ad068308d481..258642ac229e 100644
--- a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
+++ b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
@@ -17,10 +17,12 @@
package com.android.server;
import static android.net.ConnectivityManager.NetworkCallback;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_IMS;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED;
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
+import static android.net.vcn.VcnManager.VCN_RESTRICTED_TRANSPORTS_INT_ARRAY_KEY;
import static android.net.vcn.VcnManager.VCN_STATUS_CODE_ACTIVE;
import static android.net.vcn.VcnManager.VCN_STATUS_CODE_SAFE_MODE;
import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
@@ -95,6 +97,7 @@ import com.android.server.vcn.Vcn;
import com.android.server.vcn.VcnContext;
import com.android.server.vcn.VcnNetworkProvider;
import com.android.server.vcn.util.PersistableBundleUtils;
+import com.android.server.vcn.util.PersistableBundleUtils.PersistableBundleWrapper;
import org.junit.Before;
import org.junit.Test;
@@ -252,6 +255,10 @@ public class VcnManagementServiceTest {
.when(mMockContext)
.enforceCallingOrSelfPermission(
eq(android.Manifest.permission.NETWORK_FACTORY), any());
+
+ doReturn(Collections.singleton(TRANSPORT_WIFI))
+ .when(mMockDeps)
+ .getRestrictedTransports(any(), any());
}
@@ -1031,63 +1038,188 @@ public class VcnManagementServiceTest {
new LinkProperties());
}
+ private void checkGetRestrictedTransports(
+ ParcelUuid subGrp,
+ TelephonySubscriptionSnapshot lastSnapshot,
+ Set<Integer> expectedTransports) {
+ Set<Integer> result =
+ new VcnManagementService.Dependencies()
+ .getRestrictedTransports(subGrp, lastSnapshot);
+ assertEquals(expectedTransports, result);
+ }
+
+ @Test
+ public void testGetRestrictedTransports() {
+ final Set<Integer> restrictedTransports = new ArraySet<>();
+ restrictedTransports.add(TRANSPORT_CELLULAR);
+ restrictedTransports.add(TRANSPORT_WIFI);
+
+ PersistableBundle carrierConfigBundle = new PersistableBundle();
+ carrierConfigBundle.putIntArray(
+ VCN_RESTRICTED_TRANSPORTS_INT_ARRAY_KEY,
+ restrictedTransports.stream().mapToInt(i -> i).toArray());
+ final PersistableBundleWrapper carrierConfig =
+ new PersistableBundleWrapper(carrierConfigBundle);
+
+ final TelephonySubscriptionSnapshot lastSnapshot =
+ mock(TelephonySubscriptionSnapshot.class);
+ doReturn(carrierConfig).when(lastSnapshot).getCarrierConfigForSubGrp(eq(TEST_UUID_2));
+
+ checkGetRestrictedTransports(TEST_UUID_2, lastSnapshot, restrictedTransports);
+ }
+
@Test
- public void testGetUnderlyingNetworkPolicyCellular() throws Exception {
+ public void testGetRestrictedTransports_noRestrictPolicyConfigured() {
+ final Set<Integer> restrictedTransports = Collections.singleton(TRANSPORT_WIFI);
+
+ final PersistableBundleWrapper carrierConfig =
+ new PersistableBundleWrapper(new PersistableBundle());
+ final TelephonySubscriptionSnapshot lastSnapshot =
+ mock(TelephonySubscriptionSnapshot.class);
+ doReturn(carrierConfig).when(lastSnapshot).getCarrierConfigForSubGrp(eq(TEST_UUID_2));
+
+ checkGetRestrictedTransports(TEST_UUID_2, lastSnapshot, restrictedTransports);
+ }
+
+ @Test
+ public void testGetRestrictedTransports_noCarrierConfig() {
+ final Set<Integer> restrictedTransports = Collections.singleton(TRANSPORT_WIFI);
+
+ final TelephonySubscriptionSnapshot lastSnapshot =
+ mock(TelephonySubscriptionSnapshot.class);
+
+ checkGetRestrictedTransports(TEST_UUID_2, lastSnapshot, restrictedTransports);
+ }
+
+ private void checkGetUnderlyingNetworkPolicy(
+ int transportType,
+ boolean isTransportRestricted,
+ boolean isActive,
+ boolean expectVcnManaged,
+ boolean expectRestricted)
+ throws Exception {
+
+ final Set<Integer> restrictedTransports = new ArraySet();
+ if (isTransportRestricted) {
+ restrictedTransports.add(transportType);
+ }
+ doReturn(restrictedTransports).when(mMockDeps).getRestrictedTransports(any(), any());
+
final VcnUnderlyingNetworkPolicy policy =
startVcnAndGetPolicyForTransport(
- TEST_SUBSCRIPTION_ID, TEST_UUID_2, true /* isActive */, TRANSPORT_CELLULAR);
+ TEST_SUBSCRIPTION_ID, TEST_UUID_2, isActive, transportType);
assertFalse(policy.isTeardownRequested());
verifyMergedNetworkCapabilities(
policy.getMergedNetworkCapabilities(),
+ transportType,
+ expectVcnManaged,
+ expectRestricted);
+ }
+
+ @Test
+ public void testGetUnderlyingNetworkPolicy_unrestrictCell() throws Exception {
+ checkGetUnderlyingNetworkPolicy(
TRANSPORT_CELLULAR,
- true /* isVcnManaged */,
- false /* isRestricted */);
+ false /* isTransportRestricted */,
+ true /* isActive */,
+ true /* expectVcnManaged */,
+ false /* expectRestricted */);
}
@Test
- public void testGetUnderlyingNetworkPolicyCellular_safeMode() throws Exception {
- final VcnUnderlyingNetworkPolicy policy =
- startVcnAndGetPolicyForTransport(
- TEST_SUBSCRIPTION_ID,
- TEST_UUID_2,
- false /* isActive */,
- TRANSPORT_CELLULAR);
+ public void testGetUnderlyingNetworkPolicy_unrestrictCellSafeMode() throws Exception {
+ checkGetUnderlyingNetworkPolicy(
+ TRANSPORT_CELLULAR,
+ false /* isTransportRestricted */,
+ false /* isActive */,
+ false /* expectVcnManaged */,
+ false /* expectRestricted */);
+ }
- assertFalse(policy.isTeardownRequested());
- verifyMergedNetworkCapabilities(
- policy.getMergedNetworkCapabilities(),
- NetworkCapabilities.TRANSPORT_CELLULAR,
- false /* isVcnManaged */,
- false /* isRestricted */);
+ @Test
+ public void testGetUnderlyingNetworkPolicy_restrictCell() throws Exception {
+ checkGetUnderlyingNetworkPolicy(
+ TRANSPORT_CELLULAR,
+ true /* isTransportRestricted */,
+ true /* isActive */,
+ true /* expectVcnManaged */,
+ true /* expectRestricted */);
}
@Test
- public void testGetUnderlyingNetworkPolicyWifi() throws Exception {
- final VcnUnderlyingNetworkPolicy policy =
- startVcnAndGetPolicyForTransport(
- TEST_SUBSCRIPTION_ID, TEST_UUID_2, true /* isActive */, TRANSPORT_WIFI);
+ public void testGetUnderlyingNetworkPolicy_restrictCellSafeMode() throws Exception {
+ checkGetUnderlyingNetworkPolicy(
+ TRANSPORT_CELLULAR,
+ true /* isTransportRestricted */,
+ false /* isActive */,
+ false /* expectVcnManaged */,
+ false /* expectRestricted */);
+ }
- assertFalse(policy.isTeardownRequested());
- verifyMergedNetworkCapabilities(
- policy.getMergedNetworkCapabilities(),
- NetworkCapabilities.TRANSPORT_WIFI,
- true /* isVcnManaged */,
- true /* isRestricted */);
+ @Test
+ public void testGetUnderlyingNetworkPolicy_unrestrictWifi() throws Exception {
+ checkGetUnderlyingNetworkPolicy(
+ TRANSPORT_WIFI,
+ false /* isTransportRestricted */,
+ true /* isActive */,
+ true /* expectVcnManaged */,
+ false /* expectRestricted */);
}
@Test
- public void testGetUnderlyingNetworkPolicyVcnWifi_safeMode() throws Exception {
+ public void testGetUnderlyingNetworkPolicy_unrestrictWifiSafeMode() throws Exception {
+ checkGetUnderlyingNetworkPolicy(
+ TRANSPORT_WIFI,
+ false /* isTransportRestricted */,
+ false /* isActive */,
+ false /* expectVcnManaged */,
+ false /* expectRestricted */);
+ }
+
+ @Test
+ public void testGetUnderlyingNetworkPolicy_restrictWifi() throws Exception {
+ checkGetUnderlyingNetworkPolicy(
+ TRANSPORT_WIFI,
+ true /* isTransportRestricted */,
+ true /* isActive */,
+ true /* expectVcnManaged */,
+ true /* expectRestricted */);
+ }
+
+ @Test
+ public void testGetUnderlyingNetworkPolicy_restrictWifiSafeMode() throws Exception {
+ checkGetUnderlyingNetworkPolicy(
+ TRANSPORT_WIFI,
+ true /* isTransportRestricted */,
+ false /* isActive */,
+ false /* expectVcnManaged */,
+ true /* expectRestricted */);
+ }
+
+ @Test
+ public void testGetUnderlyingNetworkPolicyCell_restrictWifi() throws Exception {
+ doReturn(Collections.singleton(TRANSPORT_WIFI))
+ .when(mMockDeps)
+ .getRestrictedTransports(any(), any());
+
+ setupSubscriptionAndStartVcn(TEST_SUBSCRIPTION_ID, TEST_UUID_2, true /* isVcnActive */);
+
+ // Get the policy for a cellular network and expect it won't be affected by the wifi
+ // restriction policy
final VcnUnderlyingNetworkPolicy policy =
- startVcnAndGetPolicyForTransport(
- TEST_SUBSCRIPTION_ID, TEST_UUID_2, false /* isActive */, TRANSPORT_WIFI);
+ mVcnMgmtSvc.getUnderlyingNetworkPolicy(
+ getNetworkCapabilitiesBuilderForTransport(
+ TEST_SUBSCRIPTION_ID, TRANSPORT_CELLULAR)
+ .build(),
+ new LinkProperties());
assertFalse(policy.isTeardownRequested());
verifyMergedNetworkCapabilities(
policy.getMergedNetworkCapabilities(),
- NetworkCapabilities.TRANSPORT_WIFI,
- false /* isVcnManaged */,
- true /* isRestricted */);
+ TRANSPORT_CELLULAR,
+ true /* expectVcnManaged */,
+ false /* expectRestricted */);
}
private void setupTrackedCarrierWifiNetwork(NetworkCapabilities caps) {
@@ -1138,6 +1270,27 @@ public class VcnManagementServiceTest {
}
@Test
+ public void testGetUnderlyingNetworkPolicyForRestrictedImsWhenUnrestrictingCell()
+ throws Exception {
+ final NetworkCapabilities existingNetworkCaps =
+ getNetworkCapabilitiesBuilderForTransport(TEST_SUBSCRIPTION_ID, TRANSPORT_CELLULAR)
+ .addCapability(NET_CAPABILITY_NOT_RESTRICTED)
+ .removeCapability(NET_CAPABILITY_IMS)
+ .build();
+ setupTrackedCarrierWifiNetwork(existingNetworkCaps);
+
+ final VcnUnderlyingNetworkPolicy policy =
+ mVcnMgmtSvc.getUnderlyingNetworkPolicy(
+ getNetworkCapabilitiesBuilderForTransport(
+ TEST_SUBSCRIPTION_ID, TRANSPORT_CELLULAR)
+ .addCapability(NET_CAPABILITY_IMS)
+ .removeCapability(NET_CAPABILITY_NOT_RESTRICTED)
+ .build(),
+ new LinkProperties());
+ assertFalse(policy.isTeardownRequested());
+ }
+
+ @Test
public void testGetUnderlyingNetworkPolicyNonVcnNetwork() throws Exception {
setupSubscriptionAndStartVcn(TEST_SUBSCRIPTION_ID, TEST_UUID_1, true /* isActive */);
@@ -1217,6 +1370,30 @@ public class VcnManagementServiceTest {
verify(mMockPolicyListener).onPolicyChanged();
}
+ @Test
+ public void testVcnCarrierConfigChangeUpdatesPolicyListener() throws Exception {
+ setupActiveSubscription(TEST_UUID_2);
+
+ mVcnMgmtSvc.setVcnConfig(TEST_UUID_2, TEST_VCN_CONFIG, TEST_PACKAGE_NAME);
+ mVcnMgmtSvc.addVcnUnderlyingNetworkPolicyListenerForTest(mMockPolicyListener);
+
+ final TelephonySubscriptionSnapshot snapshot =
+ buildSubscriptionSnapshot(
+ TEST_SUBSCRIPTION_ID,
+ TEST_UUID_2,
+ Collections.singleton(TEST_UUID_2),
+ Collections.emptyMap(),
+ true /* hasCarrierPrivileges */);
+
+ final PersistableBundleWrapper mockCarrierConfig = mock(PersistableBundleWrapper.class);
+ doReturn(mockCarrierConfig).when(snapshot).getCarrierConfigForSubGrp(eq(TEST_UUID_2));
+
+ final TelephonySubscriptionTrackerCallback cb = getTelephonySubscriptionTrackerCallback();
+ cb.onNewSnapshot(snapshot);
+
+ verify(mMockPolicyListener).onPolicyChanged();
+ }
+
private void triggerVcnSafeMode(
@NonNull ParcelUuid subGroup,
@NonNull TelephonySubscriptionSnapshot snapshot,
diff --git a/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java b/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java
index 09080be9ee41..965b073ff0db 100644
--- a/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java
+++ b/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java
@@ -16,6 +16,9 @@
package com.android.server.vcn;
+import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
+import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
+import static android.net.vcn.VcnManager.VCN_RESTRICTED_TRANSPORTS_INT_ARRAY_KEY;
import static android.telephony.CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED;
import static android.telephony.CarrierConfigManager.EXTRA_SLOT_INDEX;
import static android.telephony.CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX;
@@ -39,6 +42,7 @@ import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
@@ -494,6 +498,37 @@ public class TelephonySubscriptionTrackerTest {
}
@Test
+ public void testCarrierConfigUpdatedAfterValidTriggersCallbacks() throws Exception {
+ mTelephonySubscriptionTracker.onReceive(mContext, buildTestBroadcastIntent(true));
+ mTestLooper.dispatchAll();
+ verify(mCallback).onNewSnapshot(eq(buildExpectedSnapshot(TEST_PRIVILEGED_PACKAGES)));
+ reset(mCallback);
+
+ final PersistableBundle updatedConfig = new PersistableBundle();
+ updatedConfig.putIntArray(
+ VCN_RESTRICTED_TRANSPORTS_INT_ARRAY_KEY,
+ new int[] {TRANSPORT_WIFI, TRANSPORT_CELLULAR});
+ doReturn(updatedConfig)
+ .when(mCarrierConfigManager)
+ .getConfigForSubId(eq(TEST_SUBSCRIPTION_ID_1));
+
+ Map<Integer, PersistableBundleWrapper> subIdToCarrierConfigMap = new HashMap<>();
+ subIdToCarrierConfigMap.put(
+ TEST_SUBSCRIPTION_ID_1, new PersistableBundleWrapper(updatedConfig));
+ mTelephonySubscriptionTracker.onReceive(mContext, buildTestBroadcastIntent(true));
+ mTestLooper.dispatchAll();
+
+ verify(mCallback)
+ .onNewSnapshot(
+ eq(
+ buildExpectedSnapshot(
+ 0,
+ TEST_SUBID_TO_INFO_MAP,
+ subIdToCarrierConfigMap,
+ TEST_PRIVILEGED_PACKAGES)));
+ }
+
+ @Test
public void testSlotClearedAfterValidTriggersCallbacks() throws Exception {
mTelephonySubscriptionTracker.onReceive(mContext, buildTestBroadcastIntent(true));
mTestLooper.dispatchAll();
diff --git a/tools/locked_region_code_injection/Android.bp b/tools/locked_region_code_injection/Android.bp
index ff1f8e2c9d30..a0cc446cd42d 100644
--- a/tools/locked_region_code_injection/Android.bp
+++ b/tools/locked_region_code_injection/Android.bp
@@ -12,10 +12,10 @@ java_binary_host {
manifest: "manifest.txt",
srcs: ["src/**/*.java"],
static_libs: [
- "asm-9.2",
- "asm-commons-9.2",
- "asm-tree-9.2",
- "asm-analysis-9.2",
"guava",
+ "ow2-asm",
+ "ow2-asm-analysis",
+ "ow2-asm-commons",
+ "ow2-asm-tree",
],
}
diff --git a/tools/protologtool/tests/com/android/protolog/tool/LogParserTest.kt b/tools/protologtool/tests/com/android/protolog/tool/LogParserTest.kt
index 67a31da87081..512d90c725fe 100644
--- a/tools/protologtool/tests/com/android/protolog/tool/LogParserTest.kt
+++ b/tools/protologtool/tests/com/android/protolog/tool/LogParserTest.kt
@@ -84,8 +84,8 @@ class LogParserTest {
@Test
fun parse_formatting() {
- config[123] = ViewerConfigParser.ConfigEntry("Test completed successfully: %b %d %% %o" +
- " %x %e %g %s %f", "ERROR", "WindowManager")
+ config[123] = ViewerConfigParser.ConfigEntry("Test completed successfully: %b %d %%" +
+ " %x %s %f", "ERROR", "WindowManager")
val logBuilder = ProtoLogFileProto.newBuilder()
val logMessageBuilder = ProtoLogMessage.newBuilder()
@@ -93,21 +93,21 @@ class LogParserTest {
.setMessageHash(123)
.setElapsedRealtimeNanos(0)
.addBooleanParams(true)
- .addAllSint64Params(listOf(1000, 20000, 300000))
- .addAllDoubleParams(listOf(0.1, 0.00001, 1000.1))
+ .addAllSint64Params(listOf(1000, 20000))
+ .addDoubleParams(1000.1)
.addStrParams("test")
logBuilder.addLog(logMessageBuilder.build())
parser.parse(buildProtoInput(logBuilder), getConfigDummyStream(), printStream)
assertEquals("${testDate(0)} ERROR WindowManager: Test completed successfully: " +
- "true 1000 % 47040 493e0 1.000000e-01 1.00000e-05 test 1000.100000\n",
+ "true 1000 % 4e20 test 1000.100000\n",
outStream.toString())
}
@Test
fun parse_invalidParamsTooMany() {
- config[123] = ViewerConfigParser.ConfigEntry("Test completed successfully: %b %d %% %o",
+ config[123] = ViewerConfigParser.ConfigEntry("Test completed successfully: %b %d %%",
"ERROR", "WindowManager")
val logBuilder = ProtoLogFileProto.newBuilder()
@@ -129,8 +129,8 @@ class LogParserTest {
@Test
fun parse_invalidParamsNotEnough() {
- config[123] = ViewerConfigParser.ConfigEntry("Test completed successfully: %b %d %% %o" +
- " %x %e %g %s %f", "ERROR", "WindowManager")
+ config[123] = ViewerConfigParser.ConfigEntry("Test completed successfully: %b %d %%" +
+ " %x %s %f", "ERROR", "WindowManager")
val logBuilder = ProtoLogFileProto.newBuilder()
val logMessageBuilder = ProtoLogMessage.newBuilder()
diff --git a/tools/sdkparcelables/Android.bp b/tools/sdkparcelables/Android.bp
index 6ebacd8a0b14..6503a1f3a5f8 100644
--- a/tools/sdkparcelables/Android.bp
+++ b/tools/sdkparcelables/Android.bp
@@ -14,7 +14,7 @@ java_binary_host {
"src/**/*.kt",
],
static_libs: [
- "asm-9.2",
+ "ow2-asm",
],
}
diff --git a/tools/traceinjection/Android.bp b/tools/traceinjection/Android.bp
index bb32df6c65af..d627fb99d882 100644
--- a/tools/traceinjection/Android.bp
+++ b/tools/traceinjection/Android.bp
@@ -12,10 +12,10 @@ java_binary_host {
manifest: "manifest.txt",
srcs: ["src/**/*.java"],
static_libs: [
- "asm-9.2",
- "asm-commons-9.2",
- "asm-tree-9.2",
- "asm-analysis-9.2",
+ "ow2-asm",
+ "ow2-asm-commons",
+ "ow2-asm-tree",
+ "ow2-asm-analysis",
"guava",
],
}